From 506e23bf32b304256fcf15a3d1c0e09c6b82207d Mon Sep 17 00:00:00 2001 From: Ondrej Novak Date: Fri, 24 Jan 2025 18:27:22 +0100 Subject: [PATCH] github publish --- .gitignore | 7 + .vs/Skeldal/v17/.suo | Bin 0 -> 156160 bytes 3DTEST/TEXTURAA.ASM | 64 + AdvMan/AdvMan.cpp | 187 + AdvMan/AdvMan.h | 55 + AdvMan/AdvMan.rc | 569 ++++ AdvMan/AdvMan.sln | 21 + AdvMan/AdvMan.vcproj | 525 +++ AdvMan/ChildView.cpp | 57 + AdvMan/ChildView.h | 51 + AdvMan/DlgDialogy.cpp | 264 ++ AdvMan/DlgDialogy.h | 76 + AdvMan/DlgNoveDobr.cpp | 83 + AdvMan/DlgNoveDobr.h | 57 + AdvMan/DlgNovyDialog.cpp | 127 + AdvMan/DlgNovyDialog.h | 57 + AdvMan/FCS_tasker.h | 0 AdvMan/FS_tasker.h | 0 AdvMan/MainFrm.cpp | 677 ++++ AdvMan/MainFrm.h | 95 + AdvMan/Pathname.cpp | 621 ++++ AdvMan/Pathname.h | 451 +++ AdvMan/StdAfx.cpp | 8 + AdvMan/StdAfx.h | 33 + AdvMan/bgraph2dx.h | 0 AdvMan/debug.h | 0 AdvMan/idc_note.ico | Bin 0 -> 2550 bytes AdvMan/mem.h | 4 + AdvMan/res/AdvMan.ico | Bin 0 -> 1078 bytes AdvMan/res/AdvMan.rc2 | 13 + AdvMan/res/Toolbar.bmp | Bin 0 -> 886 bytes AdvMan/res/editory.bmp | Bin 0 -> 838 bytes AdvMan/res/prekladace.bmp | Bin 0 -> 478 bytes AdvMan/resource.h | 88 + AdvMan/skeldal_win.h | 4 + DDLReader/DDLFile.cpp | 93 + DDLReader/DDLFile.h | 45 + DDLReader/DDLReader.cpp | 67 + DDLReader/DDLReader.h | 49 + DDLReader/DDLReader.rc | 278 ++ DDLReader/DDLReader.sln | 34 + DDLReader/DDLReader.vcproj | 291 ++ DDLReader/DDLReaderDlg.cpp | 533 +++ DDLReader/DDLReaderDlg.h | 76 + DDLReader/DlgProgress.cpp | 41 + DDLReader/DlgProgress.h | 28 + DDLReader/IWStringEffect.h | 36 + .../Projects/Skeldal/DDLReader/DDLFile.cpp | 93 + .../Projects/Skeldal/DDLReader/DDLFile.h | 45 + .../Projects/Skeldal/DDLReader/DDLReader.cpp | 67 + .../Projects/Skeldal/DDLReader/DDLReader.h | 49 + .../Projects/Skeldal/DDLReader/DDLReader.rc | 278 ++ .../Projects/Skeldal/DDLReader/DDLReader.sln | 34 + .../Skeldal/DDLReader/DDLReader.vcproj | 291 ++ .../Skeldal/DDLReader/DDLReaderDlg.cpp | 533 +++ .../Projects/Skeldal/DDLReader/DDLReaderDlg.h | 76 + .../Skeldal/DDLReader/DlgProgress.cpp | 41 + .../Projects/Skeldal/DDLReader/DlgProgress.h | 28 + .../Skeldal/DDLReader/IWStringEffect.h | 36 + .../Projects/Skeldal/DDLReader/StdAfx.cpp | 8 + DDLReader/Projects/Skeldal/DDLReader/StdAfx.h | 27 + .../Projects/Skeldal/DDLReader/WPathname.cpp | 408 +++ .../Projects/Skeldal/DDLReader/WPathname.h | 400 +++ .../Projects/Skeldal/DDLReader/WString.cpp | 193 ++ .../Projects/Skeldal/DDLReader/WString.h | 496 +++ .../Skeldal/DDLReader/WStringMemory.cpp | 397 +++ .../Skeldal/DDLReader/WStringMemory.h | 61 + .../Skeldal/DDLReader/WStringProxy.cpp | 185 + .../Projects/Skeldal/DDLReader/WStringProxy.h | 232 ++ .../Skeldal/DDLReader/res/DDLReader.ico | Bin 0 -> 1078 bytes .../Projects/Skeldal/DDLReader/resource.h | 49 + DDLReader/StdAfx.cpp | 8 + DDLReader/StdAfx.h | 27 + DDLReader/WPathname.cpp | 408 +++ DDLReader/WPathname.h | 400 +++ DDLReader/WString.cpp | 194 ++ DDLReader/WString.h | 496 +++ DDLReader/WStringMemory.cpp | 397 +++ DDLReader/WStringMemory.h | 61 + DDLReader/WStringProxy.cpp | 185 + DDLReader/WStringProxy.h | 232 ++ DDLReader/res/DDLReader.ico | Bin 0 -> 1078 bytes DDLReader/res/DDLReader.rc2 | 13 + DDLReader/resource.h | 49 + FONT/BIG.FON | Bin 0 -> 12309 bytes FONT/BIG2.FON | Bin 0 -> 12064 bytes FONT/BOLDCZ.FON | Bin 0 -> 9034 bytes FONT/BROOKLIN.FON | Bin 0 -> 17336 bytes FONT/EUROMODE.FON | Bin 0 -> 12673 bytes FONT/FONT4X8.FON | Bin 0 -> 4496 bytes FONT/FONT5X8.FON | Bin 0 -> 4408 bytes FONT/FONT6X9.FON | Bin 0 -> 5593 bytes FONT/IKONES.FON | Bin 0 -> 8909 bytes FONT/KNIHA.FON | Bin 0 -> 8880 bytes FONT/SADA16.FON | Bin 0 -> 9163 bytes FONT/SADA7.FON | Bin 0 -> 8813 bytes FONT/TIMESBIG.FON | Bin 0 -> 40400 bytes FONT/TIMESBIT.FON | Bin 0 -> 31710 bytes FONT/TIMESE.FON | Bin 0 -> 11547 bytes FONT/TINY.FON | Bin 0 -> 8880 bytes FONT/ikony.fon | Bin 0 -> 4918 bytes GAME/AUTOMAP.C | 954 ++++++ GAME/BOLDCZ.FON | Bin 0 -> 9034 bytes GAME/BUILDER.C | 1315 +++++++ GAME/CHARGEN.C | 908 +++++ GAME/CHARGEN2.C | 344 ++ GAME/CLK_MAP.C | 571 ++++ GAME/CRC.C | 31 + GAME/DIALOGY.C | 1419 ++++++++ GAME/DLGLIB.C | 271 ++ GAME/DUMP.C | 81 + GAME/ENCRYPT.C | 66 + GAME/ENEMY.C | 2140 ++++++++++++ GAME/ENGINE1.C | 1412 ++++++++ GAME/ENGINE1.H | 162 + GAME/ENGINE2.ASM | 2188 ++++++++++++ GAME/GAMESAVE.C | 1586 +++++++++ GAME/GLOBALS.H | 1729 ++++++++++ GAME/GLOBMAP.C | 662 ++++ GAME/INTERFAC.C | 1623 +++++++++ GAME/INV.C | 3011 +++++++++++++++++ GAME/KNIHA.C | 702 ++++ GAME/KOUZLA.C | 1969 +++++++++++ GAME/MACROS.C | 794 +++++ GAME/MENU.C | 599 ++++ GAME/REALGAME.C | 1997 +++++++++++ GAME/SERIAL.C | 16 + GAME/SETUP.C | 265 ++ GAME/SKELDAL.C | 1755 ++++++++++ GAME/SNDandMUS.C | 644 ++++ GAME/SOUBOJE.C | 2442 +++++++++++++ GAME/SPECPROC.C | 707 ++++ GAME/SPECPROC.H | 39 + GAME/TRANSAV.C | 682 ++++ GAME/WIZARD.C | 758 +++++ GAME/WIZARD.H | 1 + GAME/engine2.c | 1315 +++++++ GAME/extras.h | 16 + GAME/version.h | 13 + GIF/Decoder.c | 377 +++ GIF/Errs.h | 14 + GIF/GIF.H | 16 + GIF/GIF2.C | 147 + GIF/GIF2XED.C | 39 + GIF/Gif.c | 61 + GIF/STD.H | 16 + INST/SETUP.C | 1427 ++++++++ INST/SETUP.H | 18 + INST/SETUPCPY.C | 165 + INST/SETUPCPY.H | 9 + INST/SETUPLIB.C | 505 +++ INST/SETUPLIB.H | 22 + INST/SETVIDEO.C | 197 ++ INST/SETVIDEO.H | 6 + INST/STUB.C | 53 + INST/TEXTLIB.ASM | 101 + INST/TEXTLIB.C | 4 + LIBS/ADDTEXT.C | 120 + LIBS/ADVINST.C | 132 + LIBS/BASICOBJ.C | 1332 ++++++++ LIBS/BASICOBJ.H | 38 + LIBS/BGRAPH.C | 261 ++ LIBS/BGRAPH.H | 155 + LIBS/BGRAPH1.ASM | 658 ++++ LIBS/BGRAPH2A.ASM | 1132 +++++++ LIBS/BLDICONS.C | 82 + LIBS/BMOUSE.C | 118 + LIBS/BMOUSE.H | 20 + LIBS/BMP2HI.C | 233 ++ LIBS/Bgraph2.c | 800 +++++ LIBS/CSPELLS.C | 181 + LIBS/DEVICES.C | 66 + LIBS/DEVICES.H | 35 + LIBS/DOSERR.ASM | 76 + LIBS/DOSERR.H | 18 + LIBS/ENGINE1.C | 885 +++++ LIBS/ENGINE2.ASM | 380 +++ LIBS/ERRTEST.C | 23 + LIBS/EVENT.C | 629 ++++ LIBS/EVENT.H | 157 + LIBS/EXPAND.C | 31 + LIBS/EXTRACT.C | 32 + LIBS/FASTLOAD.C | 29 + LIBS/GRAPHTST.C | 118 + LIBS/GUI.C | 932 +++++ LIBS/GUI.H | 166 + LIBS/INICFG.C | 164 + LIBS/INICFG.H | 10 + LIBS/LEX_LIB.C | 280 ++ LIBS/LZWA.ASM | 55 + LIBS/MEMMAN.C | 963 ++++++ LIBS/MEMMAN.H | 121 + LIBS/MGFPLAY.C | 384 +++ LIBS/MGFPLAY.H | 7 + LIBS/MGIFMEM.C | 275 ++ LIBS/MGIFMEM.H | 40 + LIBS/MGIFPLAYA.C | 302 ++ LIBS/MOUSE.C | 165 + LIBS/PADY.C | 424 +++ LIBS/PCSPEAK.ASM | 304 ++ LIBS/PCSPEAK.H | 137 + LIBS/PCX.C | 209 ++ LIBS/PCX.H | 41 + LIBS/READFONT.C | 181 + LIBS/STRLISTS.C | 368 ++ LIBS/STRLISTS.H | 9 + LIBS/STRLITE.C | 404 +++ LIBS/STRLITE.H | 35 + LIBS/SWAPER.C | 150 + LIBS/TASKER.ASM | 90 + LIBS/TESTSVGA.C | 148 + LIBS/TST.C | 6 + LIBS/TYPES.H | 4 + LIBS/VESATST.C | 98 + LIBS/WAV.C | 42 + LIBS/WAV.H | 20 + LIBS/WAV_MEM.C | 37 + LIBS/WAV_MEM.H | 20 + LIBS/ZVUK.C | 1426 ++++++++ LIBS/ZVUK.H | 74 + LIBS/ZVUKA.ASM | 1247 +++++++ LIBS/bgraph2a.c | 758 +++++ LIBS/bgraph2a.cpp | 206 ++ LIBS/bios.h | 0 LIBS/mem.h | 2 + LIBS/mgifmapmem.c | 147 + LIBS/mgifmapmem.h | 3 + LIBS/zvuk_dx.cpp | 842 +++++ LZWC.C | 272 ++ LZWC.H | 56 + MAPS/CDIALOGY.C | 585 ++++ MAPS/DLGPRINT.C | 188 + MAPS/DUMP.C | 78 + MAPS/DUMP.H | 1 + MAPS/EDIT_MAP.C | 1179 +++++++ MAPS/EDIT_MAP.H | 21 + MAPS/GLOBALS.H | 133 + MAPS/ITEMS.C | 1012 ++++++ MAPS/ITEMS2.C | 1707 ++++++++++ MAPS/MAPEDIT.C | 976 ++++++ MAPS/MAPY.C | 1108 ++++++ MAPS/MAPY.H | 630 ++++ MAPS/MOB_EDIT.C | 1184 +++++++ MAPS/MOB_EDIT.H | 20 + MAPS/PCXVIEW.C | 459 +++ MAPS/SAVE_MAP.C | 694 ++++ MAPS/SAVE_MAP.H | 14 + MAPS/STENY.C | 542 +++ MAPS/STENY.H | 33 + MAPS/WIN_TEST.C | 175 + MAPS/WIZ_TOOL.C | 3010 ++++++++++++++++ MAPS/WIZ_TOOL.H | 5 + PCX/3DMAN.C | 102 + PCX/BOLDCZ.FON | Bin 0 -> 8730 bytes PCX/PCX.C | 180 + PCX/PCX.H | 25 + PCX/PCXTST.C | 173 + PCX/PODLAHY.C | 330 ++ POKUSSCR.C | 58 + Skeldal.sln | 43 + Skeldal.suo | Bin 0 -> 156160 bytes Skeldal.vcproj | 1917 +++++++++++ StdAfx.cpp | 8 + StdAfx.h | 19 + UTILS/ITEMLIST.C | 328 ++ UTILS/Podlahar/Podlahar.cpp | 73 + UTILS/Podlahar/Podlahar.h | 31 + UTILS/Podlahar/Podlahar.rc | 200 ++ UTILS/Podlahar/Podlahar.vcproj | 193 ++ UTILS/Podlahar/PodlaharDlg.cpp | 161 + UTILS/Podlahar/PodlaharDlg.h | 34 + UTILS/Podlahar/Resource.h | 23 + UTILS/Podlahar/res/Podlahar.ico | Bin 0 -> 21630 bytes UTILS/Podlahar/res/Podlahar.rc2 | 13 + UTILS/Podlahar/stdafx.cpp | 7 + UTILS/Podlahar/stdafx.h | 43 + VIDEO/ANIPACK.ASM | 318 ++ VIDEO/ANIPACK.H | 39 + VIDEO/BITLINE.ASM | 342 ++ VIDEO/BITLINE.H | 16 + VIDEO/BOLDCZ.FON | Bin 0 -> 9034 bytes VIDEO/CINEMA.H | 8 + VIDEO/CNMBUILD.C | 667 ++++ VIDEO/CNMCONTR.C | 74 + VIDEO/FLC.C | 202 ++ VIDEO/FLC.H | 62 + VIDEO/FLC/ANALYSE/DOSMEM.C | 71 + VIDEO/FLC/ANALYSE/DOSMEM.H | 46 + VIDEO/FLC/ANALYSE/FLC.C | 5 + VIDEO/FLC/ANALYSE/FLC.H | 54 + VIDEO/FLC/ANALYSE/PLAY.C | 54 + VIDEO/FLC/ANALYSE/VESA.C | 296 ++ VIDEO/FLC/ANALYSE/VESA.H | 70 + VIDEO/FLC/ANALYSE/VESA_.ASM | 63 + VIDEO/FLC/DOSMEM.C | 71 + VIDEO/FLC/DOSMEM.H | 46 + VIDEO/FLC/FLC.C | 176 + VIDEO/FLC/FLC.H | 61 + VIDEO/FLC/PLAY.C | 54 + VIDEO/FLC/VESA.C | 296 ++ VIDEO/FLC/VESA.H | 70 + VIDEO/FLC/VESA_.ASM | 63 + VIDEO/FLC2MGIF.C | 620 ++++ VIDEO/JPEGMGFA.ASM | 119 + VIDEO/JPEGMGIF.C | 172 + VIDEO/JPEGMGIF.H | 10 + VIDEO/JPEG_SIM.C | 252 ++ VIDEO/LZW.C | 225 ++ VIDEO/LZW.H | 5 + VIDEO/LZWA.ASM | 55 + VIDEO/LZWC.C | 261 ++ VIDEO/LZW_EX.C | 92 + VIDEO/MGFPLAYA.ASM | 500 +++ VIDEO/MGFSOUND.C | 558 +++ VIDEO/MGIF.C | 646 ++++ VIDEO/MGIF98.C | 376 ++ VIDEO/MGIFCAT.C | 216 ++ VIDEO/MGIFEACT.C | 906 +++++ VIDEO/MGIFEACT.H | 98 + VIDEO/MGIFEBLD.C | 426 +++ VIDEO/MGIFEBLD.H | 9 + VIDEO/MGIFEDIT.C | 905 +++++ VIDEO/MGIFEDIT.H | 40 + VIDEO/MGIFEOBJ.C | 275 ++ VIDEO/MGIFEOBJ.H | 6 + VIDEO/MGIFPLAY.C | 331 ++ VIDEO/OLD/MGIFMEM.C | 209 ++ VIDEO/OLD/MGIFMEM.H | 21 + VIDEO/PCX2MGIF.C | 892 +++++ VIDEO/PLAY.C | 54 + VIDEO/PLAYCNM.C | 356 ++ VIDEO/SADA7.FON | Bin 0 -> 8815 bytes VIDEO/VIDEO.C | 102 + Windows/BGraph2Dx.cpp | 684 ++++ Windows/BGraph2Dx.h | 58 + Windows/BOLDCZ.FON | Bin 0 -> 9034 bytes Windows/FCS_Tasker.c | 209 ++ Windows/FCS_Tasker.h | 32 + Windows/Music.cpp | 507 +++ Windows/Music.h | 121 + Windows/Skeldal.rc | 499 +++ Windows/StdAfx.cpp | 8 + Windows/StdAfx.h | 26 + Windows/WAInputPlugin.cpp | 632 ++++ Windows/WAInputPlugin.h | 130 + Windows/WAPlayer.cpp | 74 + Windows/WAPlayer.h | 23 + Windows/WaveOut.cpp | 157 + Windows/WaveOut.h | 52 + Windows/WinAmpInterface.cpp | 27 + Windows/WinAmpInterface.h | 0 Windows/bios.c | 0 Windows/bios.h | 2 + Windows/debug.h | 19 + Windows/extras.rtf | 77 + Windows/fiber_task.h | 21 + Windows/icon.bmp | Bin 0 -> 1132 bytes Windows/icon.ico | Bin 0 -> 3638 bytes Windows/install.cpp | 325 ++ Windows/install.h | 5 + Windows/konfig.cpp | 492 +++ Windows/konfig.h | 1 + Windows/logo.bmp | Bin 0 -> 19440 bytes Windows/mem.h | 2 + Windows/plugins.rtf | 0 Windows/resource.h | 139 + Windows/richview.cpp | 91 + Windows/richview.h | 1 + Windows/seladv_male.bmp | Bin 0 -> 25078 bytes Windows/skeldal_win.c | 199 ++ Windows/skeldal_win.h | 50 + Windows/uvodni.bmp | Bin 0 -> 308280 bytes Windows/uvodni.cpp | 322 ++ Windows/uvodni.h | 11 + Windows/uvodni_sel.bmp | Bin 0 -> 40520 bytes Windows/wa_ipc.h | 1028 ++++++ Windows/winamp/In2.h | 103 + Windows/winamp/Out.h | 62 + Windows/zvuk_win.cpp | 95 + ZVUK/ANALYSE/DOSMEM.C | 71 + ZVUK/ANALYSE/DOSMEM.H | 46 + ZVUK/ANALYSE/FLC.C | 5 + ZVUK/ANALYSE/FLC.H | 54 + ZVUK/ANALYSE/PLAY.C | 54 + ZVUK/ANALYSE/VESA.C | 296 ++ ZVUK/ANALYSE/VESA.H | 70 + ZVUK/ANALYSE/VESA_.ASM | 63 + ZVUK/DOSMEM.C | 71 + ZVUK/DOSMEM.H | 46 + ZVUK/EXAMPLE.ASM | 67 + ZVUK/FLC.C | 176 + ZVUK/FLC.H | 61 + ZVUK/PLAY.C | 54 + ZVUK/SNDPACK.C | 254 ++ ZVUK/SPK_TEST.C | 74 + ZVUK/TRACK.C | 834 +++++ ZVUK/VESA.C | 296 ++ ZVUK/VESA.H | 70 + ZVUK/VESA_.ASM | 63 + ZVUK/ZVUK1.C | 872 +++++ ZVUK/ZVUK1A.ASM | 271 ++ ZVUK/ZVUK2A.ASM | 741 ++++ addonKouzla.odt | Bin 0 -> 6658 bytes crashdump.cpp | 276 ++ crashdump.h | 1 + cztable.cpp | 84 + cztable.h | 19 + extras.h | 14 + history.txt | 1 + html/dont export/export.bmp | Bin 0 -> 1380194 bytes insteng/SETUP.C | 1462 ++++++++ insteng/SETUP.H | 18 + insteng/SETUPCPY.C | 165 + insteng/SETUPCPY.H | 9 + insteng/SETUPLIB.C | 505 +++ insteng/SETUPLIB.H | 22 + insteng/SETVIDEO.C | 210 ++ insteng/SETVIDEO.H | 6 + insteng/STUB.C | 53 + insteng/TEXTLIB.ASM | 101 + insteng/TEXTLIB.C | 4 + mapedit.cpp | 10 + mapedit.vcproj | 852 +++++ mapedit/CDialogy/CDialogy.vcproj | 204 ++ mapedit/CDialogy/Debug/BuildLog.htm | Bin 0 -> 30474 bytes mapedit/CDialogy/Debug/CDialogy.exe | Bin 0 -> 532480 bytes .../Debug/CDialogy.exe.embed.manifest | 10 + .../Debug/CDialogy.exe.embed.manifest.res | Bin 0 -> 472 bytes .../Debug/CDialogy.exe.intermediate.manifest | 10 + mapedit/CDialogy/Debug/mt.dep | 1 + mapedit/CDialogy/Debug/vc80.idb | Bin 0 -> 117760 bytes mapedit/CDialogy/Debug/vc90.idb | Bin 0 -> 134144 bytes mapedit/CDialogy/Release/BuildLog.htm | Bin 0 -> 9544 bytes mapedit/CDialogy/Release/CDialogy.exe | Bin 0 -> 85504 bytes .../CDialogy.exe.intermediate.manifest | 10 + mapedit/CDialogy/Release/mt.dep | 1 + mapedit/CDialogy/Release/vc80.idb | Bin 0 -> 117760 bytes mapedit/CDialogy/Release/vc90.idb | Bin 0 -> 125952 bytes mapedit/CSpells/CSpells.cpp | 10 + mapedit/CSpells/CSpells.vcproj | 208 ++ mapedit/CSpells/Debug/BuildLog.htm | Bin 0 -> 23022 bytes mapedit/CSpells/Debug/CSpells.exe | Bin 0 -> 514560 bytes .../CSpells/Debug/CSpells.exe.embed.manifest | 10 + .../Debug/CSpells.exe.embed.manifest.res | Bin 0 -> 472 bytes .../Debug/CSpells.exe.intermediate.manifest | 10 + mapedit/CSpells/Debug/mt.dep | 1 + mapedit/CSpells/Debug/vc80.idb | Bin 0 -> 125952 bytes mapedit/CSpells/Debug/vc90.idb | Bin 0 -> 134144 bytes mapedit/CSpells/Release/BuildLog.htm | Bin 0 -> 9048 bytes mapedit/CSpells/Release/CSpells.exe | Bin 0 -> 78336 bytes .../Release/CSpells.exe.intermediate.manifest | 10 + mapedit/CSpells/Release/mt.dep | 1 + mapedit/CSpells/Release/vc80.idb | Bin 0 -> 117760 bytes mapedit/CSpells/Release/vc90.idb | Bin 0 -> 134144 bytes mapedit/CSpells/stdafx.cpp | 8 + mapedit/CSpells/stdafx.h | 12 + mapedit/ColEdit/ColEdit.cpp | 72 + mapedit/ColEdit/ColEdit.h | 49 + mapedit/ColEdit/ColEdit.rc | 281 ++ mapedit/ColEdit/ColEdit.sln | 21 + mapedit/ColEdit/ColEdit.vcproj | 454 +++ mapedit/ColEdit/ColEditDlg.cpp | 489 +++ mapedit/ColEdit/ColEditDlg.h | 79 + mapedit/ColEdit/EditPaletteDlg.cpp | 233 ++ mapedit/ColEdit/EditPaletteDlg.h | 63 + mapedit/ColEdit/PaletteEditor.cpp | 113 + mapedit/ColEdit/PaletteEditor.h | 61 + mapedit/ColEdit/StdAfx.cpp | 8 + mapedit/ColEdit/StdAfx.h | 26 + mapedit/ColEdit/res/ColEdit.ico | Bin 0 -> 1078 bytes mapedit/ColEdit/res/ColEdit.rc2 | 13 + mapedit/ColEdit/res/down.ico | Bin 0 -> 766 bytes mapedit/ColEdit/res/icon1.ico | Bin 0 -> 766 bytes mapedit/ColEdit/resource.h | 44 + mapedit/Debug/BuildLog.htm | Bin 0 -> 79656 bytes mapedit/Debug/MapEdit.bsc | Bin 0 -> 5024768 bytes mapedit/Debug/MapEdit.exe | Bin 0 -> 1191936 bytes mapedit/Debug/MapEdit.exe.embed.manifest | 3 + mapedit/Debug/MapEdit.exe.embed.manifest.res | Bin 0 -> 212 bytes .../Debug/MapEdit.exe.intermediate.manifest | 3 + mapedit/Debug/MapEdit.pch | Bin 0 -> 6029312 bytes mapedit/Debug/WinAmpInt.pch | Bin 0 -> 4063232 bytes mapedit/Debug/mapedit.res | Bin 0 -> 69024 bytes mapedit/Debug/mt.dep | 1 + mapedit/Debug/vc80.idb | Bin 0 -> 355328 bytes mapedit/ItemIcons/DlgOpen.cpp | 184 + mapedit/ItemIcons/DlgOpen.h | 39 + mapedit/ItemIcons/IconViewerButton.cpp | 86 + mapedit/ItemIcons/IconViewerButton.h | 30 + mapedit/ItemIcons/ItemIcons.cpp | 71 + mapedit/ItemIcons/ItemIcons.h | 31 + mapedit/ItemIcons/ItemIcons.rc | 354 ++ mapedit/ItemIcons/ItemIcons.sln | 30 + mapedit/ItemIcons/ItemIcons.vcproj | 208 ++ mapedit/ItemIcons/ItemIconsDlg.cpp | 554 +++ mapedit/ItemIcons/ItemIconsDlg.h | 69 + mapedit/ItemIcons/res/ItemIcons.ico | Bin 0 -> 21630 bytes mapedit/ItemIcons/res/ItemIcons.rc2 | 13 + mapedit/ItemIcons/resource.h | 66 + mapedit/ItemIcons/stdafx.cpp | 7 + mapedit/ItemIcons/stdafx.h | 46 + mapedit/Lex_Lib/Debug/BuildLog.htm | Bin 0 -> 21932 bytes mapedit/Lex_Lib/Debug/Lex_Lib.exe | Bin 0 -> 499200 bytes .../Lex_Lib/Debug/Lex_Lib.exe.embed.manifest | 10 + .../Debug/Lex_Lib.exe.embed.manifest.res | Bin 0 -> 472 bytes .../Debug/Lex_Lib.exe.intermediate.manifest | 10 + mapedit/Lex_Lib/Debug/mt.dep | 1 + mapedit/Lex_Lib/Debug/vc80.idb | Bin 0 -> 27648 bytes mapedit/Lex_Lib/Debug/vc90.idb | Bin 0 -> 35840 bytes mapedit/Lex_Lib/Lex_Lib.cpp | 10 + mapedit/Lex_Lib/Lex_Lib.vcproj | 208 ++ mapedit/Lex_Lib/Release/BuildLog.htm | Bin 0 -> 8002 bytes mapedit/Lex_Lib/Release/Lex_Lib.exe | Bin 0 -> 69120 bytes .../Release/Lex_Lib.exe.intermediate.manifest | 10 + mapedit/Lex_Lib/Release/mt.dep | 1 + mapedit/Lex_Lib/Release/vc80.idb | Bin 0 -> 27648 bytes mapedit/Lex_Lib/Release/vc90.idb | Bin 0 -> 27648 bytes mapedit/Lex_Lib/stdafx.cpp | 8 + mapedit/Lex_Lib/stdafx.h | 12 + mapedit/Podlahar/ColorButton.cpp | 46 + mapedit/Podlahar/ColorButton.h | 26 + mapedit/Podlahar/ImageView.cpp | 64 + mapedit/Podlahar/ImageView.h | 27 + mapedit/Podlahar/Podlahar.cpp | 96 + mapedit/Podlahar/Podlahar.h | 32 + mapedit/Podlahar/Podlahar.rc | 235 ++ mapedit/Podlahar/Podlahar.sln | 30 + mapedit/Podlahar/Podlahar.vcproj | 338 ++ mapedit/Podlahar/PodlaharDlg.cpp | 260 ++ mapedit/Podlahar/PodlaharDlg.h | 62 + mapedit/Podlahar/Podlahy.c | 397 +++ mapedit/Podlahar/res/Podlahar.ico | Bin 0 -> 1078 bytes mapedit/Podlahar/res/Podlahar.rc2 | 13 + mapedit/Podlahar/res/Podlahář.ico | Bin 0 -> 21630 bytes mapedit/Podlahar/res/Podlahář.rc2 | 13 + mapedit/Podlahar/resource.h | 39 + mapedit/Podlahar/stdafx.cpp | 7 + mapedit/Podlahar/stdafx.h | 41 + release/Skeldal.exe | Bin 0 -> 1044480 bytes release/WinAmp.pch | Bin 0 -> 6684672 bytes release/crashdump.dmp | Bin 0 -> 23718 bytes release/crashdump.suo | Bin 0 -> 13312 bytes 542 files changed, 120675 insertions(+) create mode 100644 .gitignore create mode 100644 .vs/Skeldal/v17/.suo create mode 100644 3DTEST/TEXTURAA.ASM create mode 100644 AdvMan/AdvMan.cpp create mode 100644 AdvMan/AdvMan.h create mode 100644 AdvMan/AdvMan.rc create mode 100644 AdvMan/AdvMan.sln create mode 100644 AdvMan/AdvMan.vcproj create mode 100644 AdvMan/ChildView.cpp create mode 100644 AdvMan/ChildView.h create mode 100644 AdvMan/DlgDialogy.cpp create mode 100644 AdvMan/DlgDialogy.h create mode 100644 AdvMan/DlgNoveDobr.cpp create mode 100644 AdvMan/DlgNoveDobr.h create mode 100644 AdvMan/DlgNovyDialog.cpp create mode 100644 AdvMan/DlgNovyDialog.h create mode 100644 AdvMan/FCS_tasker.h create mode 100644 AdvMan/FS_tasker.h create mode 100644 AdvMan/MainFrm.cpp create mode 100644 AdvMan/MainFrm.h create mode 100644 AdvMan/Pathname.cpp create mode 100644 AdvMan/Pathname.h create mode 100644 AdvMan/StdAfx.cpp create mode 100644 AdvMan/StdAfx.h create mode 100644 AdvMan/bgraph2dx.h create mode 100644 AdvMan/debug.h create mode 100644 AdvMan/idc_note.ico create mode 100644 AdvMan/mem.h create mode 100644 AdvMan/res/AdvMan.ico create mode 100644 AdvMan/res/AdvMan.rc2 create mode 100644 AdvMan/res/Toolbar.bmp create mode 100644 AdvMan/res/editory.bmp create mode 100644 AdvMan/res/prekladace.bmp create mode 100644 AdvMan/resource.h create mode 100644 AdvMan/skeldal_win.h create mode 100644 DDLReader/DDLFile.cpp create mode 100644 DDLReader/DDLFile.h create mode 100644 DDLReader/DDLReader.cpp create mode 100644 DDLReader/DDLReader.h create mode 100644 DDLReader/DDLReader.rc create mode 100644 DDLReader/DDLReader.sln create mode 100644 DDLReader/DDLReader.vcproj create mode 100644 DDLReader/DDLReaderDlg.cpp create mode 100644 DDLReader/DDLReaderDlg.h create mode 100644 DDLReader/DlgProgress.cpp create mode 100644 DDLReader/DlgProgress.h create mode 100644 DDLReader/IWStringEffect.h create mode 100644 DDLReader/Projects/Skeldal/DDLReader/DDLFile.cpp create mode 100644 DDLReader/Projects/Skeldal/DDLReader/DDLFile.h create mode 100644 DDLReader/Projects/Skeldal/DDLReader/DDLReader.cpp create mode 100644 DDLReader/Projects/Skeldal/DDLReader/DDLReader.h create mode 100644 DDLReader/Projects/Skeldal/DDLReader/DDLReader.rc create mode 100644 DDLReader/Projects/Skeldal/DDLReader/DDLReader.sln create mode 100644 DDLReader/Projects/Skeldal/DDLReader/DDLReader.vcproj create mode 100644 DDLReader/Projects/Skeldal/DDLReader/DDLReaderDlg.cpp create mode 100644 DDLReader/Projects/Skeldal/DDLReader/DDLReaderDlg.h create mode 100644 DDLReader/Projects/Skeldal/DDLReader/DlgProgress.cpp create mode 100644 DDLReader/Projects/Skeldal/DDLReader/DlgProgress.h create mode 100644 DDLReader/Projects/Skeldal/DDLReader/IWStringEffect.h create mode 100644 DDLReader/Projects/Skeldal/DDLReader/StdAfx.cpp create mode 100644 DDLReader/Projects/Skeldal/DDLReader/StdAfx.h create mode 100644 DDLReader/Projects/Skeldal/DDLReader/WPathname.cpp create mode 100644 DDLReader/Projects/Skeldal/DDLReader/WPathname.h create mode 100644 DDLReader/Projects/Skeldal/DDLReader/WString.cpp create mode 100644 DDLReader/Projects/Skeldal/DDLReader/WString.h create mode 100644 DDLReader/Projects/Skeldal/DDLReader/WStringMemory.cpp create mode 100644 DDLReader/Projects/Skeldal/DDLReader/WStringMemory.h create mode 100644 DDLReader/Projects/Skeldal/DDLReader/WStringProxy.cpp create mode 100644 DDLReader/Projects/Skeldal/DDLReader/WStringProxy.h create mode 100644 DDLReader/Projects/Skeldal/DDLReader/res/DDLReader.ico create mode 100644 DDLReader/Projects/Skeldal/DDLReader/resource.h create mode 100644 DDLReader/StdAfx.cpp create mode 100644 DDLReader/StdAfx.h create mode 100644 DDLReader/WPathname.cpp create mode 100644 DDLReader/WPathname.h create mode 100644 DDLReader/WString.cpp create mode 100644 DDLReader/WString.h create mode 100644 DDLReader/WStringMemory.cpp create mode 100644 DDLReader/WStringMemory.h create mode 100644 DDLReader/WStringProxy.cpp create mode 100644 DDLReader/WStringProxy.h create mode 100644 DDLReader/res/DDLReader.ico create mode 100644 DDLReader/res/DDLReader.rc2 create mode 100644 DDLReader/resource.h create mode 100644 FONT/BIG.FON create mode 100644 FONT/BIG2.FON create mode 100644 FONT/BOLDCZ.FON create mode 100644 FONT/BROOKLIN.FON create mode 100644 FONT/EUROMODE.FON create mode 100644 FONT/FONT4X8.FON create mode 100644 FONT/FONT5X8.FON create mode 100644 FONT/FONT6X9.FON create mode 100644 FONT/IKONES.FON create mode 100644 FONT/KNIHA.FON create mode 100644 FONT/SADA16.FON create mode 100644 FONT/SADA7.FON create mode 100644 FONT/TIMESBIG.FON create mode 100644 FONT/TIMESBIT.FON create mode 100644 FONT/TIMESE.FON create mode 100644 FONT/TINY.FON create mode 100644 FONT/ikony.fon create mode 100644 GAME/AUTOMAP.C create mode 100644 GAME/BOLDCZ.FON create mode 100644 GAME/BUILDER.C create mode 100644 GAME/CHARGEN.C create mode 100644 GAME/CHARGEN2.C create mode 100644 GAME/CLK_MAP.C create mode 100644 GAME/CRC.C create mode 100644 GAME/DIALOGY.C create mode 100644 GAME/DLGLIB.C create mode 100644 GAME/DUMP.C create mode 100644 GAME/ENCRYPT.C create mode 100644 GAME/ENEMY.C create mode 100644 GAME/ENGINE1.C create mode 100644 GAME/ENGINE1.H create mode 100644 GAME/ENGINE2.ASM create mode 100644 GAME/GAMESAVE.C create mode 100644 GAME/GLOBALS.H create mode 100644 GAME/GLOBMAP.C create mode 100644 GAME/INTERFAC.C create mode 100644 GAME/INV.C create mode 100644 GAME/KNIHA.C create mode 100644 GAME/KOUZLA.C create mode 100644 GAME/MACROS.C create mode 100644 GAME/MENU.C create mode 100644 GAME/REALGAME.C create mode 100644 GAME/SERIAL.C create mode 100644 GAME/SETUP.C create mode 100644 GAME/SKELDAL.C create mode 100644 GAME/SNDandMUS.C create mode 100644 GAME/SOUBOJE.C create mode 100644 GAME/SPECPROC.C create mode 100644 GAME/SPECPROC.H create mode 100644 GAME/TRANSAV.C create mode 100644 GAME/WIZARD.C create mode 100644 GAME/WIZARD.H create mode 100644 GAME/engine2.c create mode 100644 GAME/extras.h create mode 100644 GAME/version.h create mode 100644 GIF/Decoder.c create mode 100644 GIF/Errs.h create mode 100644 GIF/GIF.H create mode 100644 GIF/GIF2.C create mode 100644 GIF/GIF2XED.C create mode 100644 GIF/Gif.c create mode 100644 GIF/STD.H create mode 100644 INST/SETUP.C create mode 100644 INST/SETUP.H create mode 100644 INST/SETUPCPY.C create mode 100644 INST/SETUPCPY.H create mode 100644 INST/SETUPLIB.C create mode 100644 INST/SETUPLIB.H create mode 100644 INST/SETVIDEO.C create mode 100644 INST/SETVIDEO.H create mode 100644 INST/STUB.C create mode 100644 INST/TEXTLIB.ASM create mode 100644 INST/TEXTLIB.C create mode 100644 LIBS/ADDTEXT.C create mode 100644 LIBS/ADVINST.C create mode 100644 LIBS/BASICOBJ.C create mode 100644 LIBS/BASICOBJ.H create mode 100644 LIBS/BGRAPH.C create mode 100644 LIBS/BGRAPH.H create mode 100644 LIBS/BGRAPH1.ASM create mode 100644 LIBS/BGRAPH2A.ASM create mode 100644 LIBS/BLDICONS.C create mode 100644 LIBS/BMOUSE.C create mode 100644 LIBS/BMOUSE.H create mode 100644 LIBS/BMP2HI.C create mode 100644 LIBS/Bgraph2.c create mode 100644 LIBS/CSPELLS.C create mode 100644 LIBS/DEVICES.C create mode 100644 LIBS/DEVICES.H create mode 100644 LIBS/DOSERR.ASM create mode 100644 LIBS/DOSERR.H create mode 100644 LIBS/ENGINE1.C create mode 100644 LIBS/ENGINE2.ASM create mode 100644 LIBS/ERRTEST.C create mode 100644 LIBS/EVENT.C create mode 100644 LIBS/EVENT.H create mode 100644 LIBS/EXPAND.C create mode 100644 LIBS/EXTRACT.C create mode 100644 LIBS/FASTLOAD.C create mode 100644 LIBS/GRAPHTST.C create mode 100644 LIBS/GUI.C create mode 100644 LIBS/GUI.H create mode 100644 LIBS/INICFG.C create mode 100644 LIBS/INICFG.H create mode 100644 LIBS/LEX_LIB.C create mode 100644 LIBS/LZWA.ASM create mode 100644 LIBS/MEMMAN.C create mode 100644 LIBS/MEMMAN.H create mode 100644 LIBS/MGFPLAY.C create mode 100644 LIBS/MGFPLAY.H create mode 100644 LIBS/MGIFMEM.C create mode 100644 LIBS/MGIFMEM.H create mode 100644 LIBS/MGIFPLAYA.C create mode 100644 LIBS/MOUSE.C create mode 100644 LIBS/PADY.C create mode 100644 LIBS/PCSPEAK.ASM create mode 100644 LIBS/PCSPEAK.H create mode 100644 LIBS/PCX.C create mode 100644 LIBS/PCX.H create mode 100644 LIBS/READFONT.C create mode 100644 LIBS/STRLISTS.C create mode 100644 LIBS/STRLISTS.H create mode 100644 LIBS/STRLITE.C create mode 100644 LIBS/STRLITE.H create mode 100644 LIBS/SWAPER.C create mode 100644 LIBS/TASKER.ASM create mode 100644 LIBS/TESTSVGA.C create mode 100644 LIBS/TST.C create mode 100644 LIBS/TYPES.H create mode 100644 LIBS/VESATST.C create mode 100644 LIBS/WAV.C create mode 100644 LIBS/WAV.H create mode 100644 LIBS/WAV_MEM.C create mode 100644 LIBS/WAV_MEM.H create mode 100644 LIBS/ZVUK.C create mode 100644 LIBS/ZVUK.H create mode 100644 LIBS/ZVUKA.ASM create mode 100644 LIBS/bgraph2a.c create mode 100644 LIBS/bgraph2a.cpp create mode 100644 LIBS/bios.h create mode 100644 LIBS/mem.h create mode 100644 LIBS/mgifmapmem.c create mode 100644 LIBS/mgifmapmem.h create mode 100644 LIBS/zvuk_dx.cpp create mode 100644 LZWC.C create mode 100644 LZWC.H create mode 100644 MAPS/CDIALOGY.C create mode 100644 MAPS/DLGPRINT.C create mode 100644 MAPS/DUMP.C create mode 100644 MAPS/DUMP.H create mode 100644 MAPS/EDIT_MAP.C create mode 100644 MAPS/EDIT_MAP.H create mode 100644 MAPS/GLOBALS.H create mode 100644 MAPS/ITEMS.C create mode 100644 MAPS/ITEMS2.C create mode 100644 MAPS/MAPEDIT.C create mode 100644 MAPS/MAPY.C create mode 100644 MAPS/MAPY.H create mode 100644 MAPS/MOB_EDIT.C create mode 100644 MAPS/MOB_EDIT.H create mode 100644 MAPS/PCXVIEW.C create mode 100644 MAPS/SAVE_MAP.C create mode 100644 MAPS/SAVE_MAP.H create mode 100644 MAPS/STENY.C create mode 100644 MAPS/STENY.H create mode 100644 MAPS/WIN_TEST.C create mode 100644 MAPS/WIZ_TOOL.C create mode 100644 MAPS/WIZ_TOOL.H create mode 100644 PCX/3DMAN.C create mode 100644 PCX/BOLDCZ.FON create mode 100644 PCX/PCX.C create mode 100644 PCX/PCX.H create mode 100644 PCX/PCXTST.C create mode 100644 PCX/PODLAHY.C create mode 100644 POKUSSCR.C create mode 100644 Skeldal.sln create mode 100644 Skeldal.suo create mode 100644 Skeldal.vcproj create mode 100644 StdAfx.cpp create mode 100644 StdAfx.h create mode 100644 UTILS/ITEMLIST.C create mode 100644 UTILS/Podlahar/Podlahar.cpp create mode 100644 UTILS/Podlahar/Podlahar.h create mode 100644 UTILS/Podlahar/Podlahar.rc create mode 100644 UTILS/Podlahar/Podlahar.vcproj create mode 100644 UTILS/Podlahar/PodlaharDlg.cpp create mode 100644 UTILS/Podlahar/PodlaharDlg.h create mode 100644 UTILS/Podlahar/Resource.h create mode 100644 UTILS/Podlahar/res/Podlahar.ico create mode 100644 UTILS/Podlahar/res/Podlahar.rc2 create mode 100644 UTILS/Podlahar/stdafx.cpp create mode 100644 UTILS/Podlahar/stdafx.h create mode 100644 VIDEO/ANIPACK.ASM create mode 100644 VIDEO/ANIPACK.H create mode 100644 VIDEO/BITLINE.ASM create mode 100644 VIDEO/BITLINE.H create mode 100644 VIDEO/BOLDCZ.FON create mode 100644 VIDEO/CINEMA.H create mode 100644 VIDEO/CNMBUILD.C create mode 100644 VIDEO/CNMCONTR.C create mode 100644 VIDEO/FLC.C create mode 100644 VIDEO/FLC.H create mode 100644 VIDEO/FLC/ANALYSE/DOSMEM.C create mode 100644 VIDEO/FLC/ANALYSE/DOSMEM.H create mode 100644 VIDEO/FLC/ANALYSE/FLC.C create mode 100644 VIDEO/FLC/ANALYSE/FLC.H create mode 100644 VIDEO/FLC/ANALYSE/PLAY.C create mode 100644 VIDEO/FLC/ANALYSE/VESA.C create mode 100644 VIDEO/FLC/ANALYSE/VESA.H create mode 100644 VIDEO/FLC/ANALYSE/VESA_.ASM create mode 100644 VIDEO/FLC/DOSMEM.C create mode 100644 VIDEO/FLC/DOSMEM.H create mode 100644 VIDEO/FLC/FLC.C create mode 100644 VIDEO/FLC/FLC.H create mode 100644 VIDEO/FLC/PLAY.C create mode 100644 VIDEO/FLC/VESA.C create mode 100644 VIDEO/FLC/VESA.H create mode 100644 VIDEO/FLC/VESA_.ASM create mode 100644 VIDEO/FLC2MGIF.C create mode 100644 VIDEO/JPEGMGFA.ASM create mode 100644 VIDEO/JPEGMGIF.C create mode 100644 VIDEO/JPEGMGIF.H create mode 100644 VIDEO/JPEG_SIM.C create mode 100644 VIDEO/LZW.C create mode 100644 VIDEO/LZW.H create mode 100644 VIDEO/LZWA.ASM create mode 100644 VIDEO/LZWC.C create mode 100644 VIDEO/LZW_EX.C create mode 100644 VIDEO/MGFPLAYA.ASM create mode 100644 VIDEO/MGFSOUND.C create mode 100644 VIDEO/MGIF.C create mode 100644 VIDEO/MGIF98.C create mode 100644 VIDEO/MGIFCAT.C create mode 100644 VIDEO/MGIFEACT.C create mode 100644 VIDEO/MGIFEACT.H create mode 100644 VIDEO/MGIFEBLD.C create mode 100644 VIDEO/MGIFEBLD.H create mode 100644 VIDEO/MGIFEDIT.C create mode 100644 VIDEO/MGIFEDIT.H create mode 100644 VIDEO/MGIFEOBJ.C create mode 100644 VIDEO/MGIFEOBJ.H create mode 100644 VIDEO/MGIFPLAY.C create mode 100644 VIDEO/OLD/MGIFMEM.C create mode 100644 VIDEO/OLD/MGIFMEM.H create mode 100644 VIDEO/PCX2MGIF.C create mode 100644 VIDEO/PLAY.C create mode 100644 VIDEO/PLAYCNM.C create mode 100644 VIDEO/SADA7.FON create mode 100644 VIDEO/VIDEO.C create mode 100644 Windows/BGraph2Dx.cpp create mode 100644 Windows/BGraph2Dx.h create mode 100644 Windows/BOLDCZ.FON create mode 100644 Windows/FCS_Tasker.c create mode 100644 Windows/FCS_Tasker.h create mode 100644 Windows/Music.cpp create mode 100644 Windows/Music.h create mode 100644 Windows/Skeldal.rc create mode 100644 Windows/StdAfx.cpp create mode 100644 Windows/StdAfx.h create mode 100644 Windows/WAInputPlugin.cpp create mode 100644 Windows/WAInputPlugin.h create mode 100644 Windows/WAPlayer.cpp create mode 100644 Windows/WAPlayer.h create mode 100644 Windows/WaveOut.cpp create mode 100644 Windows/WaveOut.h create mode 100644 Windows/WinAmpInterface.cpp create mode 100644 Windows/WinAmpInterface.h create mode 100644 Windows/bios.c create mode 100644 Windows/bios.h create mode 100644 Windows/debug.h create mode 100644 Windows/extras.rtf create mode 100644 Windows/fiber_task.h create mode 100644 Windows/icon.bmp create mode 100644 Windows/icon.ico create mode 100644 Windows/install.cpp create mode 100644 Windows/install.h create mode 100644 Windows/konfig.cpp create mode 100644 Windows/konfig.h create mode 100644 Windows/logo.bmp create mode 100644 Windows/mem.h create mode 100644 Windows/plugins.rtf create mode 100644 Windows/resource.h create mode 100644 Windows/richview.cpp create mode 100644 Windows/richview.h create mode 100644 Windows/seladv_male.bmp create mode 100644 Windows/skeldal_win.c create mode 100644 Windows/skeldal_win.h create mode 100644 Windows/uvodni.bmp create mode 100644 Windows/uvodni.cpp create mode 100644 Windows/uvodni.h create mode 100644 Windows/uvodni_sel.bmp create mode 100644 Windows/wa_ipc.h create mode 100644 Windows/winamp/In2.h create mode 100644 Windows/winamp/Out.h create mode 100644 Windows/zvuk_win.cpp create mode 100644 ZVUK/ANALYSE/DOSMEM.C create mode 100644 ZVUK/ANALYSE/DOSMEM.H create mode 100644 ZVUK/ANALYSE/FLC.C create mode 100644 ZVUK/ANALYSE/FLC.H create mode 100644 ZVUK/ANALYSE/PLAY.C create mode 100644 ZVUK/ANALYSE/VESA.C create mode 100644 ZVUK/ANALYSE/VESA.H create mode 100644 ZVUK/ANALYSE/VESA_.ASM create mode 100644 ZVUK/DOSMEM.C create mode 100644 ZVUK/DOSMEM.H create mode 100644 ZVUK/EXAMPLE.ASM create mode 100644 ZVUK/FLC.C create mode 100644 ZVUK/FLC.H create mode 100644 ZVUK/PLAY.C create mode 100644 ZVUK/SNDPACK.C create mode 100644 ZVUK/SPK_TEST.C create mode 100644 ZVUK/TRACK.C create mode 100644 ZVUK/VESA.C create mode 100644 ZVUK/VESA.H create mode 100644 ZVUK/VESA_.ASM create mode 100644 ZVUK/ZVUK1.C create mode 100644 ZVUK/ZVUK1A.ASM create mode 100644 ZVUK/ZVUK2A.ASM create mode 100644 addonKouzla.odt create mode 100644 crashdump.cpp create mode 100644 crashdump.h create mode 100644 cztable.cpp create mode 100644 cztable.h create mode 100644 extras.h create mode 100644 history.txt create mode 100644 html/dont export/export.bmp create mode 100644 insteng/SETUP.C create mode 100644 insteng/SETUP.H create mode 100644 insteng/SETUPCPY.C create mode 100644 insteng/SETUPCPY.H create mode 100644 insteng/SETUPLIB.C create mode 100644 insteng/SETUPLIB.H create mode 100644 insteng/SETVIDEO.C create mode 100644 insteng/SETVIDEO.H create mode 100644 insteng/STUB.C create mode 100644 insteng/TEXTLIB.ASM create mode 100644 insteng/TEXTLIB.C create mode 100644 mapedit.cpp create mode 100644 mapedit.vcproj create mode 100644 mapedit/CDialogy/CDialogy.vcproj create mode 100644 mapedit/CDialogy/Debug/BuildLog.htm create mode 100644 mapedit/CDialogy/Debug/CDialogy.exe create mode 100644 mapedit/CDialogy/Debug/CDialogy.exe.embed.manifest create mode 100644 mapedit/CDialogy/Debug/CDialogy.exe.embed.manifest.res create mode 100644 mapedit/CDialogy/Debug/CDialogy.exe.intermediate.manifest create mode 100644 mapedit/CDialogy/Debug/mt.dep create mode 100644 mapedit/CDialogy/Debug/vc80.idb create mode 100644 mapedit/CDialogy/Debug/vc90.idb create mode 100644 mapedit/CDialogy/Release/BuildLog.htm create mode 100644 mapedit/CDialogy/Release/CDialogy.exe create mode 100644 mapedit/CDialogy/Release/CDialogy.exe.intermediate.manifest create mode 100644 mapedit/CDialogy/Release/mt.dep create mode 100644 mapedit/CDialogy/Release/vc80.idb create mode 100644 mapedit/CDialogy/Release/vc90.idb create mode 100644 mapedit/CSpells/CSpells.cpp create mode 100644 mapedit/CSpells/CSpells.vcproj create mode 100644 mapedit/CSpells/Debug/BuildLog.htm create mode 100644 mapedit/CSpells/Debug/CSpells.exe create mode 100644 mapedit/CSpells/Debug/CSpells.exe.embed.manifest create mode 100644 mapedit/CSpells/Debug/CSpells.exe.embed.manifest.res create mode 100644 mapedit/CSpells/Debug/CSpells.exe.intermediate.manifest create mode 100644 mapedit/CSpells/Debug/mt.dep create mode 100644 mapedit/CSpells/Debug/vc80.idb create mode 100644 mapedit/CSpells/Debug/vc90.idb create mode 100644 mapedit/CSpells/Release/BuildLog.htm create mode 100644 mapedit/CSpells/Release/CSpells.exe create mode 100644 mapedit/CSpells/Release/CSpells.exe.intermediate.manifest create mode 100644 mapedit/CSpells/Release/mt.dep create mode 100644 mapedit/CSpells/Release/vc80.idb create mode 100644 mapedit/CSpells/Release/vc90.idb create mode 100644 mapedit/CSpells/stdafx.cpp create mode 100644 mapedit/CSpells/stdafx.h create mode 100644 mapedit/ColEdit/ColEdit.cpp create mode 100644 mapedit/ColEdit/ColEdit.h create mode 100644 mapedit/ColEdit/ColEdit.rc create mode 100644 mapedit/ColEdit/ColEdit.sln create mode 100644 mapedit/ColEdit/ColEdit.vcproj create mode 100644 mapedit/ColEdit/ColEditDlg.cpp create mode 100644 mapedit/ColEdit/ColEditDlg.h create mode 100644 mapedit/ColEdit/EditPaletteDlg.cpp create mode 100644 mapedit/ColEdit/EditPaletteDlg.h create mode 100644 mapedit/ColEdit/PaletteEditor.cpp create mode 100644 mapedit/ColEdit/PaletteEditor.h create mode 100644 mapedit/ColEdit/StdAfx.cpp create mode 100644 mapedit/ColEdit/StdAfx.h create mode 100644 mapedit/ColEdit/res/ColEdit.ico create mode 100644 mapedit/ColEdit/res/ColEdit.rc2 create mode 100644 mapedit/ColEdit/res/down.ico create mode 100644 mapedit/ColEdit/res/icon1.ico create mode 100644 mapedit/ColEdit/resource.h create mode 100644 mapedit/Debug/BuildLog.htm create mode 100644 mapedit/Debug/MapEdit.bsc create mode 100644 mapedit/Debug/MapEdit.exe create mode 100644 mapedit/Debug/MapEdit.exe.embed.manifest create mode 100644 mapedit/Debug/MapEdit.exe.embed.manifest.res create mode 100644 mapedit/Debug/MapEdit.exe.intermediate.manifest create mode 100644 mapedit/Debug/MapEdit.pch create mode 100644 mapedit/Debug/WinAmpInt.pch create mode 100644 mapedit/Debug/mapedit.res create mode 100644 mapedit/Debug/mt.dep create mode 100644 mapedit/Debug/vc80.idb create mode 100644 mapedit/ItemIcons/DlgOpen.cpp create mode 100644 mapedit/ItemIcons/DlgOpen.h create mode 100644 mapedit/ItemIcons/IconViewerButton.cpp create mode 100644 mapedit/ItemIcons/IconViewerButton.h create mode 100644 mapedit/ItemIcons/ItemIcons.cpp create mode 100644 mapedit/ItemIcons/ItemIcons.h create mode 100644 mapedit/ItemIcons/ItemIcons.rc create mode 100644 mapedit/ItemIcons/ItemIcons.sln create mode 100644 mapedit/ItemIcons/ItemIcons.vcproj create mode 100644 mapedit/ItemIcons/ItemIconsDlg.cpp create mode 100644 mapedit/ItemIcons/ItemIconsDlg.h create mode 100644 mapedit/ItemIcons/res/ItemIcons.ico create mode 100644 mapedit/ItemIcons/res/ItemIcons.rc2 create mode 100644 mapedit/ItemIcons/resource.h create mode 100644 mapedit/ItemIcons/stdafx.cpp create mode 100644 mapedit/ItemIcons/stdafx.h create mode 100644 mapedit/Lex_Lib/Debug/BuildLog.htm create mode 100644 mapedit/Lex_Lib/Debug/Lex_Lib.exe create mode 100644 mapedit/Lex_Lib/Debug/Lex_Lib.exe.embed.manifest create mode 100644 mapedit/Lex_Lib/Debug/Lex_Lib.exe.embed.manifest.res create mode 100644 mapedit/Lex_Lib/Debug/Lex_Lib.exe.intermediate.manifest create mode 100644 mapedit/Lex_Lib/Debug/mt.dep create mode 100644 mapedit/Lex_Lib/Debug/vc80.idb create mode 100644 mapedit/Lex_Lib/Debug/vc90.idb create mode 100644 mapedit/Lex_Lib/Lex_Lib.cpp create mode 100644 mapedit/Lex_Lib/Lex_Lib.vcproj create mode 100644 mapedit/Lex_Lib/Release/BuildLog.htm create mode 100644 mapedit/Lex_Lib/Release/Lex_Lib.exe create mode 100644 mapedit/Lex_Lib/Release/Lex_Lib.exe.intermediate.manifest create mode 100644 mapedit/Lex_Lib/Release/mt.dep create mode 100644 mapedit/Lex_Lib/Release/vc80.idb create mode 100644 mapedit/Lex_Lib/Release/vc90.idb create mode 100644 mapedit/Lex_Lib/stdafx.cpp create mode 100644 mapedit/Lex_Lib/stdafx.h create mode 100644 mapedit/Podlahar/ColorButton.cpp create mode 100644 mapedit/Podlahar/ColorButton.h create mode 100644 mapedit/Podlahar/ImageView.cpp create mode 100644 mapedit/Podlahar/ImageView.h create mode 100644 mapedit/Podlahar/Podlahar.cpp create mode 100644 mapedit/Podlahar/Podlahar.h create mode 100644 mapedit/Podlahar/Podlahar.rc create mode 100644 mapedit/Podlahar/Podlahar.sln create mode 100644 mapedit/Podlahar/Podlahar.vcproj create mode 100644 mapedit/Podlahar/PodlaharDlg.cpp create mode 100644 mapedit/Podlahar/PodlaharDlg.h create mode 100644 mapedit/Podlahar/Podlahy.c create mode 100644 mapedit/Podlahar/res/Podlahar.ico create mode 100644 mapedit/Podlahar/res/Podlahar.rc2 create mode 100644 mapedit/Podlahar/res/Podlahář.ico create mode 100644 mapedit/Podlahar/res/Podlahář.rc2 create mode 100644 mapedit/Podlahar/resource.h create mode 100644 mapedit/Podlahar/stdafx.cpp create mode 100644 mapedit/Podlahar/stdafx.h create mode 100644 release/Skeldal.exe create mode 100644 release/WinAmp.pch create mode 100644 release/crashdump.dmp create mode 100644 release/crashdump.suo diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cb384a3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*.user +*.old +*.XML +.svn +_UpgradeReport_Files +/Bin +/Debug \ No newline at end of file diff --git a/.vs/Skeldal/v17/.suo b/.vs/Skeldal/v17/.suo new file mode 100644 index 0000000000000000000000000000000000000000..369497b7246445b80aca1ddcd702601875faa5e9 GIT binary patch literal 156160 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 Zcp?(+>rj6ed)}qaqof#5Ot2gB{6CzaxtRa} literal 0 HcmV?d00001 diff --git a/3DTEST/TEXTURAA.ASM b/3DTEST/TEXTURAA.ASM new file mode 100644 index 0000000..58da83a --- /dev/null +++ b/3DTEST/TEXTURAA.ASM @@ -0,0 +1,64 @@ +.model small +.386 + +DGROUP group _DATA + +extrn _start_poss:word +extrn _end_poss:word +extrn _scr_max_x:dword +extrn _scr_next_line:dword + +_TEXT segment byte public 'CODE' use32 + assume CS:_TEXT + assume DS:DGROUP + +public draw_flat_triangle_ +draw_flat_triangle_: +dft_lp2:mov ebx,edi + movsx edx,_start_poss[esi*2] + lea edi,[ebx+edx*2] + cmp dx,_end_poss[esi*2] + jz dft_skpa + jl dft_dirr + std + cmp edx,0 + js dft_skpa + cmp edx,_scr_max_x + jbe dft_drr1 + mov edi,_scr_max_x + lea edi,[ebx+edi*2] + jmp dft_drr1 +dft_dirr:cld + cmp edx,_scr_max_x + jg dft_skpa + cmp edx,0 + jns dft_drr1 + mov edi,ebx +dft_drr1:movsx edx,_end_poss[esi*2] + cmp edx,0 + jns dft_dc1 + xor edx,edx + jmp dft_dc2 +dft_dc1:cmp edx,_scr_max_x + jna dft_dc2 + mov edx,_scr_max_x +dft_dc2:shl edx,1 + add edx,ebx +dft_lp1: stosw + cmp edi,edx + jnz dft_lp1 +dft_skpa: + stosw + mov edi,_scr_next_line + lea edi,[ebx+edi] + inc esi + dec ecx + jnz dft_lp2 + cld + ret +_TEXT ends +end + + + + diff --git a/AdvMan/AdvMan.cpp b/AdvMan/AdvMan.cpp new file mode 100644 index 0000000..88670a8 --- /dev/null +++ b/AdvMan/AdvMan.cpp @@ -0,0 +1,187 @@ +// AdvMan.cpp : Defines the class behaviors for the application. +// + +#include "stdafx.h" +#include "AdvMan.h" + +#include "MainFrm.h" +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CAdvManApp + +BEGIN_MESSAGE_MAP(CAdvManApp, CWinApp) + //{{AFX_MSG_MAP(CAdvManApp) + ON_COMMAND(ID_APP_ABOUT, OnAppAbout) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CAdvManApp construction + +CAdvManApp::CAdvManApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CAdvManApp object + +CAdvManApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CAdvManApp initialization + +extern "C" +{ +#include "..\crashdump.h" + +int GetExeVersion(); +} + +int GetExeVersion() +{ + return 1; +} + +BOOL CAdvManApp::InitInstance() +{ +InitCrashDump(); + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + +#ifdef _AFXDLL + Enable3dControls(); // Call this when using MFC in a shared DLL +#else + Enable3dControlsStatic(); // Call this when linking to MFC statically +#endif + + // Change the registry key under which our settings are stored. + // TODO: You should modify this string to be something appropriate + // such as the name of your company or organization. + SetRegistryKey(_T("Bredysoft")); + + + // To create the main window, this code creates a new frame window + // object and then sets it as the application's main window object. + + CMainFrame* pFrame = new CMainFrame; + m_pMainWnd = pFrame; + + // create and load the frame with its resources + + pFrame->LoadFrame(IDR_MAINFRAME, + WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, + NULL); + + + + + // The one and only window has been initialized, so show and update it. + pFrame->ShowWindow(SW_SHOW); + pFrame->UpdateWindow(); + + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CAdvManApp message handlers + + + + + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + // No message handlers + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +// App command to run the dialog +void CAdvManApp::OnAppAbout() +{ + CAboutDlg aboutDlg; + aboutDlg.DoModal(); +} + +///////////////////////////////////////////////////////////////////////////// +// CAdvManApp message handlers + +struct TestDlgInfo +{ + MSG *msg; + BOOL found; + HWND exclude; +}; + +static BOOL WINAPI TestDlgWindows(HWND hWnd, LPARAM lParam) +{ + TestDlgInfo *nfo=(TestDlgInfo *)lParam; + if (hWnd==nfo->exclude) return TRUE; + if (SendMessage(hWnd,WM_APP+9998,0,(LPARAM)nfo->msg) || IsDialogMessage(hWnd,nfo->msg)) + { + nfo->found=TRUE; + return FALSE; + } + return TRUE; +} + +BOOL CAdvManApp::PreTranslateMessage(MSG *pMsg) +{ + TestDlgInfo nfo; + nfo.msg=pMsg; + nfo.found=FALSE; + nfo.exclude=*m_pMainWnd; + + EnumThreadWindows(GetCurrentThreadId(),TestDlgWindows,(LPARAM)&nfo); + return nfo.found; +} diff --git a/AdvMan/AdvMan.h b/AdvMan/AdvMan.h new file mode 100644 index 0000000..f08f54b --- /dev/null +++ b/AdvMan/AdvMan.h @@ -0,0 +1,55 @@ +// AdvMan.h : main header file for the ADVMAN application +// + +#if !defined(AFX_ADVMAN_H__A43CD3B3_508C_4DDB_B89C_50FE1291B8B9__INCLUDED_) +#define AFX_ADVMAN_H__A43CD3B3_508C_4DDB_B89C_50FE1291B8B9__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CAdvManApp: +// See AdvMan.cpp for the implementation of this class +// + +class CAdvManApp : public CWinApp +{ +public: + CAdvManApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAdvManApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + +public: + //{{AFX_MSG(CAdvManApp) + afx_msg void OnAppAbout(); + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() + + virtual BOOL PreTranslateMessage(MSG *pMsg); +}; + + +///////////////////////////////////////////////////////////////////////////// + +extern CAdvManApp theApp; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_ADVMAN_H__A43CD3B3_508C_4DDB_B89C_50FE1291B8B9__INCLUDED_) diff --git a/AdvMan/AdvMan.rc b/AdvMan/AdvMan.rc new file mode 100644 index 0000000..1d9b914 --- /dev/null +++ b/AdvMan/AdvMan.rc @@ -0,0 +1,569 @@ +// 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 + +///////////////////////////////////////////////////////////////////////////// +// Czech resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY) +#ifdef _WIN32 +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT +#pragma code_page(1250) +#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 + "#define _AFX_NO_SPLITTER_RESOURCES\r\n" + "#define _AFX_NO_OLE_RESOURCES\r\n" + "#define _AFX_NO_TRACKER_RESOURCES\r\n" + "#define _AFX_NO_PROPERTY_RESOURCES\r\n" + "\r\n" + "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n" + "#ifdef _WIN32\r\n" + "LANGUAGE 9, 1\r\n" + "#pragma code_page(1252)\r\n" + "#endif //_WIN32\r\n" + "#include ""res\\AdvMan.rc2"" // non-Microsoft Visual C++ edited resources\r\n" + "#include ""afxres.rc"" // Standard components\r\n" + "#endif\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDR_MAINFRAME BITMAP "res\\Toolbar.bmp" +IDR_TOOLEDITORY BITMAP "res\\editory.bmp" +IDR_PREKLADACE BITMAP "res\\prekladace.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// Toolbar +// + +IDR_MAINFRAME TOOLBAR 16, 16 +BEGIN + BUTTON ID_FILE_NOVDOBRODRUST + BUTTON ID_FILE_NATIDOBRODRUSTV + SEPARATOR + BUTTON ID_NSTROJE_MAPEDIT + BUTTON ID_NSTROJE_TESTUJDOBRODRUSTV + SEPARATOR + BUTTON ID_APP_EXIT + SEPARATOR + BUTTON ID_APP_ABOUT +END + +IDR_TOOLEDITORY TOOLBAR 16, 15 +BEGIN + BUTTON ID_EDITORY_KOUZLATAB + BUTTON ID_EDITORY_POSTAVYTAB + BUTTON ID_EDITORY_DIALOGY + BUTTON ID_EDITORY_WEAPONSSCR + BUTTON ID_EDITORY_ITEMSPIC + BUTTON ID_EDITORY_ITEMSSCR +END + +IDR_PREKLADACE TOOLBAR 16, 15 +BEGIN + BUTTON ID_PEKLADAE_PELOKOUZLA + BUTTON ID_PEKLADAE_PELODIALOGY + BUTTON ID_PEKLADAE_PELOPOSTAVYTAB +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MAINFRAME MENU +BEGIN + POPUP "&File" + BEGIN + MENUITEM "Nov dobrodrust", ID_FILE_NOVDOBRODRUST + MENUITEM SEPARATOR + MENUITEM "Nati dobrodrustv", ID_FILE_NATIDOBRODRUSTV + MENUITEM "Znovu nast", ID_FILE_ZNOVUNAST + MENUITEM SEPARATOR + MENUITEM "E&xit", ID_APP_EXIT + END + POPUP "Editory" + BEGIN + MENUITEM "KOUZLA.TAB", ID_EDITORY_KOUZLATAB + MENUITEM "POSTAVY.TAB", ID_EDITORY_POSTAVYTAB + MENUITEM "Dialogy", ID_EDITORY_DIALOGY + MENUITEM "ITEMS.SCR", ID_EDITORY_ITEMSSCR + MENUITEM "ITEMS.PIC", ID_EDITORY_ITEMSPIC + MENUITEM "WEAPONS.SCR", ID_EDITORY_WEAPONSSCR + MENUITEM "Soubor ADV", ID_EDITORY_SOUBORADV + END + POPUP "Pekladae" + BEGIN + MENUITEM "Pelo kouzla", ID_PEKLADAE_PELOKOUZLA + MENUITEM "Pelo dialogy", ID_PEKLADAE_PELODIALOGY + MENUITEM "Pelo POSTAVY.TAB", ID_PEKLADAE_PELOPOSTAVYTAB + END + POPUP "Nstroje" + BEGIN + MENUITEM "MapEdit", ID_NSTROJE_MAPEDIT + MENUITEM "Testuj dobrodrustv", ID_NSTROJE_TESTUJDOBRODRUSTV + MENUITEM SEPARATOR + MENUITEM "Tvrce podlah", ID_NSTROJE_TVRCEPODLAH + MENUITEM "Tvrce palet pro nestvry", ID_NSTROJE_TVRCEPALETPRONESTVRY + + MENUITEM "Tvrce ikon pro pedmty", ID_NSTROJE_TVRCEIKONPROPEDMTY + + MENUITEM "teka DDL soubor", ID_NSTROJE_TEKADDLSOUBOR + MENUITEM SEPARATOR + MENUITEM "Exportuj dobrodrustv", ID_NSTROJE_EXPORTUJDOBRODRUSTV + + END + POPUP "&View" + BEGIN + MENUITEM "Hlavn toolbar", ID_VIEW_TOOLBAR + MENUITEM "Pekladae", ID_VIEW_PREKLADACE + MENUITEM "Editory", 32810 + MENUITEM "&Status Bar", ID_VIEW_STATUS_BAR + END + POPUP "&Help" + BEGIN + MENUITEM "&About AdvMan...", ID_APP_ABOUT + END +END + +IDR_EDITORMENU MENU +BEGIN + POPUP "Soubor" + BEGIN + MENUITEM "Uloit", IDOK + MENUITEM SEPARATOR + MENUITEM "Konec", IDCANCEL + END + POPUP "pravy" + BEGIN + MENUITEM "Zpt", ID_PRAVY_UNDO + MENUITEM SEPARATOR + MENUITEM "Koprovat", ID_UPRAVY_COPY + MENUITEM "Vyjmout", ID_UPRAVY_VYJMOUT + MENUITEM "Vloit", ID_UPRAVY_VLOZIT + MENUITEM "Vymazat", ID_UPRAVY_VYMAZAT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_NOVEDOBR DIALOGEX 0, 0, 234, 297 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Zaloit nov dobrodrustv" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + LTEXT "Jmno novho dobrodrustv",IDC_STATIC,7,7,92,8 + EDITTEXT IDC_JMENO,7,18,159,12,ES_AUTOHSCROLL | WS_GROUP + GROUPBOX "Vyber organizaci projektu",IDC_STATIC,7,36,162,60, + WS_GROUP + CONTROL "Nov organizace (doporueno)",IDC_ORGANIZACE,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,15,55,114,10 + CONTROL "Pvodn DOSov organizace (kompatibiln)",IDC_RADIO2, + "Button",BS_AUTORADIOBUTTON,15,66,152,10 + CONTROL "Ve v jedn sloce (mal projeky)",IDC_RADIO3,"Button", + BS_AUTORADIOBUTTON,15,77,121,10 + GROUPBOX "Do novho projektu vloit",IDC_STATIC,7,98,162,82, + WS_GROUP + CONTROL "Tak soubory pro editaci kouzel",IDC_KOUZLA,"Button", + BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP,15,111,117,10 + CONTROL "Tak soubory pro editaci dialog",IDC_DIALOGY,"Button", + BS_AUTOCHECKBOX,15,123,119,10 + CONTROL "Tak definice grafiky originln hry",IDC_DEFINICE, + "Button",BS_AUTOCHECKBOX,15,135,123,10 + CONTROL "Tak vechny mapy z originln hry",IDC_MAPY,"Button", + BS_AUTOCHECKBOX,15,147,127,10 + GROUPBOX "Startovn mapa",IDC_STATIC,7,183,161,29,WS_GROUP + EDITTEXT IDC_STARTMAP,16,193,145,12,ES_AUTOHSCROLL | WS_GROUP + GROUPBOX "Poet len druiny",IDC_STATIC,7,214,161,42,WS_GROUP + LTEXT "Nejmn",IDC_STATIC,15,228,29,8 + LTEXT "Nejvce",IDC_STATIC,15,242,26,8 + EDITTEXT IDC_MINPOSTAV,53,226,16,12,ES_MULTILINE | WS_GROUP + EDITTEXT IDC_MAXPOSTAV,53,240,16,12,ES_MULTILINE | WS_GROUP + DEFPUSHBUTTON "OK",IDOK,177,7,50,14,WS_GROUP + PUSHBUTTON "Storno",IDCANCEL,177,24,50,14,NOT WS_TABSTOP + CONTROL "Tak originln dialogy",IDC_ORIGDLGS,"Button", + BS_AUTOCHECKBOX,15,159,87,10 +END + +IDD_TEXTEDITOR DIALOGEX 0, 0, 599, 412 +STYLE DS_SETFONT | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | + WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "Textov editor" +MENU IDR_EDITORMENU +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + DEFPUSHBUTTON "Uloit (Ctrl+S)",IDOK,540,397,58,14 + EDITTEXT IDC_EDIT,44,0,553,395,ES_MULTILINE | ES_AUTOVSCROLL | + ES_AUTOHSCROLL | ES_WANTRETURN | NOT WS_BORDER | + WS_VSCROLL | WS_HSCROLL,WS_EX_STATICEDGE +END + +IDD_DIALOGY DIALOGEX 0, 0, 334, 202 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Dialogy" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + PUSHBUTTON "Zavt",IDCANCEL,267,24,60,14 + PUSHBUTTON "Upravit dialog",IDC_EDIT,267,68,60,14 + PUSHBUTTON "Pidat dialog",IDC_ADD,267,52,60,14 + PUSHBUTTON "Vymazat dialog",IDC_DELETE,267,85,60,14 + CONTROL "List1",IDC_DLGLIST,"SysListView32",LVS_REPORT | + LVS_SHOWSELALWAYS | LVS_EDITLABELS | WS_BORDER | + WS_TABSTOP,7,7,256,188 + PUSHBUTTON "Obnovit",IDC_RESCAN,267,181,60,14 + DEFPUSHBUTTON "OK",IDOK,267,7,60,14 +END + +IDD_NOVYDIALOG DIALOG 0, 0, 214, 105 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Nov dialog" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,157,67,50,14 + PUSHBUTTON "Cancel",IDCANCEL,157,84,50,14 + LTEXT "Popis dialogu:",IDC_STATIC,7,7,45,8 + EDITTEXT IDC_POPIS,7,18,200,12,ES_AUTOHSCROLL + LTEXT "Jmno souboru dialogu bez ppony (.dlg) - 8 znak", + IDC_STATIC,7,32,162,8 + COMBOBOX IDC_JMENO,7,43,73,61,CBS_DROPDOWN | CBS_SORT | + WS_VSCROLL | WS_TABSTOP + LTEXT "islo dialogu:",IDC_STATIC,7,60,42,8 + LTEXT "Uplatn se pouze pro nov zaloen dialog",IDC_STATIC,7, + 89,134,8 + COMBOBOX IDC_CISLO,7,72,33,105,CBS_DROPDOWN | CBS_SORT | + WS_VSCROLL | WS_TABSTOP +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_NOVEDOBR, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 227 + TOPMARGIN, 7 + BOTTOMMARGIN, 290 + END + + IDD_TEXTEDITOR, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 592 + TOPMARGIN, 7 + BOTTOMMARGIN, 405 + END + + IDD_DIALOGY, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 327 + TOPMARGIN, 7 + BOTTOMMARGIN, 195 + END + + IDD_NOVYDIALOG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 207 + TOPMARGIN, 7 + BOTTOMMARGIN, 98 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_NOTEPADICON ICON "idc_note.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDR_MAINFRAME "Adventure Manager" + IDS_NOVEDOBRODRUZSTVIDOKONCENO + "Prvodce novm dobrodrustvm dokonil vechny koly.\r\n\r\nPokud se zobrazila njak chyba, bude nutn po oprav chyby pkaz opakovat, jinak nebude dobrodrustv hrateln." + IDS_ADVFILTER "Dobrodrustv Skeldalu|*.adv|Vechny soubory|*.*||" + IDS_CHYBAPRICTENI "Chyba pi ten souboru dobrodrustv" + IDS_MAINFRAMETITLE "%s - Adventure Manager " + IDS_UNTITLED "Nepojmenovan.ADV" + IDS_CANNOTEXECUTE "Nemohu spustit aplikaci '%1'" + IDS_NEMOHUNAJITNICOD "Pozor! Nemohu najt nsledujc soubor(y):\r\n\r\n%1\r\n\r\nChybjc soubory mohou zpsobit, e dobrodrustv nebude mon hrt." + IDS_EDITADVWARN "Pozor! Zmny v souboru ADV se neprojev ihned. Po uloen nechte znovu nast dobrodrustv pomoc funkce Soubor -> Znovu nast." + IDS_DLGNAME "Jmno" + IDS_DLGDESC "Popis" + IDS_DLGID "ID" + IDS_UNABLETOSAVEDIALOGYDLG + "Nemohu uloit soubor DIALOGY.DLG. Nastala njak chyba." + IDS_NODESC "" +END + +STRINGTABLE +BEGIN + AFX_IDS_APP_TITLE "AdvMan" + AFX_IDS_IDLEMESSAGE "Ready" +END + +STRINGTABLE +BEGIN + ID_INDICATOR_EXT "EXT" + ID_INDICATOR_CAPS "CAP" + ID_INDICATOR_NUM "NUM" + ID_INDICATOR_SCRL "SCRL" + ID_INDICATOR_OVR "OVR" + ID_INDICATOR_REC "REC" +END + +STRINGTABLE +BEGIN + ID_APP_ABOUT "Display program information, version number and copyright\nAbout" + ID_APP_EXIT "Quit the application; prompts to save documents\nExit" +END + +STRINGTABLE +BEGIN + ID_NEXT_PANE "Switch to the next window pane\nNext Pane" + ID_PREV_PANE "Switch back to the previous window pane\nPrevious Pane" +END + +STRINGTABLE +BEGIN + ID_WINDOW_SPLIT "Split the active window into panes\nSplit" +END + +STRINGTABLE +BEGIN + ID_EDIT_CLEAR "Erase the selection\nErase" + ID_EDIT_CLEAR_ALL "Erase everything\nErase All" + ID_EDIT_COPY "Copy the selection and put it on the Clipboard\nCopy" + ID_EDIT_CUT "Cut the selection and put it on the Clipboard\nCut" + ID_EDIT_FIND "Find the specified text\nFind" + ID_EDIT_PASTE "Insert Clipboard contents\nPaste" + ID_EDIT_REPEAT "Repeat the last action\nRepeat" + ID_EDIT_REPLACE "Replace specific text with different text\nReplace" + ID_EDIT_SELECT_ALL "Select the entire document\nSelect All" + ID_EDIT_UNDO "Undo the last action\nUndo" + ID_EDIT_REDO "Redo the previously undone action\nRedo" +END + +STRINGTABLE +BEGIN + ID_VIEW_TOOLBAR "Show or hide the toolbar\nToggle ToolBar" + ID_VIEW_STATUS_BAR "Show or hide the status bar\nToggle StatusBar" +END + +STRINGTABLE +BEGIN + AFX_IDS_SCSIZE "Change the window size" + AFX_IDS_SCMOVE "Change the window position" + AFX_IDS_SCMINIMIZE "Reduce the window to an icon" + AFX_IDS_SCMAXIMIZE "Enlarge the window to full size" + AFX_IDS_SCNEXTWINDOW "Switch to the next document window" + AFX_IDS_SCPREVWINDOW "Switch to the previous document window" + AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents" +END + +STRINGTABLE +BEGIN + AFX_IDS_SCRESTORE "Restore the window to normal size" + AFX_IDS_SCTASKLIST "Activate Task List" +END + +#endif // Czech resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOG 0, 0, 235, 55 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About AdvMan" +FONT 8, "MS Sans Serif" +BEGIN + ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20 + LTEXT "AdvMan Version 1.0",IDC_STATIC,40,10,119,8,SS_NOPREFIX + LTEXT "Copyright (C) 2005",IDC_STATIC,40,25,119,8 + DEFPUSHBUTTON "OK",IDOK,178,7,50,14,WS_GROUP +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_ABOUTBOX, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 228 + TOPMARGIN, 7 + BOTTOMMARGIN, 48 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDR_MAINFRAME ICON "res\\AdvMan.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_MAINFRAME ACCELERATORS +BEGIN + "C", ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT + "V", ID_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT + VK_BACK, ID_EDIT_UNDO, VIRTKEY, ALT, NOINVERT + VK_DELETE, ID_EDIT_CUT, VIRTKEY, SHIFT, NOINVERT + VK_F6, ID_NEXT_PANE, VIRTKEY, NOINVERT + VK_F6, ID_PREV_PANE, VIRTKEY, SHIFT, NOINVERT + VK_INSERT, ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT + VK_INSERT, ID_EDIT_PASTE, VIRTKEY, SHIFT, NOINVERT + "X", ID_EDIT_CUT, VIRTKEY, CONTROL, NOINVERT + "Z", ID_EDIT_UNDO, VIRTKEY, CONTROL, NOINVERT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "FileDescription", "AdvMan MFC Application" + VALUE "FileVersion", "1, 0, 0, 1" + VALUE "InternalName", "AdvMan" + VALUE "LegalCopyright", "Copyright (C) 2005" + VALUE "OriginalFilename", "AdvMan.EXE" + VALUE "ProductName", "AdvMan Application" + 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. +// +#define _AFX_NO_SPLITTER_RESOURCES +#define _AFX_NO_OLE_RESOURCES +#define _AFX_NO_TRACKER_RESOURCES +#define _AFX_NO_PROPERTY_RESOURCES + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE 9, 1 +#pragma code_page(1252) +#endif //_WIN32 +#include "res\AdvMan.rc2" // non-Microsoft Visual C++ edited resources +#include "afxres.rc" // Standard components +#endif + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/AdvMan/AdvMan.sln b/AdvMan/AdvMan.sln new file mode 100644 index 0000000..d4e56d1 --- /dev/null +++ b/AdvMan/AdvMan.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AdvMan", "AdvMan.vcproj", "{D38E31E6-CC5E-4C25-B966-85BF48E8C53E}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {D38E31E6-CC5E-4C25-B966-85BF48E8C53E}.Debug.ActiveCfg = Debug|Win32 + {D38E31E6-CC5E-4C25-B966-85BF48E8C53E}.Debug.Build.0 = Debug|Win32 + {D38E31E6-CC5E-4C25-B966-85BF48E8C53E}.Release.ActiveCfg = Release|Win32 + {D38E31E6-CC5E-4C25-B966-85BF48E8C53E}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/AdvMan/AdvMan.vcproj b/AdvMan/AdvMan.vcproj new file mode 100644 index 0000000..b3f0061 --- /dev/null +++ b/AdvMan/AdvMan.vcproj @@ -0,0 +1,525 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AdvMan/ChildView.cpp b/AdvMan/ChildView.cpp new file mode 100644 index 0000000..d4dc2da --- /dev/null +++ b/AdvMan/ChildView.cpp @@ -0,0 +1,57 @@ +// ChildView.cpp : implementation of the CChildView class +// + +#include "stdafx.h" +#include "AdvMan.h" +#include "ChildView.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CChildView + +CChildView::CChildView() +{ +} + +CChildView::~CChildView() +{ +} + + +BEGIN_MESSAGE_MAP(CChildView,CWnd ) + //{{AFX_MSG_MAP(CChildView) + ON_WM_PAINT() + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + + +///////////////////////////////////////////////////////////////////////////// +// CChildView message handlers + +BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) +{ + if (!CWnd::PreCreateWindow(cs)) + return FALSE; + + cs.dwExStyle |= WS_EX_CLIENTEDGE; + cs.style &= ~WS_BORDER; + cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, + ::LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW+1), NULL); + + return TRUE; +} + +void CChildView::OnPaint() +{ + CPaintDC dc(this); // device context for painting + + // TODO: Add your message handler code here + + // Do not call CWnd::OnPaint() for painting messages +} + diff --git a/AdvMan/ChildView.h b/AdvMan/ChildView.h new file mode 100644 index 0000000..1a31b1d --- /dev/null +++ b/AdvMan/ChildView.h @@ -0,0 +1,51 @@ +// ChildView.h : interface of the CChildView class +// +///////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_CHILDVIEW_H__C7E216F0_6DED_46F2_9E4F_0F71719D08CA__INCLUDED_) +#define AFX_CHILDVIEW_H__C7E216F0_6DED_46F2_9E4F_0F71719D08CA__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +///////////////////////////////////////////////////////////////////////////// +// CChildView window + +class CChildView : public CWnd +{ +// Construction +public: + CChildView(); + +// Attributes +public: + +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CChildView) + protected: + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + //}}AFX_VIRTUAL + +// Implementation +public: + virtual ~CChildView(); + + // Generated message map functions +protected: + //{{AFX_MSG(CChildView) + afx_msg void OnPaint(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_CHILDVIEW_H__C7E216F0_6DED_46F2_9E4F_0F71719D08CA__INCLUDED_) diff --git a/AdvMan/DlgDialogy.cpp b/AdvMan/DlgDialogy.cpp new file mode 100644 index 0000000..4ca4f96 --- /dev/null +++ b/AdvMan/DlgDialogy.cpp @@ -0,0 +1,264 @@ +// DlgDialogy.cpp : implementation file +// + +#include "stdafx.h" +#include "AdvMan.h" +#include "DlgDialogy.h" +#include "../cztable.h" +#include "MainFrm.h" +#include "DlgNovyDialog.h" +#include +#include ".\dlgdialogy.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// DlgDialogy dialog + + +DlgDialogy::DlgDialogy(CWnd* pParent /*=NULL*/) + : CDialog(DlgDialogy::IDD, pParent) +{ + //{{AFX_DATA_INIT(DlgDialogy) + // NOTE: the ClassWizard will add member initialization here + //}}AFX_DATA_INIT +} + + +void DlgDialogy::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(DlgDialogy) + DDX_Control(pDX, IDC_DLGLIST, wList); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(DlgDialogy, CDialog) + //{{AFX_MSG_MAP(DlgDialogy) + ON_BN_CLICKED(IDC_RESCAN, OnRescan) + ON_BN_CLICKED(IDC_DELETE, OnDelete) + ON_BN_CLICKED(IDC_EDIT, OnEdit) + ON_NOTIFY(LVN_COLUMNCLICK, IDC_DLGLIST, OnColumnclickDlglist) + ON_BN_CLICKED(IDC_ADD, OnAdd) + ON_NOTIFY(NM_DBLCLK, IDC_DLGLIST, OnNMDblclkDlglist) + //}}AFX_MSG_MAP + ON_NOTIFY(LVN_ENDLABELEDIT, IDC_DLGLIST, OnLvnEndlabeleditDlglist) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// DlgDialogy message handlers + +BOOL DlgDialogy::OnInitDialog() +{ + CDialog::OnInitDialog(); + + wList.InsertColumn(0,CString(MAKEINTRESOURCE(IDS_DLGDESC)),LVCFMT_LEFT,200,0); + wList.InsertColumn(1,CString(MAKEINTRESOURCE(IDS_DLGNAME)),LVCFMT_LEFT,100,1); + wList.InsertColumn(2,CString(MAKEINTRESOURCE(IDS_DLGID)),LVCFMT_CENTER,30,2); + ListView_SetExtendedListViewStyleEx(wList,LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES,LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES); + OnRescan(); + + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +int DlgDialogy::GetDialogID(const char *name) +{ + Pathname dialogPath=_dlgpath; + dialogPath.SetFilename(name); + FILE *f=fopen(dialogPath,"r"); + if (f==0) return -1; + int id; + char dialog[40]; + if (fscanf(f," %40[^\r\n\t (] ( %d )",dialog,&id)==2) + { + if (stricmp(dialog,"DIALOG")==0) + { + fclose(f); + return id; + } + } + fclose(f); + return -1; +} + +void DlgDialogy::LoadDialogyDlg() +{ + FILE *f=fopen(_dlgpath,"r"); + if (f==0) return; + + int p=0; + + while (!feof(f)) + { + char name[80]; + char desc[256]; + name[0]=0; + desc[0]=0; + fscanf(f,"%80s",name); + fscanf(f," %250[^\r\n]",desc); + kamenik2windows(name,strlen(name),name); + kamenik2windows(desc,strlen(desc),desc); + int row; + + if (name[0]!=0 || desc[0]!=0) + { + row=wList.InsertItem(p,desc,0); + wList.SetItemText(row,1,name); + int dlgId=GetDialogID(name); + wList.SetItemText(row,2,itoa(dlgId,desc,10)); + p++; + } + } + fclose(f); +} + +void DlgDialogy::OnRescan() +{ + wList.DeleteAllItems(); + LoadDialogyDlg(); +} + +void DlgDialogy::OnDelete() +{ + int w; + while ((w=wList.GetNextItem(-1,LVNI_SELECTED))!=-1) + { + wList.DeleteItem(w); + } +} + +void DlgDialogy::OnEdit() +{ + CString name; + int w=-1; + while ((w=wList.GetNextItem(w,LVNI_SELECTED))!=-1) + { + name=wList.GetItemText(w,1); + Pathname editName=_dlgpath; + editName.SetFilename(name); + _mainFrame->OpenEditor(editName); + } +} + +void DlgDialogy::OnOK() +{ + FILE *f=fopen(_dlgpath,"w"); + if (f==0) + { + AfxMessageBox(IDS_UNABLETOSAVEDIALOGYDLG,MB_ICONEXCLAMATION); + return; + } + + for (int i=0,cnt=wList.GetItemCount();iiSubItem; + wList.SortItems(CompareFunc,(DWORD)this); + + *pResult = 0; +} + + +int DlgDialogy::CompareItems(int item1, int item2) +{ + switch (_sortItem) + { + case 0: + { + CString a=wList.GetItemText(item1,0); + CString b=wList.GetItemText(item2,0); + return stricmp(a,b); + } + case 1: + { + CString a=wList.GetItemText(item1,1); + CString b=wList.GetItemText(item2,1); + return stricmp(a,b); + } + case 2: + { + char buff[20]; + int a,b; + wList.GetItemText(item1,2,buff,20);a=atoi(buff); + wList.GetItemText(item2,2,buff,20);b=atoi(buff); + return (a>b)-(a_dlgpath; + nw.sourceLst=&wList; + if (nw.DoModal()==IDOK) + { + int p=wList.InsertItem(wList.GetItemCount(),nw.vPopis); + Pathname dlgName=_dlgpath; + dlgName.SetFiletitle(nw.vJmeno); + dlgName.SetExtension(".dlg"); + wList.SetItemText(p,1,dlgName.GetFilename()); + if (_access(dlgName,0)!=0) + { + FILE *f=fopen(dlgName,"w"); + fprintf(f,"DIALOG(%d)\n",nw.vCislo); + fprintf(f,"{\nPICTURE (\"SCREEN\")\nDESC (\"Popis\")\nSTANDARD (1)\n}\n\nSENTENCE (1,0)\n{\n\n}"); + fclose(f); + } + int num=GetDialogID(dlgName.GetFilename()); + char buff[20]; + wList.SetItemText(p,2,itoa(num,buff,10)); + } +} + + +void DlgDialogy::OnNMDblclkDlglist(NMHDR *pNMHDR, LRESULT *pResult) +{ + OnEdit(); + *pResult = 0; +} + +void DlgDialogy::OnLvnEndlabeleditDlglist(NMHDR *pNMHDR, LRESULT *pResult) +{ + NMLVDISPINFO *pDispInfo = reinterpret_cast(pNMHDR); + // TODO: Add your control notification handler code here + *pResult = 1; +} diff --git a/AdvMan/DlgDialogy.h b/AdvMan/DlgDialogy.h new file mode 100644 index 0000000..10efb2d --- /dev/null +++ b/AdvMan/DlgDialogy.h @@ -0,0 +1,76 @@ +#if !defined(AFX_DLGDIALOGY_H__E47269D5_6849_42F5_AF6F_32EEEE32104D__INCLUDED_) +#define AFX_DLGDIALOGY_H__E47269D5_6849_42F5_AF6F_32EEEE32104D__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// DlgDialogy.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// DlgDialogy dialog + +#define MAXDIALOGY 240 + +class CMainFrame; + +class DlgDialogy : public CDialog +{ +// Construction +public: + void LoadDialogyDlg(); + DlgDialogy(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(DlgDialogy) + enum { IDD = IDD_DIALOGY }; + CListCtrl wList; + //}}AFX_DATA + + Pathname _dlgpath; + CMainFrame *_mainFrame; + int _sortItem; + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(DlgDialogy) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(DlgDialogy) + virtual BOOL OnInitDialog(); + afx_msg void OnRescan(); + afx_msg void OnDelete(); + afx_msg void OnEdit(); + virtual void OnOK(); + virtual void OnCancel(); + afx_msg void OnColumnclickDlglist(NMHDR* pNMHDR, LRESULT* pResult); + afx_msg void OnAdd(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() + + int GetDialogID(const char *name); + static int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort) + { + DlgDialogy *self=(DlgDialogy *)lParamSort; + return self->CompareItems(lParam1,lParam2); + } + + int CompareItems(int item1, int item2); + + +public: + afx_msg void OnNMDblclkDlglist(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnLvnEndlabeleditDlglist(NMHDR *pNMHDR, LRESULT *pResult); +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_DLGDIALOGY_H__E47269D5_6849_42F5_AF6F_32EEEE32104D__INCLUDED_) diff --git a/AdvMan/DlgNoveDobr.cpp b/AdvMan/DlgNoveDobr.cpp new file mode 100644 index 0000000..9c30222 --- /dev/null +++ b/AdvMan/DlgNoveDobr.cpp @@ -0,0 +1,83 @@ +// DlgNoveDobr.cpp : implementation file +// + +#include "stdafx.h" +#include "AdvMan.h" +#include "DlgNoveDobr.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// DlgNoveDobr dialog + + +DlgNoveDobr::DlgNoveDobr(CWnd* pParent /*=NULL*/) + : CDialog(DlgNoveDobr::IDD, pParent) +{ + //{{AFX_DATA_INIT(DlgNoveDobr) + vJmeno = _T(""); + vKouzla = TRUE; + vMapy = FALSE; + vDialogy = TRUE; + vDefinice = FALSE; + vOrganizace = 0; + vStartMap = _T("start.map"); + vMaxPostav = 3; + vMinPostav = 3; + //}}AFX_DATA_INIT +} + + +void DlgNoveDobr::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(DlgNoveDobr) + DDX_Text(pDX, IDC_JMENO, vJmeno); + DDX_Check(pDX, IDC_KOUZLA, vKouzla); + DDX_Check(pDX, IDC_MAPY, vMapy); + DDX_Check(pDX, IDC_DIALOGY, vDialogy); + DDX_Check(pDX, IDC_DEFINICE, vDefinice); + DDX_Radio(pDX, IDC_ORGANIZACE, vOrganizace); + DDX_Text(pDX, IDC_STARTMAP, vStartMap); + DDX_Check(pDX, IDC_ORIGDLGS, vDialogyDlg); + DDV_MaxChars(pDX, vStartMap, 12); + //}}AFX_DATA_MAP + DDX_Text(pDX, IDC_MINPOSTAV, vMinPostav); + DDV_MinMaxUInt(pDX, vMinPostav, 1, 6); + DDX_Text(pDX, IDC_MAXPOSTAV, vMaxPostav); + DDV_MinMaxUInt(pDX, vMaxPostav, vMinPostav, 6); +} + + +BEGIN_MESSAGE_MAP(DlgNoveDobr, CDialog) + //{{AFX_MSG_MAP(DlgNoveDobr) + ON_EN_CHANGE(IDC_JMENO, OnChangeJmeno) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// DlgNoveDobr message handlers + +void DlgNoveDobr::DialogRules() +{ + GetDlgItem(IDOK)->EnableWindow(GetDlgItem(IDC_JMENO)->GetWindowTextLength()); +} + +BOOL DlgNoveDobr::OnInitDialog() +{ + CDialog::OnInitDialog(); + + DialogRules(); + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +void DlgNoveDobr::OnChangeJmeno() +{ + DialogRules(); +} diff --git a/AdvMan/DlgNoveDobr.h b/AdvMan/DlgNoveDobr.h new file mode 100644 index 0000000..a3db1f4 --- /dev/null +++ b/AdvMan/DlgNoveDobr.h @@ -0,0 +1,57 @@ +#if !defined(AFX_DLGNOVEDOBR_H__410472E5_5BCF_4CE8_8FE3_10693C0F05F7__INCLUDED_) +#define AFX_DLGNOVEDOBR_H__410472E5_5BCF_4CE8_8FE3_10693C0F05F7__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// DlgNoveDobr.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// DlgNoveDobr dialog + +class DlgNoveDobr : public CDialog +{ +// Construction +public: + void DialogRules(); + DlgNoveDobr(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(DlgNoveDobr) + enum { IDD = IDD_NOVEDOBR }; + CString vJmeno; + BOOL vKouzla; + BOOL vMapy; + BOOL vDialogy; + BOOL vDefinice; + BOOL vDialogyDlg; + int vOrganizace; + CString vStartMap; + UINT vMaxPostav; + UINT vMinPostav; + //}}AFX_DATA + + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(DlgNoveDobr) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(DlgNoveDobr) + virtual BOOL OnInitDialog(); + afx_msg void OnChangeJmeno(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_DLGNOVEDOBR_H__410472E5_5BCF_4CE8_8FE3_10693C0F05F7__INCLUDED_) diff --git a/AdvMan/DlgNovyDialog.cpp b/AdvMan/DlgNovyDialog.cpp new file mode 100644 index 0000000..67f9b44 --- /dev/null +++ b/AdvMan/DlgNovyDialog.cpp @@ -0,0 +1,127 @@ +// DlgNovyDialog.cpp : implementation file +// + +#include "stdafx.h" +#include "AdvMan.h" +#include "DlgNovyDialog.h" +#include + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// DlgNovyDialog dialog + + +DlgNovyDialog::DlgNovyDialog(CWnd* pParent /*=NULL*/) + : CDialog(DlgNovyDialog::IDD, pParent) +{ + //{{AFX_DATA_INIT(DlgNovyDialog) + vCislo = 0; + vJmeno = _T(""); + vPopis = _T(""); + //}}AFX_DATA_INIT +} + + +void DlgNovyDialog::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(DlgNovyDialog) + DDX_Control(pDX, IDC_CISLO, wCislo); + DDX_Control(pDX, IDC_JMENO, wJmeno); + DDX_Text(pDX, IDC_CISLO, vCislo); + DDV_MinMaxInt(pDX, vCislo, 1, 254); + DDX_CBString(pDX, IDC_JMENO, vJmeno); + DDV_MaxChars(pDX, vJmeno, 8); + DDX_Text(pDX, IDC_POPIS, vPopis); + DDV_MaxChars(pDX, vPopis, 50); + //}}AFX_DATA_MAP +} + + +BEGIN_MESSAGE_MAP(DlgNovyDialog, CDialog) + //{{AFX_MSG_MAP(DlgNovyDialog) + ON_CBN_EDITCHANGE(IDC_JMENO, OnEditchangeJmeno) + ON_CBN_SELENDOK(IDC_JMENO, OnSelendokJmeno) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// DlgNovyDialog message handlers + +BOOL DlgNovyDialog::OnInitDialog() +{ + CDialog::OnInitDialog(); + + bool idlist[256]; + memset(idlist,0,sizeof(idlist)); + + dlgSource.SetFilename("*.dlg"); + CFileFind fnd; + BOOL next; + if (fnd.FindFile(dlgSource)) do + { + next=fnd.FindNextFile(); + CString name=fnd.GetFileTitle(); + name.MakeLower(); + wJmeno.AddString(name); + }while (next); + + int i,cnt; + for (i=0,cnt=sourceLst->GetItemCount();iGetItemText(i,1); + dlgSource.SetFilename(name); + name=dlgSource.GetTitle(); + name.MakeLower(); + int p=wJmeno.FindStringExact(-1,name); + if (p!=-1) wJmeno.DeleteString(p); + + name=sourceLst->GetItemText(i,2); + p=atoi(name); + if (p>=0 && p<256) idlist[p]=true; + } + bool x=true; + for (i=1;i<254;i++) if (!idlist[i]) + { + char buff[50]; + sprintf(buff,"%3d",i); + wCislo.AddString(buff); + if (x) + { + wCislo.SetWindowText(buff); + x=false; + } + } + + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} + +void DlgNovyDialog::DialogRules() +{ + BOOL ok=wJmeno.GetWindowTextLength() && wCislo.GetWindowTextLength(); + GetDlgItem(IDOK)->EnableWindow(ok); + CString name; + wJmeno.GetWindowText(name); + dlgSource.SetFiletitle(name); + wCislo.EnableWindow(access(dlgSource,0)==-1); +} + +void DlgNovyDialog::OnEditchangeJmeno() +{ + DialogRules(); +} + +void DlgNovyDialog::OnSelendokJmeno() +{ + int p=wJmeno.GetCurSel(); + CString z; + wJmeno.GetLBText(p,z); + wJmeno.SetWindowText(z); + DialogRules(); +} diff --git a/AdvMan/DlgNovyDialog.h b/AdvMan/DlgNovyDialog.h new file mode 100644 index 0000000..526175a --- /dev/null +++ b/AdvMan/DlgNovyDialog.h @@ -0,0 +1,57 @@ +#if !defined(AFX_DLGNOVYDIALOG_H__00136ADF_E2C6_4081_83AB_D5110EE43612__INCLUDED_) +#define AFX_DLGNOVYDIALOG_H__00136ADF_E2C6_4081_83AB_D5110EE43612__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +// DlgNovyDialog.h : header file +// + +///////////////////////////////////////////////////////////////////////////// +// DlgNovyDialog dialog + +class DlgDialogy; + +class DlgNovyDialog : public CDialog +{ +// Construction +public: + void DialogRules(); + DlgNovyDialog(CWnd* pParent = NULL); // standard constructor + +// Dialog Data + //{{AFX_DATA(DlgNovyDialog) + enum { IDD = IDD_NOVYDIALOG }; + CComboBox wCislo; + CComboBox wJmeno; + int vCislo; + CString vJmeno; + CString vPopis; + //}}AFX_DATA + + CListCtrl *sourceLst; + Pathname dlgSource; + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(DlgNovyDialog) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + + // Generated message map functions + //{{AFX_MSG(DlgNovyDialog) + virtual BOOL OnInitDialog(); + afx_msg void OnEditchangeJmeno(); + afx_msg void OnSelendokJmeno(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_DLGNOVYDIALOG_H__00136ADF_E2C6_4081_83AB_D5110EE43612__INCLUDED_) diff --git a/AdvMan/FCS_tasker.h b/AdvMan/FCS_tasker.h new file mode 100644 index 0000000..e69de29 diff --git a/AdvMan/FS_tasker.h b/AdvMan/FS_tasker.h new file mode 100644 index 0000000..e69de29 diff --git a/AdvMan/MainFrm.cpp b/AdvMan/MainFrm.cpp new file mode 100644 index 0000000..9cdacb8 --- /dev/null +++ b/AdvMan/MainFrm.cpp @@ -0,0 +1,677 @@ +// MainFrm.cpp : implementation of the CMainFrame class +// + +#include "stdafx.h" +#include "AdvMan.h" +#include "..\cztable.h" + +#include "MainFrm.h" +#include "DlgDialogy.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame + +IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd) + +BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) + //{{AFX_MSG_MAP(CMainFrame) + ON_WM_CREATE() + ON_WM_SETFOCUS() + ON_WM_INITMENUPOPUP() + ON_COMMAND(ID_FILE_NOVDOBRODRUST, OnFileNovdobrodrust) + ON_COMMAND(ID_FILE_NATIDOBRODRUSTV, OnFileNatidobrodrustv) + ON_COMMAND(ID_EDITORY_KOUZLATAB, OnEditoryKouzlatab) + ON_COMMAND(ID_EDITORY_POSTAVYTAB, OnEditoryPostavytab) + ON_COMMAND(ID_EDITORY_ITEMSSCR, OnEditoryItemsscr) + ON_COMMAND(ID_EDITORY_ITEMSPIC, OnEditoryItemspic) + ON_COMMAND(ID_EDITORY_WEAPONSSCR, OnEditoryWeaponsscr) + ON_WM_DESTROY() + ON_COMMAND(ID_PEKLADAE_PELOKOUZLA, OnPekladaePelokouzla) + ON_COMMAND(ID_PEKLADAE_PELODIALOGY, OnPekladaePelodialogy) + ON_COMMAND(ID_PEKLADAE_PELOPOSTAVYTAB, OnPekladaePelopostavytab) + ON_COMMAND(ID_NSTROJE_MAPEDIT, OnNstrojeMapedit) + ON_COMMAND(ID_NSTROJE_TESTUJDOBRODRUSTV, OnNstrojeTestujdobrodrustv) + ON_COMMAND(ID_NSTROJE_TVRCEPODLAH, OnNstrojeTvrcepodlah) + ON_COMMAND(ID_NSTROJE_TVRCEPALETPRONESTVRY, OnNstrojeTvrcepaletpronestvry) + ON_COMMAND(ID_NSTROJE_TVRCEIKONPROPEDMTY, OnNstrojeTvrceikonpropedmty) + ON_COMMAND(ID_EDITORY_SOUBORADV, OnEditorySouboradv) + ON_COMMAND(ID_FILE_ZNOVUNAST, OnFileZnovunast) + ON_UPDATE_COMMAND_UI(ID_FILE_ZNOVUNAST, OnUpdateFileZnovunast) + ON_COMMAND(ID_EDITORY_DIALOGY, OnEditoryDialogy) + ON_COMMAND_EX(ID_VIEW_EDITORY,OnBarCheck) + ON_COMMAND_EX(ID_VIEW_PREKLADACE,OnBarCheck) + ON_UPDATE_COMMAND_UI(ID_VIEW_EDITORY,OnUpdateControlBarMenu) + ON_UPDATE_COMMAND_UI(ID_VIEW_PREKLADACE,OnUpdateControlBarMenu) + ON_UPDATE_COMMAND_UI_RANGE(ID_EDITORY_KOUZLATAB,ID_EDITORY_WEAPONSSCR,OnUpdateEditory) + ON_UPDATE_COMMAND_UI_RANGE(ID_PEKLADAE_PELOKOUZLA,ID_PEKLADAE_PELOPOSTAVYTAB,OnUpdateEditory) + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +static UINT indicators[] = +{ + ID_SEPARATOR, // status line indicator + ID_INDICATOR_CAPS, + ID_INDICATOR_NUM, + ID_INDICATOR_SCRL, +}; + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame construction/destruction + +CMainFrame::CMainFrame() +{ + // TODO: add member initialization code here + +} + +CMainFrame::~CMainFrame() +{ + +} + +int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) +{ + if (CFrameWnd::OnCreate(lpCreateStruct) == -1) + return -1; + // create a view to occupy the client area of the frame + if (!m_wndView.Create(ES_READONLY|WS_VISIBLE|WS_CHILD|ES_MULTILINE|ES_AUTOVSCROLL|ES_AUTOHSCROLL|WS_VSCROLL|WS_HSCROLL,CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST)) + { + TRACE0("Failed to create view window\n"); + return -1; + } + + if (!m_wndToolBar.CreateEx(this, TBSTYLE_BUTTON, WS_CHILD | WS_VISIBLE | CBRS_TOP + | CBRS_TOOLTIPS | CBRS_FLYBY |BTNS_AUTOSIZE | CBRS_SIZE_DYNAMIC) || + !m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) + { + TRACE0("Failed to create toolbar\n"); + return -1; // fail to create + } + + if (!m_wndEditoryBar.CreateEx(this, TBSTYLE_BUTTON, WS_CHILD | WS_VISIBLE | CBRS_TOP + | CBRS_TOOLTIPS | CBRS_FLYBY |BTNS_AUTOSIZE | CBRS_SIZE_DYNAMIC,CRect(0,0,0,0),ID_VIEW_EDITORY) || + !m_wndEditoryBar.LoadToolBar(IDR_TOOLEDITORY)) + { + TRACE0("Failed to create toolbar\n"); + return -1; // fail to create + } + + if (!m_wndPrekladaceBar.CreateEx(this, TBSTYLE_BUTTON, WS_CHILD | WS_VISIBLE | CBRS_TOP + | CBRS_TOOLTIPS | CBRS_FLYBY |BTNS_AUTOSIZE | CBRS_SIZE_DYNAMIC,CRect(0,0,0,0),ID_VIEW_PREKLADACE) || + !m_wndPrekladaceBar.LoadToolBar(IDR_PREKLADACE)) + { + TRACE0("Failed to create toolbar\n"); + return -1; // fail to create + } + + if (!m_wndStatusBar.Create(this) || + !m_wndStatusBar.SetIndicators(indicators, + sizeof(indicators)/sizeof(UINT))) + { + TRACE0("Failed to create status bar\n"); + return -1; // fail to create + } + + // TODO: Delete these three lines if you don't want the toolbar to + // be dockable + ShowWindow(SW_SHOW); + m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY); + m_wndEditoryBar.EnableDocking(CBRS_ALIGN_ANY); + m_wndPrekladaceBar.EnableDocking(CBRS_ALIGN_ANY); + EnableDocking(CBRS_ALIGN_ANY); + DockControlBar(&m_wndToolBar); + DockControlBar(&m_wndEditoryBar); + DockControlBar(&m_wndPrekladaceBar); + UpdateWindow(); + CRect rc; + GetClientRect(&rc); + ClientToScreen(&rc); + DockControlBar(&m_wndEditoryBar,(UINT)0,CRect(rc.left+180,rc.top+5,rc.left+180,rc.top+5)); + DockControlBar(&m_wndPrekladaceBar,(UINT)0,CRect(rc.left+350,rc.top+5,rc.left+350,rc.top+5)); + + _adv=0; + CString untitled; + untitled.LoadString(IDS_UNTITLED); + SetTitle(untitled); + + SetClassLong(*this,GCL_HICON,(LONG)(theApp.LoadIcon(IDR_MAINFRAME))); + + return 0; +} + +BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) +{ + if( !CFrameWnd::PreCreateWindow(cs) ) + return FALSE; + // TODO: Modify the Window class or styles here by modifying + // the CREATESTRUCT cs + + cs.dwExStyle &= ~WS_EX_CLIENTEDGE; + cs.lpszClass = AfxRegisterWndClass(0); + return TRUE; +} + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame diagnostics + +#ifdef _DEBUG +void CMainFrame::AssertValid() const +{ + CFrameWnd::AssertValid(); +} + +void CMainFrame::Dump(CDumpContext& dc) const +{ + CFrameWnd::Dump(dc); +} + +#endif //_DEBUG + +///////////////////////////////////////////////////////////////////////////// +// CMainFrame message handlers +void CMainFrame::OnSetFocus(CWnd* pOldWnd) +{ + // forward focus to the view window + m_wndView.SetFocus(); +} + +BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) +{ + // let the view have first crack at the command + if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)) + return TRUE; + + // otherwise, do default handling + return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); +} + + +void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu) +{ + if (_adv==0) + { + for (int i=0,cnt=pPopupMenu->GetMenuItemCount();iGetMenuItemID(i); + if (id!=ID_FILE_NOVDOBRODRUST && id!=ID_FILE_NATIDOBRODRUSTV && id!=ID_APP_EXIT && + id!=ID_VIEW_TOOLBAR && id!=ID_VIEW_STATUS_BAR && id!=ID_APP_ABOUT && id!=ID_VIEW_EDITORY) + pPopupMenu->EnableMenuItem(i,MF_GRAYED|MF_BYPOSITION); + } + } + else + CFrameWnd::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu); +} + +#include "DlgNoveDobr.h" + +static str_add_wildcard(TSTR_LIST *lst, const char *mask) +{ + CFileFind fnd; + BOOL nxt=fnd.FindFile(mask); + if (nxt==FALSE) + { + CString msg; + AfxFormatString1(msg,IDS_NEMOHUNAJITNICOD,mask); + AfxMessageBox(msg,MB_ICONEXCLAMATION); + } + while (nxt) + { + nxt=fnd.FindNextFile(); + str_add(lst,fnd.GetFilePath()); + } +} + +void CMainFrame::OnFileNovdobrodrust() +{ + DlgNoveDobr dlg; + int id=dlg.DoModal(); + if (id==IDOK) + { + release_list(_adv); + _adv=create_list(10); + CString baseMap=_T("adv\\")+dlg.vJmeno+_T("\\"); + add_field_txt(&_adv,_T("CESTA_MAPY"),baseMap); + CString cestaGrafika; + CString cestaDialogy; + CString cestaEnemy; + CString cestaItemy; + CString cestaPozice; + CString cestaZvuky; + CString cestaBasicGr; + switch (dlg.vOrganizace) + { + case 0: + cestaGrafika=baseMap+_T("GRFSTENY\\"); + cestaDialogy=baseMap+_T("GRFDIALG\\"); + cestaEnemy=baseMap+_T("GRFENEMY\\"); + cestaItemy=baseMap+_T("GRFITEMS\\"); + cestaPozice=baseMap+_T("SAVEGAME\\"); + cestaZvuky=baseMap+_T("SOUNDS\\"); + cestaBasicGr=baseMap+_T("GRFBASIC\\"); + break; + case 1: + cestaGrafika=baseMap+_T("graphics\\"); + cestaDialogy=baseMap+_T("graphics\\dialogs\\"); + cestaEnemy=baseMap+_T("graphics\\enemies\\"); + cestaItemy=baseMap+_T("graphics\\items\\"); + cestaPozice=baseMap+_T("SAVEGAME\\"); + cestaZvuky=baseMap+_T("SAMPLES\\"); + cestaBasicGr=baseMap+_T("graphics\\basic\\"); + break; + case 2: + cestaGrafika=baseMap; + cestaDialogy=baseMap; + cestaEnemy=baseMap; + cestaItemy=baseMap; + cestaPozice=baseMap+_T("SAVEGAME\\"); + cestaZvuky=baseMap; + cestaBasicGr=baseMap; + break; + } + + add_field_txt(&_adv,_T("CESTA_GRAFIKA"),cestaGrafika); + add_field_txt(&_adv,_T("CESTA_DIALOGY"),cestaDialogy); + add_field_txt(&_adv,_T("CESTA_ENEMY"),cestaEnemy); + add_field_txt(&_adv,_T("CESTA_ITEMY"),cestaItemy); + add_field_txt(&_adv,_T("CESTA_POZICE"),cestaPozice); + add_field_txt(&_adv,_T("CESTA_ZVUKY"),cestaZvuky); + add_field_txt(&_adv,_T("CESTA_BGRAFIKA"),cestaBasicGr); + + add_field_txt(&_adv,_T("DEFAULT_MAP"),dlg.vStartMap); + add_field_num(&_adv,_T("CHAR_MIN"),dlg.vMinPostav); + add_field_num(&_adv,_T("CHAR_MAX"),dlg.vMaxPostav); + add_field_num(&_adv,_T("PATCH"),1); + + Pathname pth=Pathname::GetExePath(); + pth.SetFiletitle(dlg.vJmeno); + pth.SetExtension(_T(".adv")); + + save_config(_adv,pth); + + _advName=pth; + _advPath=pth.GetDirectoryWithDrive(); + + SetTitle(pth); + + + Pathname exePath=Pathname::GetExePath(); + + pth.CreateFolder(exePath.GetDirectoryWithDrive()+baseMap); + pth.CreateFolder(exePath.GetDirectoryWithDrive()+cestaGrafika); + pth.CreateFolder(exePath.GetDirectoryWithDrive()+cestaDialogy); + pth.CreateFolder(exePath.GetDirectoryWithDrive()+cestaItemy); + pth.CreateFolder(exePath.GetDirectoryWithDrive()+cestaEnemy); + pth.CreateFolder(exePath.GetDirectoryWithDrive()+cestaPozice); + pth.CreateFolder(exePath.GetDirectoryWithDrive()+cestaZvuky); + pth.CreateFolder(exePath.GetDirectoryWithDrive()+cestaBasicGr); + + CString basePath=pth.GetDirectoryWithDrive(); + + TSTR_LIST fileList=create_list(10); + str_add_wildcard(&fileList,basePath+_T("maps\\*.dat")); + if (!dlg.vDefinice) str_add_wildcard(&fileList,basePath+_T("AdvManData\\weapons.scr")); + if (!dlg.vDefinice) str_add_wildcard(&fileList,basePath+_T("AdvManData\\items.scr")); + str_add_wildcard(&fileList,basePath+_T("AdvManData\\items.pic")); + str_add_wildcard(&fileList,basePath+_T("AdvManData\\*.lst")); + str_add_wildcard(&fileList,basePath+_T("AdvManData\\postavy.def")); + str_add_wildcard(&fileList,basePath+_T("AdvManData\\postavy.tab")); + str_add_wildcard(&fileList,basePath+_T("AdvManData\\predmety.tab")); + if (dlg.vKouzla) + { + str_add_wildcard(&fileList,basePath+_T("AdvManData\\kouzla.def")); + str_add_wildcard(&fileList,basePath+_T("AdvManData\\kouzla.tab")); + } + if (dlg.vDialogy) + { + str_add_wildcard(&fileList,basePath+_T("AdvManData\\dialogy.def")); + str_add_wildcard(&fileList,basePath+_T("AdvManData\\dlgsecrt.def")); + } + if (dlg.vDefinice) + { + str_add_wildcard(&fileList,basePath+_T("AdvManData\\*.scr")); + str_add_wildcard(&fileList,basePath+_T("AdvManData\\*.txt")); + } + if (dlg.vMapy) + { + str_add_wildcard(&fileList,basePath+_T("maps\\*.map")); + } + if (dlg.vDialogyDlg) + { + str_add_wildcard(&fileList,basePath+_T("AdvManData\\*.dlg")); + } + int totalszneed=0; + int i,cnt; + for (i=0,cnt=str_count(fileList);imessage,pMsg->wParam,pMsg->lParam); + pMsg->time=res; + return res==0; +} + + +LRESULT CMainFrame::BroadcastMessage(UINT msg, WPARAM wParam, LPARAM lParam) +{ + MSG Msg; + Msg.message=msg; + Msg.wParam=wParam; + Msg.lParam=lParam; + Msg.time=0; + EnumThreadWindows(GetCurrentThreadId(),BroadcastMsgCallback,(LPARAM)&Msg); + return Msg.time; +} + +void CMainFrame::SaveAll() +{ + BroadcastMessage(MSG_FORCESAVE,0,0); +} + +void CMainFrame::OpenEditor(const char *name) +{ + if (BroadcastMessage(MSG_FINDANDPOPUP,0,(LPARAM)name)==0) + { + EditSkeldalFile(name); + } +} + +void CMainFrame::OnDestroy() +{ + SaveBarState("MainFrame"); + CFrameWnd::OnDestroy(); + + BroadcastMessage(MSG_CLOSEEDITOR,0,0); + release_list(_adv); + _adv=0; + + +} + +void CMainFrame::StartApp(const char *appname, CString cmdline, bool wait, const char *folder) +{ + SaveAll(); + STARTUPINFO nfo; + memset(&nfo,0,sizeof(nfo)); + nfo.cb=sizeof(nfo); + HANDLE pipe; + if (wait) + { + HANDLE output; + CreatePipe(&pipe,&output,0,0); + DuplicateHandle(GetCurrentProcess(),output,GetCurrentProcess(),&output,0,TRUE,DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE); + nfo.hStdOutput=output; + nfo.hStdError=output; + nfo.dwFlags|=STARTF_USESTDHANDLES; + m_wndView.SetWindowText(""); + } + Pathname app=appname; + cmdline=_T("\"")+CString(appname)+_T("\" ")+cmdline; + CString startdir; + PROCESS_INFORMATION pi; + if (folder==0) + startdir=app.GetDirectoryWithDrive(); + else + startdir=folder; + if (startdir[startdir.GetLength()-1]=='\\') startdir.Delete(startdir.GetLength()-1); + BOOL res=CreateProcess(appname,cmdline.LockBuffer(),0,0,TRUE,NORMAL_PRIORITY_CLASS|DETACHED_PROCESS,0,startdir,&nfo,&pi); + cmdline.UnlockBuffer(); + if (res==FALSE) + { + CString ss; + AfxFormatString1(ss,IDS_CANNOTEXECUTE,cmdline); + AfxMessageBox(ss,MB_ICONSTOP); + } + else + { + CloseHandle(pi.hThread); + if (wait) + { + int rep=10; + bool end; + do + { + DWORD datalen; + PeekNamedPipe(pipe,0,0,0,&datalen,0); + while (datalen) + { + DWORD readed=0; + char buff[256]; + if (ReadFile(pipe,&buff,255,&readed,0)==FALSE) break; + if (readed==0) break; + int cnt=m_wndView.GetWindowTextLength(); + if (cnt>20000) + { + m_wndView.SetSel(0,10000); + m_wndView.ReplaceSel(""); + cnt=m_wndView.GetWindowTextLength(); + } + buff[readed]=0; + kamenik2windows(buff,readed,buff); + m_wndView.SetSel(cnt,cnt); + m_wndView.ReplaceSel(buff); + PeekNamedPipe(pipe,0,0,0,&datalen,0); + rep=10; + } + UpdateWindow(); + end=WaitForSingleObject(pi.hProcess,200)==WAIT_TIMEOUT; + rep--; + } + while (rep>0 || end); + } + CloseHandle(pi.hProcess); + } + if (wait) + { + CloseHandle(pipe); + CloseHandle(nfo.hStdOutput); + } + SetForegroundWindow(); +} + +void CMainFrame::OnPekladaePelokouzla() +{ + CString cmdline=_T("\"")+_baseMapPath+_T("KOUZLA.TAB")+_T("\""); + Pathname apppath=Pathname::GetExePath(); + CString appname=apppath.GetDirectoryWithDrive()+CString(_T("AdvManData\\CSPELLS.EXE")); + StartApp(appname,cmdline,true,_baseMapPath); +} + +void CMainFrame::OnPekladaePelodialogy() +{ + CString cmdline=_T("\"")+_baseMapPath+_T("DIALOGY.DLG")+_T("\""); + Pathname apppath=Pathname::GetExePath(); + CString appname=apppath.GetDirectoryWithDrive()+CString(_T("AdvManData\\CDIALOGY.EXE")); + StartApp(appname,cmdline,true,_baseMapPath); + +} + +void CMainFrame::OnPekladaePelopostavytab() +{ + CString cmdline=_T("\"")+_baseMapPath+_T("POSTAVY.TAB\" \"")+_baseMapPath+_T("POSTAVY.DAT")+_T("\""); + Pathname apppath=Pathname::GetExePath(); + CString appname=apppath.GetDirectoryWithDrive()+CString(_T("AdvManData\\Lex_Lib.exe")); + StartApp(appname,cmdline,true,_baseMapPath); + +} + +void CMainFrame::OnNstrojeMapedit() +{ + Pathname apppath=Pathname::GetExePath(); + apppath.SetFilename(_T("MapEdit.exe")); + StartApp(apppath,CString(_T("\""))+_advName+_T("\""),false); +} + +void CMainFrame::OnNstrojeTestujdobrodrustv() +{ + Pathname apppath=Pathname::GetExePath(); + apppath.SetFilename(_T("Skeldal.exe")); + StartApp(apppath,CString(_T("\""))+_advName+_T("\""),false); +} + +void CMainFrame::OnNstrojeTvrcepodlah() +{ + Pathname apppath=Pathname::GetExePath(); + apppath.SetFilename(_T("AdvManData\\Podlahar.exe")); + StartApp(apppath,"",false,_advPath+get_text_field(_adv,"CESTA_GRAFIKA")); + +} + +void CMainFrame::OnNstrojeTvrcepaletpronestvry() +{ + Pathname apppath=Pathname::GetExePath(); + apppath.SetFilename(_T("AdvManData\\ColEdit.exe")); + StartApp(apppath,"",false,_advPath+get_text_field(_adv,"CESTA_ENEMY")); +} + + +void CMainFrame::OnNstrojeTvrceikonpropedmty() +{ + Pathname apppath=Pathname::GetExePath(); + apppath.SetFilename(_T("AdvManData\\ItemIcons.exe")); + StartApp(apppath,"",false,_advPath+get_text_field(_adv,"CESTA_ITEMY")); +} + +void CMainFrame::OnEditorySouboradv() +{ + AfxMessageBox(IDS_EDITADVWARN,MB_ICONEXCLAMATION); + OpenEditor(_advName); +} + +void CMainFrame::OnFileZnovunast() +{ + release_list(_adv); + _adv=read_config(_advName); + _baseMapPath=_advPath+get_text_field(_adv,"CESTA_MAPY"); +} + +void CMainFrame::OnUpdateFileZnovunast(CCmdUI* pCmdUI) +{ + pCmdUI->Enable(_adv!=0); +} + +void CMainFrame::OnEditoryDialogy() +{ + DlgDialogy dlg; + dlg._dlgpath.SetDirectory(_baseMapPath); + dlg._dlgpath.SetFilename(_T("Dialogy.dlg")); + dlg.DoModal(); +} + +void CMainFrame::OnUpdateEditory(CCmdUI *pCmdUI) +{ + pCmdUI->Enable(_adv!=0); +} diff --git a/AdvMan/MainFrm.h b/AdvMan/MainFrm.h new file mode 100644 index 0000000..5a31502 --- /dev/null +++ b/AdvMan/MainFrm.h @@ -0,0 +1,95 @@ +// MainFrm.h : interface of the CMainFrame class +// +///////////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_MAINFRM_H__0420AD88_2B58_4379_BD0D_069A821C039D__INCLUDED_) +#define AFX_MAINFRM_H__0420AD88_2B58_4379_BD0D_069A821C039D__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "ChildView.h" + + +class CMainFrame : public CFrameWnd +{ + +public: + CMainFrame(); +protected: + DECLARE_DYNAMIC(CMainFrame) + +// Attributes +public: + TSTR_LIST _adv; + CString _baseMapPath; + CString _advPath; + CString _advName; +// Operations +public: + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CMainFrame) + virtual BOOL PreCreateWindow(CREATESTRUCT& cs); + virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo); + //}}AFX_VIRTUAL + +// Implementation +public: + void StartApp(const char *appname, CString cmdline, bool wait, const char *folder=0); + void OpenEditor(const char *name); + void SaveAll(); + static LRESULT BroadcastMessage(UINT msg, WPARAM wParam, LPARAM lParam); + void SetTitle(const _TCHAR *name); + virtual ~CMainFrame(); +#ifdef _DEBUG + virtual void AssertValid() const; + virtual void Dump(CDumpContext& dc) const; +#endif + +protected: // control bar embedded members + CStatusBar m_wndStatusBar; + CToolBar m_wndToolBar; + CToolBar m_wndEditoryBar; + CToolBar m_wndPrekladaceBar; + CEdit m_wndView; + +// Generated message map functions +protected: + //{{AFX_MSG(CMainFrame) + afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); + afx_msg void OnSetFocus(CWnd *pOldWnd); + afx_msg void OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu); + afx_msg void OnFileNovdobrodrust(); + afx_msg void OnFileNatidobrodrustv(); + afx_msg void OnEditoryKouzlatab(); + afx_msg void OnEditoryPostavytab(); + afx_msg void OnEditoryItemsscr(); + afx_msg void OnEditoryItemspic(); + afx_msg void OnEditoryWeaponsscr(); + afx_msg void OnDestroy(); + afx_msg void OnPekladaePelokouzla(); + afx_msg void OnPekladaePelodialogy(); + afx_msg void OnPekladaePelopostavytab(); + afx_msg void OnNstrojeMapedit(); + afx_msg void OnNstrojeTestujdobrodrustv(); + afx_msg void OnNstrojeTvrcepodlah(); + afx_msg void OnNstrojeTvrcepaletpronestvry(); + afx_msg void OnNstrojeTvrceikonpropedmty(); + afx_msg void OnEditorySouboradv(); + afx_msg void OnFileZnovunast(); + afx_msg void OnUpdateFileZnovunast(CCmdUI* pCmdUI); + afx_msg void OnEditoryDialogy(); + afx_msg void OnUpdateEditory(CCmdUI *pCmdUI); +//}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_MAINFRM_H__0420AD88_2B58_4379_BD0D_069A821C039D__INCLUDED_) diff --git a/AdvMan/Pathname.cpp b/AdvMan/Pathname.cpp new file mode 100644 index 0000000..aa14710 --- /dev/null +++ b/AdvMan/Pathname.cpp @@ -0,0 +1,621 @@ +// Pathname.cpp: implementation of the Pathname class. +// +////////////////////////////////////////////////////////////////////// + +#include "Pathname.h" +#include +#include +#include +#include +#include + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +#pragma comment(lib,"User32") +#pragma comment(lib,"shell32") + +Pathname::Pathname(const char *name) +{ + _fullpath=NULL; + _path=_filetitle=_extension=_end=""; + + if (name==NULL) SetPathName("*.*"); + else SetPathName(name); +} + +Pathname::Pathname(PathNameNullEnum null) +{ + _fullpath=NULL; + _path=_filetitle=_extension=_end=""; +} + + +Pathname::Pathname(const char *relpath, const Pathname &abspath) +{ + _path=_filetitle=_extension=_end=""; + _fullpath=NULL; + + char *part; + char *pth=strcpy((char *)alloca(sizeof(*relpath)+strlen(relpath)+1),relpath); + part=strrchr(pth,'\\'); + if (part) part++;else part=NULL; + if (part) + { + SetFilename(part); + *part=0; + SetDirectory(pth); + } + else + SetFilename(pth); + if (RelativeToFull(abspath)==false) SetNull(); +} + + +Pathname::~Pathname() +{ + delete [] _fullpath; +} + +const char *Pathname::GetNameFromPath(const char *path) +{ + char *c=strrchr(path,'\\'); + if (c!=NULL) c++;else return path; + return c; +} + +const char *Pathname::GetExtensionFromPath(const char *path) +{ + const char *fname=GetNameFromPath(path); + char *c=strrchr(fname,'.'); + if (c==NULL) c=strrchr(path,0); + return c; +} + +void Pathname::RebuildData(const char *path, const char *filetitle, const char *extension, int pathlen, int titlelen, int extlen) +{ + int totalsize=(pathlen+titlelen+extlen)*2+10; + char *olddata=_fullpath; + _fullpath=new char[totalsize]; + _path=_fullpath+pathlen+titlelen+extlen+1; + memcpy(_path,path,pathlen+1); + _filetitle=_path+pathlen+1; + memcpy(_filetitle,filetitle,titlelen+1); + _extension=_filetitle+titlelen+1; + memcpy(_extension,extension,extlen+1); + _end=_extension+extlen+1; + RebuildPath(); + delete [] olddata; +} + +void Pathname::RebuildPath() +{ + sprintf(_fullpath,"%s%s%s",_path,_filetitle,_extension); +} + +void Pathname::SetDrive(const char dr) +{ + if (HasDrive()) + { + if (dr==0) + { + strcpy(_path,_path+2); + strcpy(_fullpath,_fullpath+2); + } + else + { + _path[0]=dr; + _fullpath[0]=dr; + } + } + else if (dr!=0) + { + int np=IsNetworkPath(); + if (np) + { + _path[0]=dr; + _path[1]=':'; + strcpy(_path+2,_path+np); + RebuildPath(); + } + else + { + char *c=(char *)alloca((strlen(_path)+4)*sizeof(*c)); + sprintf(c,"%c:%s",dr,_path); + SetDirectory(c); + } + } +} + +void Pathname::SetDirectory(const char *dir) +{ + bool copydrv; //directory doesn't contain drive, need copy from original + bool addslash; //directory doesn't ending by backslash, need add it + + int len=strlen(dir); + copydrv=HasDrive() && !HasDrive(dir); //copy original drive, if exists and directory doesn't contaion drive + if (strncmp(dir,"\\\\",2)==0) copydrv=false; //network path, don't copy drive + addslash=len && dir[len-1]!='\\'; //add slash + if (addslash || copydrv) + { + char *c=(char *)alloca((len+4)*sizeof(dir[0])); //allocate some space for string + if (addslash && copydrv) + sprintf(c,"%c%c%s\\",_path[0],_path[1],dir); //add drive and add slash + else if (addslash) + sprintf(c,"%s\\",dir); //add slash only + else + sprintf(c,"%c%c%s",_path[0],_path[1],dir); //add drive only + dir=c; //this is new path for now + len=strlen(dir); + } + if (len<_filetitle-_path) //there is space for store path + {strcpy(_path,dir); RebuildPath();} //store it and rebuild result + else + RebuildData(dir,_filetitle,_extension,len,strlen(_filetitle),strlen(_extension)); + //rebuild internal data complettly +} + +void Pathname::SetFilename(const char *filename) +{ + char *dot=strrchr(filename,'.'); + if (dot==NULL) + { + SetFiletitle(filename); + SetExtension(""); + return; + } + int tllen=dot-filename; + int exlen=strlen(dot); + char *c=(char *)alloca((tllen+1)*sizeof(*c)); + memcpy(c,filename,tllen); + c[tllen]=0; + if (exlen+tllen+1<_end-_filetitle) + { + memcpy(_filetitle,c,tllen+1); + _extension=_filetitle+tllen+1; + memcpy(_extension,dot,exlen+1); + RebuildPath(); + } + else + RebuildData(_path,c,dot,strlen(_path),tllen,exlen); +} + +void Pathname::SetExtension(const char *ext) +{ + int len=strlen(ext); + if (ext[0] && ext[0]!='.') + { + char *s=(char *)alloca((len+2)*sizeof(*s)); + sprintf(s,".%s",ext); + ext=s; + len++; + } + if (len<_end-_extension) + { + memcpy(_extension,ext,len+1); + RebuildPath(); + } + else + { + RebuildData(_path,_filetitle,ext,strlen(_path),strlen(_filetitle),len); + } +} + +void Pathname::SetFiletitle(const char *title) +{ + int len=strlen(title); + if (len<_extension-_filetitle) + { + memcpy(_filetitle,title,len+1); + RebuildPath(); + } + else + { + RebuildData(_path,title,_extension,strlen(_path),len,strlen(_extension)); + } +} + +void Pathname::SetPathName(const char *pathname) +{ + if (pathname==NULL || pathname[0]==0) + { + SetNull(); + return; + } + char *part; + DWORD needsz=GetFullPathName(pathname,0,NULL,&part); + char *fpth=(char *)alloca(needsz*sizeof(*fpth)); + GetFullPathName(pathname,needsz,fpth,&part); + part=strrchr(fpth,'\\'); + if (part) part++;else part=NULL; + if (part) + { + SetFilename(part); + *part=0; + } + else + SetFilename(""); + SetDirectory(fpth); +} + +Pathname& Pathname::operator=(const Pathname& other) +{ + if (other.IsNull()) SetNull(); + else RebuildData(other._path,other._filetitle,other._extension,strlen(other._path),strlen(other._filetitle),strlen(other._extension)); + return *this; +} + +Pathname::Pathname(const Pathname &other) +{ + _fullpath=NULL; + if (other.IsNull()) SetNull(); + else RebuildData(other._path,other._filetitle,other._extension,strlen(other._path),strlen(other._filetitle),strlen(other._extension)); +} + +bool Pathname::FullToRelative(const Pathname &relativeto) +{ + if (relativeto.IsNull() || IsNull()) return false; + bool h1=HasDrive(); + bool h2=relativeto.HasDrive(); + if (h1!=h2) return false; //rozdilny zpusob adresace - nelze vytvorit relatvni cestu + if (h1==true && h2==true && toupper(GetDrive())!=toupper(relativeto.GetDrive())) + return false; //ruzne disky, nelze vytvorit relativni cestu + if (strncmp(_path,"\\\\",2)==0) //sitova cesta + { + int slsh=0; //citac lomitek + const char *a=_path; + const char *b=relativeto._path; + while (toupper(*a)==toupper(*b) && *a && slsh<3) //zacatek sitove cesty musi byt stejny + { + if (*a=='\\') slsh++; + a++;b++; + } + if (slsh!=3) return false; //pokud neni stejny, nelze vytvorit relativni cestu + } + int sublevel=0; + const char *ps1=_path; + const char *ps2=relativeto._path; + if (h1) + {ps1+=2;ps2+=2;} + const char *sls=ps2; + while (toupper(*ps1)==toupper(*ps2) && *ps1) + { + if (*ps2=='\\') sls=ps2+1; + ps1++;ps2++; + } + ps1-=ps2-sls; + if (sls) + { + while (sls=strchr(sls,'\\')) + { + sls++; + sublevel++; + } + } + char *buff=(char *)alloca((sublevel*3+strlen(ps1)+1)*sizeof(*buff)); + char *pos=buff; + for (int i=0;iref._path) + { + end--; + while (end>ref._path && end[-1]!='\\') end--; + } + beg+=3; + } + else + beg+=2; + } + int partln=end-ref._path; + char *buff=(char *)alloca((partln+strlen(beg)+1)*sizeof(*buff)); + memcpy(buff,ref._path,partln); + strcpy(buff+partln,beg); + SetDrive(0); + SetDirectory(buff); + return true; +} + +int Pathname::IsNetworkPath() const +{ + if (strncmp(_path,"\\\\",2)==0) //sitova cesta + { + const char *p=_path+2; + char *c=strchr(p,'\\'); + if (c) return c-_path; + } + return 0; +} + +void Pathname::SetServerName(const char *server) +{ + if (HasDrive()) SetDrive(0); + else + { + int np=IsNetworkPath(); + if (np) strcpy(_path,_path+np); //str + } + char *buff=(char *)alloca((strlen(server)+strlen(_path)+5)*sizeof(*buff)); + if (_path[0]!='\\') + sprintf(buff,"\\\\%s\\%s",server,_path); + else + sprintf(buff,"\\\\%s%s",server,_path); + SetDirectory(buff); +} + +void Pathname::SetNull() +{ + delete [] _fullpath; + _fullpath=NULL; + _path=_filetitle=_extension=_end=""; +} + +bool Pathname::GetPartFromPath(const char *path, int partnum, char *buff, int bufsize, int mode) +{ + const char *scan=path; + while (*scan=='\\') scan++; + while (partnum && *scan) + { + while (*scan!='\\' && *scan) scan++; + while (*scan=='\\') scan++; + partnum--; + } + if (*scan==0) + { + buff[0]=0; + return false; + } + int pt=0; + if (mode==-1) + { + pt=scan-path; + if (pt>bufsize) + { + buff[0]=0; + return true; + } + else + memcpy(buff,path,pt); + } + bool nlast=false; + while (*scan && (mode==1 || !nlast) && ptsize) return false; + if (psize==0) {buff[0]=0;return true;} + strncpy(buff,GetDirectoryWithDrive(),psize-1); + buff[psize-1]=0; + return true; +} + +bool Pathname::IsPathValid() const +{ + if (IsNull()) return false; + char *invalidChars="/*?\"<>|"; + const char *path=GetFullPath(); + if (*path==0) return false; + while (*path) + { + if (strchr(invalidChars,*path)!=NULL) return false; + path++; + } + return true; +} + + + +bool Pathname::SetTempDirectory() +{ + char buff[1]; + DWORD size=GetTempPath(1,buff); + if (size==0) return false; + size++; + char *p=(char *)alloca(size); + if (GetTempPath(size,p)==0) return false; + SetDirectory(p); + return true; +} + +bool Pathname::SetDirectorySpecial(int nSpecCode) +{ + char buff[MAX_PATH]; + if (SHGetSpecialFolderPath(GetForegroundWindow(),buff,nSpecCode,FALSE)!=NOERROR) return false; + SetDirectory(buff); + return true; +} + +bool Pathname::SetTempFile(const char *prefix, unsigned int unique) +{ + char tempname[MAX_PATH]; + if (GetTempFileName(GetDirectoryWithDrive(),prefix,unique,tempname)==0) return false; + this->SetPathName(tempname); + return true; +} + +Pathname Pathname::GetExePath() +{ + char buff[MAX_PATH*4]; + GetModuleFileName(NULL,buff,sizeof(buff)); + return Pathname(buff); +} + +const char *Pathname::FullToRelativeProjectRoot(const char *full, const char *projectRoot) +{ + const char *a=full,*b=projectRoot; + while (*a && tolower(*a)==tolower(*b)) {a++;b++;}; + if (*b) return full; + return a; +} + +bool Pathname::CreateFolder(void *security_descriptor) +{ + int begpart=-1; + int len=strlen(_fullpath)+1; + char *buff=(char *)alloca(len); + for (int i=1;GetPart(i,buff,len,-1);i++) + { + if (begpart==-1 && _access(buff,0)!=0) begpart=i; + if (begpart!=-1) + { + if (begpart==-1) begpart=i; + BOOL res=CreateDirectory(buff,(LPSECURITY_ATTRIBUTES)security_descriptor); + if (res==FALSE) + { + for (int j=i;i>=begpart;i--) + { + GetPart(i,buff,len,-1); + RemoveDirectory(buff); + } + return false; + } + } + } + return true; +} + +bool Pathname::CreateFolder(const char *path, void *security_descriptor) +{ + Pathname pth; + pth.SetDirectory(path); + return pth.CreateFolder(security_descriptor); +} + +static bool RemoveDirectoryFull(const Pathname &p, int part, char *buff, int bufsize) +{ + if (p.GetPart(part+1,buff,bufsize,-1)) + if (RemoveDirectoryFull(p,part+1,buff,bufsize)==false) return false; + p.GetPart(part,buff,bufsize, -1); + return RemoveDirectory(buff)!=FALSE; +} + +static bool RemoveDirRecursive(const char *dir, const char *mask) +{ + if (dir==0 || dir[0]==0) return false; + if (strcmp(dir,"\\")==0) return false; + bool res=true; + Pathname newp; + newp.SetDirectory(dir); + if (mask) + { + WIN32_FIND_DATAA fnd; + HANDLE h; + newp.SetFilename(mask); + h=FindFirstFileA(newp,&fnd); + if (h) + { + do + { + if (!(fnd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + newp.SetFilename(fnd.cFileName); + if (DeleteFile(newp)==FALSE) res=false; + } + }while (FindNextFileA(h,&fnd)); + CloseHandle(h); + } + } + { + WIN32_FIND_DATAA fnd; + HANDLE h; + newp.SetFilename("*.*"); + h=FindFirstFileA(newp,&fnd); + if (h) + { + do + { + if ((fnd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && strcmp(fnd.cFileName,".")!=0 && strcmp(fnd.cFileName,"..")!=0) + { + newp.SetFilename(fnd.cFileName); + if (RemoveDirRecursive(newp,mask)==false) res=false; + else DeleteFile(newp); + } + }while (FindNextFileA(h,&fnd)); + CloseHandle(h); + } + } + return res; + +} + +bool Pathname::DeleteFolder(int dfFlags) +{ + int bufflen=strlen(_fullpath)+1; + char *buff=(char *)alloca(bufflen); +/* if (dfFlags & DFRecycleBin) + { + GetDirectoryWithDriveWLBS(buff,bufflen); + SHFILEOPSTRUCT delinfo; + delinfo.hwnd=NULL; + delinfo.wFunc=FO_DELETE; + delinfo.pFrom=GetFullPath(); + delinfo.pTo=NULL; + delinfo.fFlags=FOF_ALLOWUNDO|FOF_NOCONFIRMATION|FOF_NOERRORUI|((dfFlags & DFRecursive)?0:FOF_NORECURSION)| + ((dfFlags & DFShowProgress)?0:FOF_SILENT); + delinfo.fAnyOperationsAborted=0; + delinfo.hNameMappings=0; + delinfo.lpszProgressTitle=0; + + } + else*/ + { + if (dfFlags & DFRecursive) + { + bool res=RemoveDirRecursive(GetDirectoryWithDrive(),dfFlags & DFFile?GetFilename():0); + if (res==false) return false; + } + if (dfFlags & DFPath) + { + if (GetPart(1,buff,bufflen,-1)==false) return false; + return RemoveDirectoryFull(*this, 1,buff,bufflen); + } + else + { + GetDirectoryWithDriveWLBS(buff,bufflen); + return RemoveDirectory(buff)!=FALSE; + } + + } + return false; +} \ No newline at end of file diff --git a/AdvMan/Pathname.h b/AdvMan/Pathname.h new file mode 100644 index 0000000..8b4c999 --- /dev/null +++ b/AdvMan/Pathname.h @@ -0,0 +1,451 @@ +// Pathname.h: interface for the Pathname class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_Pathname_H__40F41C23_3AA2_486C_B9E5_33AEE67FB313__INCLUDED_) +#define AFX_Pathname_H__40F41C23_3AA2_486C_B9E5_33AEE67FB313__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include +#include +#include + +#ifndef ASSERT +#ifdef _DEBUG +#define ASSERT(x) assert(x) +#else +#define ASSERT(x) +#endif +#endif + +enum PathNameNullEnum {PathNull}; + +#define PathNameCompare(op) bool operator op (const Pathname &other) const \ +{if (IsNull() || other.IsNull()) return false;else return stricmp(_fullpath,other._fullpath) op 0;}\ + bool operator op (const char *other) const \ +{ASSERT(other[0]!=0);\ + if (IsNull() || other==NULL) return false;else return stricmp(_fullpath,other) op 0;} + +#ifndef _UNICODE + +/** class Pathname simplifying manipulation with pathnames, filenames, general paths, and +also supports convert from absolute path to relative respectively */ + + + +class Pathname +{ + ///object value and data + /**The implementation of Pathname creates only one buffer for all variables. It can + increase speed by effective memory use. Strings are stored one after another separated + by zero byte. Evry time any string changed, implementation recalculate buffer usage, and + decide, whether it should resize buffer or not. + + _fullpath also points to string contain full path with filename, + it is dominant value of the class + */ + char *_fullpath; + char *_path; /// + If name is provided, Pathname will expand it into full name with drive and folder name. + @param name optional argument to inicialize object + */ + Pathname(const char *name=NULL); + + ///Construct Pathname class + /** Using this constructor Pathname(PathNull) will create Pathname class with null content is set. + If null content is set, all string-query function returns NULL. IsNull function returns true. This state + is sets until new path is assigned. There is a set of functions invalid called in null state. + */ + + Pathname(PathNameNullEnum null); + + ///Construct Pathname class + /** + @param relpath Relative path or uncomplette path or single filename with extension. + Pathname will expand this pathname into full using absolute path provided by the second + argument. + @param abspath Absolute path used as reference to folder - the origin of relative path + provided in the first argument. + */ + Pathname(const char *relpath, const Pathname &abspath); + + ///Construct Pathname as copy of another pathname + Pathname(const Pathname &other); + + ///Destruct Pathname + virtual ~Pathname(); + + ///Function returns the current drive letter. + /** Before usage, ensure, that current pathname contain drive. + In network path drive letter is missing. + In this case, result is undefined. To ensure, use HasDrive function + @return the drive letter of current path. + */ + char GetDrive() const + { + if (IsNull()) return 0; + return _path[0]; + } + + ///Static function determines, if argument contain a drive information. + /** + @param dir directory to inspect + @return true, if directory contain drive.

+ This function is independed, it don't need any Pathname variable declared. + */ + static bool HasDrive(const char *dir) + {return (isalpha(dir[0]) && dir[1]==':');} + + ///Function determines, if current pathname contain a drive information + /** + @return true, if current pathname contain a drive information + */ + bool HasDrive() const + { + if (IsNull()) return false; + return HasDrive(_path); + } + + + ///Function returns current folder name + /** + if current folder name contain drive, only folder name is returned (without drive). + In other cases (relative or network drives) returns full path. + @return folder name or full path. Pointer is valid until any first change in object. + Do not invoke release function at pointer! + */ + const char *GetDirectory() const + { + if (HasDrive()) return _path+3; + else return _path; + } + + const char *GetDirectoryWithDrive() const + { + return _path; + } + + ///Function returns current filename with extension + /** + @return current filename with extension. Pointer is valid until any first change in object. + Do not invoke release function at pointer! + */ + const char *GetFilename() const + { + if (IsNull()) return NULL; + const char *blk=strrchr(_fullpath,'\\'); + if (blk) blk=blk+1;else blk=_fullpath; + return blk; + } + + ///Function returns current extension (with starting dot) + /** + @return current extension. Pointer is valid until any first change in object. + Do not invoke release function at pointer! + */ + const char *GetExtension() const + {return _extension;} + + ///Function returns current filename without extension (without dot) + /** + @return current filename without extension (without dot). Pointer is valid until any first change in object. + Do not invoke release function at pointer! + */ + const char *GetTitle() const + {return _filetitle;} + + ///Function changes current drive. + /**If object contain pathname with drive, then current drive is changed and function returns. + If object contain network path, then computer name is changed to the drive name. + If object contain relative path, then whole path is replaced by path on root on drive. + @param dr new drive letter. This parameter can be set to zero. It means, that current + driver is deleted, and path is converted to relative path from root. Note: Zero c + cannot be used with network paths and relative paths, and finnaly has no effect to the object + */ + + void SetDrive(const char dr); + + ///Sets new directory for object + /** if object contain a drive letter and argument dir doesn't, then current drive is remain + and only directory part is replaced. If current path is network path or relative path, + then whole path is replaced by new one. + If argument dir contain drive letter, then whole path is replaced too. + @param dir contain new pathname. Backslash should be the last character in string + */ + void SetDirectory(const char *dir); + + ///Sets new filename for object. + /** + If filename contain dot, function assumes, that filename is provided with extension. + Otherwise, current extension remains untouched. + @param filename new filename for object + */ + + void SetFilename(const char *filename); + + ///Sets new extension for object. + /** + If ext doesn't starting with dot, function adds it. + @param ext new extension for object + */ + void SetExtension(const char *ext); + + ///Sets new file title + /** Function changes file title, extension remains untouched. + if title contains extension (dot inside its name), this extension doesn't change + current extension. For example, if current extension is ".cpp" and filetitle contain + "source.h", then result is "source.h.cpp" + @param title a new title for object. + */ + + void SetFiletitle(const char *title); + + ///Function returns full pathname. + /** + @return current pathname. Pointer is valid until any first change in object. + Do not invoke release function at pointer! + */ + + const char *GetFullPath() const + {return _fullpath;} + + ///Sets pathname + /** Function has same effect as constructor. But it can be used + anytime during object lifetime. It simply replaces current pathname with newer. Pathname + in argument is expanded to full pathname, current directory is used as reference. + @param pathname new pathname + */ + void SetPathName(const char *pathname); + + Pathname& operator=(const char *other) + {SetPathName(other);return *this;} + Pathname& operator=(const Pathname& other); + + ///converts object to string + operator const char *() const + {return GetFullPath();} + + ///Static function to help getting filename from pathname + /** Function finds last backslash / and return pointer to first character after it. + Pointer stays valid until original path is destroyed or until original path is changed + @param path pathname to inspect as string + @return pointer to filename + */ + static const char *GetNameFromPath(const char *path); + + ///Static function to help getting extension from pathname + /** Function finds last dot '.' in filename return pointer to it (extension with dot). + Pointer stays valid until original path is destroyed or until original path is changed + @param path pathname to inspect as string + @return pointer to extension + */ + static const char *GetExtensionFromPath(const char *path); + + ///Function sets server name for network path + /** If current path is network path, then changes server name to newer. Otherwise + it remove drive letter, and insert server name before remain path + @param server server name without slashes + */ + void SetServerName(const char *server); + + ///Function inspects current path and returns, whether contain server name + /**@return zero, if current path is not valid network path. Nonzero if path contain + server name. Then value returned count characters containing server name with precedent + slashes. + */ + int IsNetworkPath() const; + + ///Function converts current relative path into absolute path + /** + If current path is not relative, function do nothing. + @param ref reference to path, against which path is relative. + @return true if path has been converted, or false, if conversion is impossible + */ + bool RelativeToFull(const Pathname &ref); + + ///Function converts current absolute path into relative path + /** + If current path is not relative, function do nothing. Both paths must be on the same + drive or network computer. + + @param ref reference to path, against which path should be relative. + @return true if path has been converted, or false, if conversion is impossible + */ + bool FullToRelative(const Pathname &relativeto); + + Pathname& operator+=(const char *relativePath) + {*this=Pathname(relativePath,*this);return *this;} + + Pathname operator+(const char *relativePath) + {Pathname out(relativePath,*this);return out;} + + bool IsNull() const {return _fullpath==NULL;} + + void SetNull(); + + PathNameCompare(<) + PathNameCompare(>) + PathNameCompare(==) + PathNameCompare(>=) + PathNameCompare(<=) + PathNameCompare(!=) + + + ///Function gets part of pathname + /** + @param path subject of examine + @param partnum zero-base index of part of pathname. Index 0 mostly contain drive or server, in case of + relative path, there is the name of the first folder or dots. + @param buff buffer for store result + @param bufsize count characters in buffer; + @param mode mode=0, gets only name of part. + mode=1, get current part and remain parts of path. + mode=-1, gets all parts till current + @return Function returns true, if it was succesful, and it was not last part. Function returns + false, if it was succesful, and it was last part. Function returns false and sets buffer empty, + if an error occured. Function returns true and sets buffer empty, if buffer is too small to hold data + */ + static bool GetPartFromPath(const char *path, int partnum, char *buff, int bufsize, int mode=0); + + ///Function gets part of object + /** + @param partnum zero-base index of part of pathname. Index 0 mostly contain drive or server, in case of + relative path, there is the name of the first folder or dots. + @param buff buffer for store result + @param bufsize count characters in buffer; + @param mode mode=0, gets only name of part. + mode=1, get current part and remain parts of path. + mode=-1, gets all parts till current + @return Function returns true, if it was succesful, and it was not last part. Function returns + false, if it was succesful, and it was last part. Function returns false and sets buffer empty, + if an error occured. Function returns true and sets buffer empty, if buffer is too small to hold data + */ + bool GetPart(int partnum, char *buff, int bufsize,int mode=0) const + { + return GetPartFromPath(this->_fullpath,partnum,buff,bufsize,mode); + } + + /// Get Directory With Drive Without Last Back Slash + /** Retrieves into buffer directory with drive and removes last backslash + @param buff buffer that retrieves path + @param size size of buffer + @return true, if success, failed if buffer is too small*/ + + + bool GetDirectoryWithDriveWLBS(char *buff, size_t size) const; + + + /// function checks, if path is valid and returns true, if does. + bool IsPathValid() const; + + /// Sets special directory. + /** + @param bSpecCode this value may be operation-system + depend. Windows implementation using CSIDL_XXXX constants, which is described in SHGetSpecialFolderLocation function + description + @return true, if function were successful + */ + bool SetDirectorySpecial(int nSpecCode); + + ///Sets temporaly directory. + bool SetTempDirectory(); + + ///Guess temporaly file name + /** + @param prefix prefix string for name + @param unique if unique is non-zero, it is used for new temporaly file. If unique is zero, function guess own unique + value. + @return true if function were successful + */ + bool SetTempFile(const char *prefix="tmp", unsigned int unique=NULL); + + ///Returns path of current executable. + /**It useful, when accessing folder, from when current module has been executed */ + static Pathname GetExePath(); + + ///Solves most used conversion from fullpath to path relative to project root + /** + @param full full pathname with drive + @param projectRoot project root path + @return function returns pointer to full path, where starts relative part. If + fullpath doesn't contain project root path, it returns pointer to full. + @example FullToProjectRoot("x:\\project\\data\\example.txt","x:\\project"); //result is "data\\example.txt" + */ + + static const char *FullToRelativeProjectRoot(const char *full, const char *projectRoot); + + ///Creates folder from path + static bool CreateFolder(const char *path, void *security_descriptor=0); + + ///Creates all folders from path stored in object + /** + Function creates path stored in object. Function creates whole path, when it doesn't + exists. + @param security_descriptor pointer for additional information about security on new folder + if this parameter is NULL, default descriptor is used. This parameter is platform + depended. + @return if path has been created, returns true. In case of error, returns false + and no changes are made on disk (Function rollbacks any changes) + */ + bool CreateFolder(void *security_descriptor=0); + + + enum DeleteFolderFlags { + DFSimple=0, //only deletes latest folder + DFPath=1, //deletes whole path, if there are no files + DFFile=2, //deletes file specified in object. You can use wildcards + DFRecursive=4, //also deletes all folders inside the path +/* DFRecycleBin=8, //move all deleted files or folders into recycle bin + DFShowProgress=16, //enables progress bar during deleting*/ + }; + + ///Deletes folder stored in object + /** + @param dfFlags combination of flags. + @return function returns true, when no error occured. Function return false, + when error occured. + */ + bool DeleteFolder(int dfFlags); + + +protected: + ///Function rebuild buffer with new values + /** This protected function recalculates space for buffer, allocated it, and rebuild its + content with data supplied by arguments. Function doesn't assumes, that all strings are + terminated by zero by default. "pathlen, titlelen and extlen" must contain correct values. + Terminating zero is not included, but function excepting it. + Valid using is: RebuildData(a,b,c,strlen(a),strlen(b),strlen(c)); + All pointers returned by Get functions can be used and stays valid, until this function returns. + */ + void RebuildData(const char *path, const char *filetitle, const char *extension, int pathlen, int titlelen, int extlen); + ///Function only rebuild _fullpath string. + /** It doesn't check space for string! This function is used, when length of path is excepted + the same or smaller, then current. + */ + void RebuildPath(); + + +}; + + +#else + +#error unicode version of Pathname is not currently supported + +#endif + +#undef PathNameCompare + +#endif // !defined(AFX_Pathname_H__40F41C23_3AA2_486C_B9E5_33AEE67FB313__INCLUDED_) diff --git a/AdvMan/StdAfx.cpp b/AdvMan/StdAfx.cpp new file mode 100644 index 0000000..46c628d --- /dev/null +++ b/AdvMan/StdAfx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// AdvMan.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + + + diff --git a/AdvMan/StdAfx.h b/AdvMan/StdAfx.h new file mode 100644 index 0000000..c87af4f --- /dev/null +++ b/AdvMan/StdAfx.h @@ -0,0 +1,33 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__978B5377_B3F7_4A88_A4CA_02390EC070E2__INCLUDED_) +#define AFX_STDAFX_H__978B5377_B3F7_4A88_A4CA_02390EC070E2__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC support for Internet Explorer 4 Common Controls +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + +extern "C" +{ +#include +#include +} +#include "Pathname.h" +#include +#include "..\mapedit\editor.h" +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__978B5377_B3F7_4A88_A4CA_02390EC070E2__INCLUDED_) diff --git a/AdvMan/bgraph2dx.h b/AdvMan/bgraph2dx.h new file mode 100644 index 0000000..e69de29 diff --git a/AdvMan/debug.h b/AdvMan/debug.h new file mode 100644 index 0000000..e69de29 diff --git a/AdvMan/idc_note.ico b/AdvMan/idc_note.ico new file mode 100644 index 0000000000000000000000000000000000000000..c6dc4fe93294834c9ab82ccf4b2de2d9dbd8bff1 GIT binary patch literal 2550 zcmbW3J!oS`5P(OqxF?=n*ecveg=0cE*PF(mBA7smU^pJQ_BGlj7z8OCM2c6bNfQVd zw#pSrNQyfS6GA|ZszBl;rQO6}aB*M@B0~y+l1#o`z34v|$V#*Gc4l_wd$UjCiIn6G z+1ZgezNv`3&DG}SW?VlmiTr}?F{>TqU8E!!7&0sUZrsEKc-D0=cEq04NY;)KhcE`eDci2(l zv3u+uyT{(I8nt1=1`C6ymNLf{QfK^O9orka0~NI$QL)w3b}%`L zItn*(smebQy>2x}Bc6KHg7Z-AVelAy6S8{!QEw{I~a(8zp4-XGA z91dkLQu*@PGk(W8-3`BipvV_jA#Yf!q^}(xz1F+v>@SY_fMjv>`?CSiXl-^%k~x3U z91mOQW^LZzZ!{XsX5&SzT^&dC=lw~OfJUR%u4TkAbivzf*rvt!7zv zUt`L$#$tZk9*?Y+QKZ&b;G5oSy?v6kvuaU)v^3H->6^_W|0r4bjPO@MEcP$DlMw+Y zQ-8V~kk&{);a^A}!qdz)r~FF+fuLh2{aY?DN~_KLX@8aj(&qjBv_DG)AUL_7GQLKV9p;3O!kk|dt=h#(@gul_#TqJpq(F*$g z@5cIrs0q{GTOW42-R~(pLI&&`u8I5&2MZ}L literal 0 HcmV?d00001 diff --git a/AdvMan/mem.h b/AdvMan/mem.h new file mode 100644 index 0000000..02ee3d7 --- /dev/null +++ b/AdvMan/mem.h @@ -0,0 +1,4 @@ +__inline void *getmem(long sz) +{ + return malloc(sz); +} \ No newline at end of file diff --git a/AdvMan/res/AdvMan.ico b/AdvMan/res/AdvMan.ico new file mode 100644 index 0000000000000000000000000000000000000000..5311fc7bb56d51f35cf31db5506d70d8281a435a GIT binary patch literal 1078 zcmd6lF^=3Y3`IHX04iK~jxbfQs->Fug~nS63_ zWfW6B#N?etihYXkW`mmk#iY}P@q=;bw4mYFwxAIRnq&+97*tuH?@cIYeD5Sq0{XLV__Wi}Kqg-`c_Rrn4j#_K~&R-%{ z53lbyzlBfX@#v2)eBcpt;nWU4$9weQcQ(_`^auU?iA*R!Klt76oOK=}9-Oz{sJWr{ zNDKOL;Ut?!2+)rNMYReK;qb_*AG~^CxOpVqJ%loG>ebJs#IL()o_e#t;{Ra30V3vA A&;S4c literal 0 HcmV?d00001 diff --git a/AdvMan/res/AdvMan.rc2 b/AdvMan/res/AdvMan.rc2 new file mode 100644 index 0000000..cb2e42e --- /dev/null +++ b/AdvMan/res/AdvMan.rc2 @@ -0,0 +1,13 @@ +// +// ADVMAN.RC2 - resources Microsoft Visual C++ does not edit directly +// + +#ifdef APSTUDIO_INVOKED + #error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// Add manually edited resources here... + +///////////////////////////////////////////////////////////////////////////// diff --git a/AdvMan/res/Toolbar.bmp b/AdvMan/res/Toolbar.bmp new file mode 100644 index 0000000000000000000000000000000000000000..90aadbeaf9d575719d8c3036e1c87f0e6dca2031 GIT binary patch literal 886 zcmZXSJxc>I7{?P#S}8w zk91I>!VU5NBzN_w|GZo-&o9sO}W2Yg_Q;V81hRUYX z_(6{$TP~OQlEH_{yr&Tw3QeI?TY|ag=B|{D$h_x$wZX_8)cy+xMc!zv`NtbX!TPX> zE7jrG^%l=yS4Mf1iXB7!KmJC_I&1kfM3;&E=0MmN#164YWOpyd-{HcJk-8q%HH7 zm+O_3St7T2TL}N=Un-G7SfBJ=nIuVH4p#YPmN$IJC-^t|%U}3|idzW0D^ZZYOdsmn zf`|6H`(4EI7a3*KYrE@x$Xhq>;P`HSXkfR_s6fQRJ z?fQco5A3{|oyY7O;QjOCQG$KLzhZr1C0Gyg1TXS83lQ83JXf?v1h+Iz1bBq9-|vAe z_;8E&jIeNVi%vvox9GOF`L&+-A@G4^u4NwbTJ2>2T)&_(sZROzeZCQyrRaA?Q3;AW|sc~``aSc zGgxlDNsEGY=vfCju5&Fi%Wpj*I36Ou1YNE7X`Du@xnHhP?{-}efczm*#R;eW3jJyi z6cnu4j1~B+UFT}@2T4Hw<$RIA_hS!l*Y+|Cr02y4~weH%@|NuJ=@~| SAM*>Jdeol|)9O+_(}@28b6Z3J literal 0 HcmV?d00001 diff --git a/AdvMan/res/prekladace.bmp b/AdvMan/res/prekladace.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5493fd2e79b976b2294b8ab1fc96985d19e98f62 GIT binary patch literal 478 zcmYL@F>b>!3`LosLy@I9f}uqndxkqcoe*E4H|Pc0$P=Q-$8yemzlgcW;9G`)8H9yonkG1j`4%%~5Ec=G zi1M3#Y-|1e{pH-fH-ndhmc#BmXb4g1JviJs&V$G{!Y`M(UlZ2u{Ml`T1o)`!x51qw zbRl#RKBB+DwIsX%@qW5$vz4WkoYQmYM>=MTrn_^_Yk=sf@adYp&M{}_7{R4U|8CA} pjKHW1@qd4HjN0$2KZ^I*xNv0tZ+9fu^is4oBj literal 0 HcmV?d00001 diff --git a/AdvMan/resource.h b/AdvMan/resource.h new file mode 100644 index 0000000..009d8cc --- /dev/null +++ b/AdvMan/resource.h @@ -0,0 +1,88 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by AdvMan.rc +// +#define IDC_ADD 4 +#define IDC_DELETE 5 +#define IDC_RESCAN 6 +#define IDD_ABOUTBOX 101 +#define IDD_TEXTEDITOR 105 +#define IDR_EDITORMENU 107 +#define IDI_MAINICON 117 +#define IDI_NOTEPADICON 118 +#define IDR_MAINFRAME 128 +#define IDR_ADVMANTYPE 129 +#define IDS_NOVEDOBRODRUZSTVIDOKONCENO 129 +#define IDD_NOVEDOBR 130 +#define IDS_ADVFILTER 130 +#define IDS_CHYBAPRICTENI 131 +#define IDS_MAINFRAMETITLE 132 +#define IDS_UNTITLED 133 +#define IDS_CANNOTEXECUTE 134 +#define IDD_DIALOGY 134 +#define IDS_NEMOHUNAJITNICOD 135 +#define IDD_NOVYDIALOG 135 +#define IDS_EDITADVWARN 136 +#define IDR_TOOLEDITORY 136 +#define IDS_DLGNAME 137 +#define IDS_DLGDESC 138 +#define IDR_PREKLADACE 138 +#define IDS_DLGID 139 +#define IDS_UNABLETOSAVEDIALOGYDLG 140 +#define IDS_NODESC 141 +#define IDC_JMENO 1000 +#define IDC_EDIT 1000 +#define IDC_ORGANIZACE 1001 +#define IDC_RADIO2 1002 +#define IDC_RADIO3 1003 +#define IDC_KOUZLA 1004 +#define IDC_DIALOGY 1005 +#define IDC_DEFINICE 1006 +#define IDC_MAPY 1007 +#define IDC_MAPY2 1008 +#define IDC_ORIGDLGS 1008 +#define IDC_STARTMAP 1009 +#define IDC_MINPOSTAV 1010 +#define IDC_MAXPOSTAV 1011 +#define IDC_DLGLIST 1012 +#define IDC_POPIS 1013 +#define IDC_CISLO 1016 +#define ID_FILE_NOVDOBRODRUST 32771 +#define ID_FILE_NATIDOBRODRUSTV 32773 +#define ID_EDITORY_KOUZLATAB 32774 +#define ID_EDITORY_POSTAVYTAB 32775 +#define ID_EDITORY_DIALOGY 32776 +#define ID_EDITORY_ITEMSSCR 32777 +#define ID_EDITORY_ITEMSPIC 32778 +#define ID_EDITORY_WEAPONSSCR 32779 +#define ID_NSTROJE_TVRCEPODLAH 32780 +#define ID_NSTROJE_TVRCEPALETPRONESTVRY 32781 +#define ID_NSTROJE_TVRCEIKONPROPEDMTY 32782 +#define ID_PEKLADAE_PELOKOUZLA 32783 +#define ID_PEKLADAE_PELODIALOGY 32784 +#define ID_PEKLADAE_PELOPOSTAVYTAB 32785 +#define ID_NSTROJE_EXPORTUJDOBRODRUSTV 32786 +#define ID_NSTROJE_TEKADDLSOUBOR 32787 +#define ID_NSTROJE_MAPEDIT 32788 +#define ID_NSTROJE_TESTUJDOBRODRUSTV 32789 +#define ID_EDITORY_SOUBORADV 32790 +#define ID_FILE_ZNOVUNAST 32791 +#define ID_VIEW_PREKLADACE 32802 +#define ID_VIEW_EDITORY 32810 +#define ID_PRAVY_UNDO 40001 +#define ID_UPRAVY_COPY 40002 +#define ID_UPRAVY_VYJMOUT 40003 +#define ID_UPRAVY_VLOZIT 40004 +#define ID_UPRAVY_VYMAZAT 40005 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_3D_CONTROLS 1 +#define _APS_NEXT_RESOURCE_VALUE 140 +#define _APS_NEXT_COMMAND_VALUE 32815 +#define _APS_NEXT_CONTROL_VALUE 1018 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/AdvMan/skeldal_win.h b/AdvMan/skeldal_win.h new file mode 100644 index 0000000..4fa48b5 --- /dev/null +++ b/AdvMan/skeldal_win.h @@ -0,0 +1,4 @@ +#include +#include +#include +#include \ No newline at end of file diff --git a/DDLReader/DDLFile.cpp b/DDLReader/DDLFile.cpp new file mode 100644 index 0000000..9f5b556 --- /dev/null +++ b/DDLReader/DDLFile.cpp @@ -0,0 +1,93 @@ +#include "stdafx.h" +#include ".\ddlfile.h" + +DDLFile::DDLFile(void) +{ + _hFile=0; +} + +DDLFile::~DDLFile(void) +{ + if (_hFile!=0) CloseHandle(_hFile); +} + + + + +bool DDLFile::OpenDDLFile(WString filename) +{ + _hFile=CreateFile(filename,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL, + OPEN_EXISTING,FILE_FLAG_RANDOM_ACCESS,NULL); + if (_hFile==INVALID_HANDLE_VALUE) + { + _hFile=0; + return false; + } + return true; +} + +bool DDLFile::ReadFile(void *data, size_t sz) +{ + DWORD readed=0; + if (::ReadFile(_hFile,data,sz,&readed,NULL)==FALSE) return false; + if (readed!=sz) return false; + return true; +} + +bool DDLFile::EnumFiles(IDDLFileEnumerator &enmClass) +{ + unsigned long firstGroup; + unsigned long groupEndOffset; + unsigned long endGroups; + int i; + int ngroups; + SetFilePointer(_hFile,0,0,FILE_BEGIN); + if (ReadFile(&firstGroup,sizeof(firstGroup))==false) return false; + if (ReadFile(&groupEndOffset,sizeof(firstGroup))==false) return false; + unsigned long *group=(unsigned long *)alloca(groupEndOffset); + group[0]=firstGroup; + group[1]=groupEndOffset; + ngroups=groupEndOffset/8; + if (groupEndOffset!=8 && ReadFile(group+2,groupEndOffset-8)==false) return false; + SetFilePointer(_hFile,12,0,FILE_CURRENT); + if (ReadFile(&endGroups,sizeof(endGroups))==false) return false; + for (i=0;i(other); + dother.data=0;dother.sz=0; + } + DDLData& operator =(const DDLData &other) + { + DDLData &dother=const_cast(other); + data=other.data;sz=other.sz; + dother.data=0;dother.sz=0; + return *this; + } +}; + +class DDLFile +{ + HANDLE _hFile; + + bool ReadFile(void *data, size_t sz); +public: + DDLFile(void); + ~DDLFile(void); + + bool OpenDDLFile(WString filename); + bool EnumFiles(IDDLFileEnumerator &enmClass); + DDLData ExtractFile(unsigned long offset); + unsigned long GetFileSize(unsigned long offset); +}; diff --git a/DDLReader/DDLReader.cpp b/DDLReader/DDLReader.cpp new file mode 100644 index 0000000..2042ba3 --- /dev/null +++ b/DDLReader/DDLReader.cpp @@ -0,0 +1,67 @@ +// DDLReader.cpp : Defines the class behaviors for the application. +// + +#include "stdafx.h" +#include "DDLReader.h" +#include "DDLReaderDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CDDLReaderApp + +BEGIN_MESSAGE_MAP(CDDLReaderApp, CWinApp) + //{{AFX_MSG_MAP(CDDLReaderApp) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG + ON_COMMAND(ID_HELP, CWinApp::OnHelp) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CDDLReaderApp construction + +CDDLReaderApp::CDDLReaderApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CDDLReaderApp object + +CDDLReaderApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CDDLReaderApp initialization + +BOOL CDDLReaderApp::InitInstance() +{ + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + + + CDDLReaderDlg dlg; + m_pMainWnd = &dlg; + int nResponse = dlg.DoModal(); + if (nResponse == IDOK) + { + // TODO: Place code here to handle when the dialog is + // dismissed with OK + } + else if (nResponse == IDCANCEL) + { + // TODO: Place code here to handle when the dialog is + // dismissed with Cancel + } + + // Since the dialog has been closed, return FALSE so that we exit the + // application, rather than start the application's message pump. + return FALSE; +} diff --git a/DDLReader/DDLReader.h b/DDLReader/DDLReader.h new file mode 100644 index 0000000..08dbe48 --- /dev/null +++ b/DDLReader/DDLReader.h @@ -0,0 +1,49 @@ +// DDLReader.h : main header file for the DDLREADER application +// + +#if !defined(AFX_DDLREADER_H__9FE8F7F8_112D_4735_A4BA_5141A991D609__INCLUDED_) +#define AFX_DDLREADER_H__9FE8F7F8_112D_4735_A4BA_5141A991D609__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CDDLReaderApp: +// See DDLReader.cpp for the implementation of this class +// + +class CDDLReaderApp : public CWinApp +{ +public: + CDDLReaderApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CDDLReaderApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CDDLReaderApp) + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_DDLREADER_H__9FE8F7F8_112D_4735_A4BA_5141A991D609__INCLUDED_) diff --git a/DDLReader/DDLReader.rc b/DDLReader/DDLReader.rc new file mode 100644 index 0000000..f1fcb4b --- /dev/null +++ b/DDLReader/DDLReader.rc @@ -0,0 +1,278 @@ +// 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 + +///////////////////////////////////////////////////////////////////////////// +// Czech resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY) +#ifdef _WIN32 +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT +#pragma code_page(1250) +#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 + "#define _AFX_NO_SPLITTER_RESOURCES\r\n" + "#define _AFX_NO_OLE_RESOURCES\r\n" + "#define _AFX_NO_TRACKER_RESOURCES\r\n" + "#define _AFX_NO_PROPERTY_RESOURCES\r\n" + "\r\n" + "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n" + "#ifdef _WIN32\r\n" + "LANGUAGE 9, 1\r\n" + "#pragma code_page(1252)\r\n" + "#endif //_WIN32\r\n" + "#include ""res\\DDLReader.rc2"" // non-Microsoft Visual C++ edited resources\r\n" + "#include ""afxres.rc"" // Standard components\r\n" + "#endif\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDR_MAINFRAME ICON "res\\DDLReader.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_EXPORTING DIALOGEX 0, 0, 186, 82 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | + WS_CAPTION | WS_SYSMENU +CAPTION "Exporting" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER | 0x1,7,39, + 172,14 + CTEXT "Exporting",IDC_STATIC,7,7,172,8 + CTEXT "Static",IDC_NAME,7,23,172,8 + PUSHBUTTON "Stop",IDC_BUTTON1,68,61,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_EXPORTING, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 75 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_ABOUTBOX "&About DDLReader..." + IDS_FILEOPENFAILED "Failed to open DDL" + IDC_HEADGROUP "Group" + IDC_HEADFNAME "Filename" + IDC_HEADSIZE "Size" + IDC_HEADOFFSET "Offset" + IDS_DDLFILTER "DDLFiles|*.ddl|All Files|*.*||" + IDC_GROUP_GRAPHICS "Graphics" + IDC_GROUP_SOUNDS "Sounds" + IDC_GROUP_FONTS "Fonts" + IDC_GROUP_BASIC "Basic graphics" +END + +STRINGTABLE +BEGIN + IDC_GROUP_ITEMS "Item graphics" + IDC_GROUP_MONSTERS "Monster graphics" + IDC_GROUP_DIALOGS "Dialog graphics" + IDC_GROUP_UNSPECIFIED "Unspecified" + IDC_GROUP_UNKNOWN "Unknown (%d)" + IDS_UNABLETOCREATEFILE "Unable to create target file: \r\n%1" + IDS_UNABLETOEXTACTDATA "Unable to extract data. General reading error" +END + +#endif // Czech resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOG 0, 0, 235, 55 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About DDLReader" +FONT 8, "MS Sans Serif" +BEGIN + ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20 + LTEXT "DDLReader Version 1.0",IDC_STATIC,40,10,119,8, + SS_NOPREFIX + LTEXT "Copyright (C) 2005",IDC_STATIC,40,25,119,8 + DEFPUSHBUTTON "OK",IDOK,178,7,50,14,WS_GROUP +END + +IDD_DDLREADER_DIALOG DIALOGEX 0, 0, 364, 262 +STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU | WS_THICKFRAME +EXSTYLE WS_EX_APPWINDOW +CAPTION "DDLReader" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + CONTROL "List2",IDC_FILELIST,"SysListView32",LVS_REPORT | + LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,0,14,363,219 + LTEXT "Export to folder:",IDC_POPISEK,0,235,50,8 + EDITTEXT IDC_FOLDER,0,248,263,14,ES_AUTOHSCROLL + PUSHBUTTON "Browse",IDC_BROWSE,268,248,34,14 + PUSHBUTTON "Export",IDC_EXPORT,306,248,58,14 + EDITTEXT IDC_DDLFILE,0,0,313,12,ES_AUTOHSCROLL + PUSHBUTTON "Browse DDL",IDC_DDLBROWSE,314,0,50,12 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "FileDescription", "DDLReader MFC Application" + VALUE "FileVersion", "1, 0, 0, 1" + VALUE "InternalName", "DDLReader" + VALUE "LegalCopyright", "Copyright (C) 2005" + VALUE "OriginalFilename", "DDLReader.EXE" + VALUE "ProductName", "DDLReader Application" + VALUE "ProductVersion", "1, 0, 0, 1" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_ABOUTBOX, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 228 + TOPMARGIN, 7 + BOTTOMMARGIN, 48 + END + + IDD_DDLREADER_DIALOG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 357 + TOPMARGIN, 7 + BOTTOMMARGIN, 255 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#define _AFX_NO_SPLITTER_RESOURCES +#define _AFX_NO_OLE_RESOURCES +#define _AFX_NO_TRACKER_RESOURCES +#define _AFX_NO_PROPERTY_RESOURCES + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE 9, 1 +#pragma code_page(1252) +#endif //_WIN32 +#include "res\DDLReader.rc2" // non-Microsoft Visual C++ edited resources +#include "afxres.rc" // Standard components +#endif + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/DDLReader/DDLReader.sln b/DDLReader/DDLReader.sln new file mode 100644 index 0000000..cc4c08b --- /dev/null +++ b/DDLReader/DDLReader.sln @@ -0,0 +1,34 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DDLReader", "DDLReader.vcproj", "{A5326507-3420-4D03-B9EB-5583790B412B}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SourceCodeControl) = preSolution + SccNumberOfProjects = 2 + SccProjectName0 = \u0022$/Skeldal/DDLReader\u0022,\u0020NJEAAAAA + SccLocalPath0 = ..\\..\\.. + SccProvider0 = MSSCCI:Microsoft\u0020Visual\u0020SourceSafe + CanCheckoutShared = false + SccProjectFilePathRelativizedFromConnection0 = Projects\\Skeldal\\DDLReader\\ + SolutionUniqueID = {A1A5598F-1F71-475C-8CAA-699B487DC20F} + SccProjectUniqueName1 = DDLReader.vcproj + SccLocalPath1 = ..\\..\\.. + CanCheckoutShared = false + SccProjectFilePathRelativizedFromConnection1 = Projects\\Skeldal\\DDLReader\\ + EndGlobalSection + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {A5326507-3420-4D03-B9EB-5583790B412B}.Debug.ActiveCfg = Debug|Win32 + {A5326507-3420-4D03-B9EB-5583790B412B}.Debug.Build.0 = Debug|Win32 + {A5326507-3420-4D03-B9EB-5583790B412B}.Release.ActiveCfg = Release|Win32 + {A5326507-3420-4D03-B9EB-5583790B412B}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/DDLReader/DDLReader.vcproj b/DDLReader/DDLReader.vcproj new file mode 100644 index 0000000..f50a9a4 --- /dev/null +++ b/DDLReader/DDLReader.vcproj @@ -0,0 +1,291 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DDLReader/DDLReaderDlg.cpp b/DDLReader/DDLReaderDlg.cpp new file mode 100644 index 0000000..a649500 --- /dev/null +++ b/DDLReader/DDLReaderDlg.cpp @@ -0,0 +1,533 @@ +// DDLReaderDlg.cpp : implementation file +// + +#include "stdafx.h" +#include "DDLReader.h" +#include "DDLReaderDlg.h" +#include ".\ddlreaderdlg.h" +#include "WPathname.h" +#include "DlgProgress.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CDDLReaderDlg dialog + +CDDLReaderDlg::CDDLReaderDlg(CWnd* pParent /*=NULL*/) + : CDialog(CDDLReaderDlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(CDDLReaderDlg) + vFolder = _T(""); + //}}AFX_DATA_INIT + // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 + m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); +} + +CDDLReaderDlg::~CDDLReaderDlg() +{ + if (!_lastTemp.IsNull()) DeleteFile(_lastTemp); +} + +void CDDLReaderDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CDDLReaderDlg) + DDX_Control(pDX, IDC_FOLDER, wFolder); + DDX_Control(pDX, IDC_FILELIST, wFileList); + DDX_Control(pDX, IDC_BROWSE, wBrowse); + DDX_Control(pDX, IDC_EXPORT, wExport); + DDX_Text(pDX, IDC_FOLDER, vFolder); + DDX_Control(pDX, IDC_POPISEK, wPopisek); + //}}AFX_DATA_MAP + DDX_Control(pDX, IDC_DDLFILE, wDDLFile); + DDX_Control(pDX, IDC_DDLBROWSE, wDDLBrowse); +} + +BEGIN_MESSAGE_MAP(CDDLReaderDlg, CDialog) + //{{AFX_MSG_MAP(CDDLReaderDlg) + ON_WM_SYSCOMMAND() + ON_WM_PAINT() + ON_WM_QUERYDRAGICON() + //}}AFX_MSG_MAP + ON_WM_SIZE() + ON_WM_GETMINMAXINFO() + ON_EN_KILLFOCUS(IDC_DDLFILE, OnEnKillfocusDdlfile) + ON_BN_CLICKED(IDC_DDLBROWSE, OnBnClickedDdlbrowse) + ON_NOTIFY(LVN_COLUMNCLICK, IDC_FILELIST, OnLvnColumnclickFilelist) + ON_BN_CLICKED(IDC_BROWSE, OnBnClickedBrowse) + ON_BN_CLICKED(IDC_EXPORT, OnBnClickedExport) + ON_NOTIFY(NM_DBLCLK, IDC_FILELIST, OnNMDblclkFilelist) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CDDLReaderDlg message handlers + +BOOL CDDLReaderDlg::OnInitDialog() +{ + CRect rc; + GetClientRect(&rc); + _dlgSize=rc.Size(); + CDialog::OnInitDialog(); + + // Add "About..." menu item to system menu. + + // IDM_ABOUTBOX must be in the system command range. + ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); + ASSERT(IDM_ABOUTBOX < 0xF000); + + CMenu* pSysMenu = GetSystemMenu(FALSE); + if (pSysMenu != NULL) + { + CString strAboutMenu; + strAboutMenu.LoadString(IDS_ABOUTBOX); + if (!strAboutMenu.IsEmpty()) + { + pSysMenu->AppendMenu(MF_SEPARATOR); + pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); + } + } + + // Set the icon for this dialog. The framework does this automatically + // when the application's main window is not a dialog + SetIcon(m_hIcon, TRUE); // Set big icon + SetIcon(m_hIcon, FALSE); // Set small icon + + CString header; + header.LoadString(IDC_HEADGROUP); + wFileList.InsertColumn(0,header,LVCFMT_CENTER,100,0); + header.LoadString(IDC_HEADFNAME); + wFileList.InsertColumn(1,header,LVCFMT_LEFT,140,1); + header.LoadString(IDC_HEADSIZE); + wFileList.InsertColumn(2,header,LVCFMT_RIGHT,80,2); + header.LoadString(IDC_HEADOFFSET); + wFileList.InsertColumn(3,header,LVCFMT_RIGHT,80,3); + ListView_SetExtendedListViewStyleEx(wFileList,LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP,LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP); + + // TODO: Add extra initialization here + + return TRUE; // return TRUE unless you set the focus to a control +} + +void CDDLReaderDlg::OnSysCommand(UINT nID, LPARAM lParam) +{ + if ((nID & 0xFFF0) == IDM_ABOUTBOX) + { + CAboutDlg dlgAbout; + dlgAbout.DoModal(); + } + else + { + CDialog::OnSysCommand(nID, lParam); + } +} + +// If you add a minimize button to your dialog, you will need the code below +// to draw the icon. For MFC applications using the document/view model, +// this is automatically done for you by the framework. + +void CDDLReaderDlg::OnPaint() +{ + if (IsIconic()) + { + CPaintDC dc(this); // device context for painting + + SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); + + // Center icon in client rectangle + int cxIcon = GetSystemMetrics(SM_CXICON); + int cyIcon = GetSystemMetrics(SM_CYICON); + CRect rect; + GetClientRect(&rect); + int x = (rect.Width() - cxIcon + 1) / 2; + int y = (rect.Height() - cyIcon + 1) / 2; + + // Draw the icon + dc.DrawIcon(x, y, m_hIcon); + } + else + { + CDialog::OnPaint(); + } +} + +// The system calls this to obtain the cursor to display while the user drags +// the minimized window. +HCURSOR CDDLReaderDlg::OnQueryDragIcon() +{ + return (HCURSOR) m_hIcon; +} + +void MoveWindowRel(HDWP &hdwp, CWnd &wnd, int xr,int yr, int xs, int ys) +{ + CRect rc; + wnd.GetWindowRect(&rc); + wnd.GetParent()->ScreenToClient(&rc); + rc.left+=xr; + rc.top+=yr; + rc.bottom+=yr+ys; + rc.right+=xr+xs; + hdwp=DeferWindowPos(hdwp,wnd,NULL,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top,SWP_NOZORDER); +} + +void CDDLReaderDlg::OnSize(UINT nType, int cx, int cy) +{ + CDialog::OnSize(nType, cx, cy); + if (nType!=SIZE_MINIMIZED) + { + if (wFileList.GetSafeHwnd()!=0) + { + HDWP dwp=BeginDeferWindowPos(10); + int difx=cx-_dlgSize.cx; + int dify=cy-_dlgSize.cy; + MoveWindowRel(dwp,wFileList,0,0,difx,dify); + MoveWindowRel(dwp,wPopisek,0,dify,0,0); + MoveWindowRel(dwp,wFolder,0,dify,difx,0); + MoveWindowRel(dwp,wExport,difx,dify,0,0); + MoveWindowRel(dwp,wBrowse,difx,dify,0,0); + MoveWindowRel(dwp,wDDLFile,0,0,difx,0); + MoveWindowRel(dwp,wDDLBrowse,difx,0,0,0); + EndDeferWindowPos(dwp); + + } + _dlgSize.cx=cx; + _dlgSize.cy=cy; + } +} + + +void CDDLReaderDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI) +{ + CDialog::OnGetMinMaxInfo(lpMMI); + lpMMI->ptMinTrackSize.x=200; + lpMMI->ptMinTrackSize.y=150; + +} + +void CDDLReaderDlg::OnEnKillfocusDdlfile() +{ + CString name; + wDDLFile.GetWindowText(name); + if (_ddlfile.OpenDDLFile(WString(name.GetString()))==false) + AfxMessageBox(IDS_FILEOPENFAILED); + UpdateList(); +} + +static CString GetGroupName(int group) +{ + int id; + switch (group) + { + case 1: id= IDC_GROUP_GRAPHICS;break; + case 2: id= IDC_GROUP_SOUNDS;break; + case 3: id= IDC_GROUP_FONTS;break; + case 7: id= IDC_GROUP_BASIC;break; + case 8: id= IDC_GROUP_ITEMS;break; + case 9: id= IDC_GROUP_MONSTERS;break; + case 11: id= IDC_GROUP_DIALOGS;break; + case 0: id=IDC_GROUP_UNSPECIFIED;break; + default: id=IDC_GROUP_UNKNOWN;break; + } + CString res; + res.Format(id,group); + return res; +} + +bool CDDLReaderDlg::File(WString name, int group, unsigned long offset) +{ + LVITEM item; + CString grpname=GetGroupName(group); + wchar_t buff[40]; + item.iItem=wFileList.GetItemCount(); + item.iSubItem=0; + item.mask=LVIF_GROUPID|LVIF_TEXT; + item.iGroupId=group; + item.pszText=grpname.LockBuffer(); + int ipos=wFileList.InsertItem(&item); + wFileList.SetItemText(ipos,1,name); + wFileList.SetItemText(ipos,3,_ui64tow(offset,buff,10)); + grpname.UnlockBuffer(); + return true; +} + +void CDDLReaderDlg::UpdateList(void) +{ + CString tmp; + wFileList.DeleteAllItems(); + _ddlfile.EnumFiles(*this); + for (int i=0,cnt=wFileList.GetItemCount();iGetItemText(lParam1,sinfo.index); + sinfo.right=sinfo.list->GetItemText(lParam2,sinfo.index); + switch (sinfo.index) + { + case 0: + case 1: res=wcsicmp(sinfo.left,sinfo.right);break; + case 3: { + int l=_wtoi(sinfo.left); + int r=_wtoi(sinfo.right); + res=(l>r)-(lGetItemText(lParam1,3); + sinfo.right=sinfo.list->GetItemText(lParam2,3); + unsigned long l=_wtoi(sinfo.left); + unsigned long r=_wtoi(sinfo.right); + l=sinfo._ddlfile->GetFileSize(l); + r=sinfo._ddlfile->GetFileSize(r); + res=(l>r)-(llParam2)-(lParam1(pNMHDR); + for (int i=0,cnt=wFileList.GetItemCount();iiSubItem; + sinfo.list=&wFileList; + sinfo._ddlfile=&_ddlfile; + wFileList.SortItems(SortItemsInFileList,(LPARAM)&sinfo); + *pResult = 0; +} + +static int WINAPI PosBrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData) + { + const wchar_t *curpath=(const wchar_t *)lpData; + if (uMsg == BFFM_INITIALIZED) + { + if (curpath && curpath[0]) + { + ::SendMessage(hwnd,BFFM_SETSELECTION,TRUE,(LPARAM)((LPCSTR)curpath)); + ::SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)((LPCSTR)curpath)); + } + } + else if (uMsg == BFFM_SELCHANGED) + { + wchar_t buff[_MAX_PATH]; + if (SHGetPathFromIDList((LPITEMIDLIST)lParam,buff)) + { + ::SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)buff); + } + } + return 0; + }; + +static bool PathBrowser(HWND hWnd, wchar_t *path /* MAX_PATH size */) +{ + BROWSEINFO brw; + memset(&brw,0,sizeof(brw)); + brw.hwndOwner=hWnd; + brw.pidlRoot=NULL; + brw.pszDisplayName=path; + brw.lParam=(LPARAM)path; + brw.ulFlags= BIF_RETURNONLYFSDIRS |BIF_STATUSTEXT|BIF_USENEWUI ; + brw.lpfn = (BFFCALLBACK)(PosBrowseCallbackProc); + LPITEMIDLIST il=SHBrowseForFolder( &brw ); + if (il==NULL) return false; + SHGetPathFromIDList(il,path); + IMalloc *shmalloc; + SHGetMalloc(&shmalloc); + shmalloc->Free(il); + if (path[0]==0) return false; + return true; +} + + +void CDDLReaderDlg::OnBnClickedBrowse() +{ + wchar_t path[MAX_PATH]; + wFolder.GetWindowText(path,MAX_PATH); + if (PathBrowser(*this,path)) + { + wFolder.SetWindowText(path); + } +} + +void CDDLReaderDlg::OnBnClickedExport() +{ + wchar_t path[MAX_PATH]; + wFolder.GetWindowText(path,MAX_PATH); + if (path[0]==0) OnBnClickedBrowse(); + wFolder.GetWindowText(path,MAX_PATH); + if (path[0]==0) return; + WPathname fpath; + fpath.SetDirectory(path); + POSITION pos=wFileList.GetFirstSelectedItemPosition(); + int max=wFileList.GetSelectedCount(); + int cur=0; + DlgProgress pb; + if (max) {pb.Create(IDD_EXPORTING);pb.CenterWindow(this);EnableWindow(FALSE);} + while (pos) + { + MSG msg; + pb.wProgress.SetRange(0,max); + pb.wProgress.SetPos(++cur); + int i=wFileList.GetNextSelectedItem(pos); + CString fname; + unsigned long offset; + fname=wFileList.GetItemText(i,1); + offset=(unsigned long)_wtoi64(wFileList.GetItemText(i,3)); + pb.wDesc.SetWindowText(fname); + if (PeekMessage(&msg,0,0,0,PM_NOREMOVE)==TRUE) AfxPumpMessage(); + if (pb.stop) break; + DDLData data=_ddlfile.ExtractFile(offset); + if (data.data!=NULL) + { + fpath.SetFilename(fname); + HANDLE hFile=CreateFile(fpath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL); + while (hFile==INVALID_HANDLE_VALUE) + { + CString msg; + AfxFormatString1(msg,IDS_UNABLETOCREATEFILE,fpath); + int retry=AfxMessageBox(msg,MB_ABORTRETRYIGNORE); + if (retry==IDABORT) {EnableWindow(TRUE);return;} + if (retry==IDIGNORE) break; + hFile=CreateFile(fpath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL); + } + if (hFile!=INVALID_HANDLE_VALUE) + { + DWORD written; + WriteFile(hFile,data.data,data.sz,&written,NULL); + CloseHandle(hFile); + } + } + else + { + CString msg; + AfxFormatString1(msg,IDS_UNABLETOEXTACTDATA,fpath); + AfxMessageBox(msg,MB_OK|MB_ICONSTOP); + } + } + EnableWindow(TRUE); + + +} + +WPathname CDDLReaderDlg::CreateTemp(int index) +{ + if (!_lastTemp.IsNull()) DeleteFile(_lastTemp); + CString fname; + unsigned long offset; + fname=wFileList.GetItemText(index,1); + offset=(unsigned long)_wtoi64(wFileList.GetItemText(index,3)); + _lastTemp.SetTempDirectory(); + _lastTemp.SetFileTitle(WSC("SkeldalDDLReader")); + _lastTemp.SetExtension(WSC(".")+WString(fname)); + DDLData data=_ddlfile.ExtractFile(offset); + if (data.data) + { + HANDLE hFile=CreateFile(_lastTemp,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL); + DWORD written; + WriteFile(hFile,data.data,data.sz,&written,NULL); + CloseHandle(hFile); + } + return _lastTemp; +} + +void CDDLReaderDlg::OnNMDblclkFilelist(NMHDR *pNMHDR, LRESULT *pResult) +{ + // TODO: Add your control notification handler code here + *pResult = 0; + int index=wFileList.GetNextItem(-1,LVNI_FOCUSED); + WPathname pth=CreateTemp(index); + ShellExecute(*this,0,pth,0,0,SW_NORMAL); +} diff --git a/DDLReader/DDLReaderDlg.h b/DDLReader/DDLReaderDlg.h new file mode 100644 index 0000000..e141af8 --- /dev/null +++ b/DDLReader/DDLReaderDlg.h @@ -0,0 +1,76 @@ +// DDLReaderDlg.h : header file +// + +#include "t:\h\atlmfc\include\afxwin.h" +#include "ddlfile.h" +#include "WPathname.h" +#if !defined(AFX_DDLREADERDLG_H__E765355F_0112_4B3E_90CE_111E28FE8EC6__INCLUDED_) +#define AFX_DDLREADERDLG_H__E765355F_0112_4B3E_90CE_111E28FE8EC6__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +///////////////////////////////////////////////////////////////////////////// +// CDDLReaderDlg dialog + +class CDDLReaderDlg : public CDialog, public IDDLFileEnumerator +{ +// Construction + CSize _dlgSize; + WPathname _lastTemp; +public: + CDDLReaderDlg(CWnd* pParent = NULL); // standard constructor + ~CDDLReaderDlg(); + +// Dialog Data + //{{AFX_DATA(CDDLReaderDlg) + enum { IDD = IDD_DDLREADER_DIALOG }; + CEdit wFolder; + CListCtrl wFileList; + CButton wBrowse; + CButton wExport; + CString vFolder; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CDDLReaderDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + HICON m_hIcon; + + // Generated message map functions + //{{AFX_MSG(CDDLReaderDlg) + virtual BOOL OnInitDialog(); + afx_msg void OnSysCommand(UINT nID, LPARAM lParam); + afx_msg void OnPaint(); + afx_msg HCURSOR OnQueryDragIcon(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +public: + afx_msg void OnSize(UINT nType, int cx, int cy); + CStatic wPopisek; + CEdit wDDLFile; + CButton wDDLBrowse; + afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI); + DDLFile _ddlfile; + afx_msg void OnEnKillfocusDdlfile(); + void UpdateList(void); + virtual bool File(WString name, int group, unsigned long offset); + afx_msg void OnBnClickedDdlbrowse(); + afx_msg void OnLvnColumnclickFilelist(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnBnClickedBrowse(); + afx_msg void OnBnClickedExport(); + afx_msg void OnNMDblclkFilelist(NMHDR *pNMHDR, LRESULT *pResult); + + WPathname CreateTemp(int index); +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_DDLREADERDLG_H__E765355F_0112_4B3E_90CE_111E28FE8EC6__INCLUDED_) diff --git a/DDLReader/DlgProgress.cpp b/DDLReader/DlgProgress.cpp new file mode 100644 index 0000000..cccfd60 --- /dev/null +++ b/DDLReader/DlgProgress.cpp @@ -0,0 +1,41 @@ +// DlgProgress.cpp : implementation file +// + +#include "stdafx.h" +#include "DDLReader.h" +#include "DlgProgress.h" +#include ".\dlgprogress.h" + + +// DlgProgress dialog + +IMPLEMENT_DYNAMIC(DlgProgress, CDialog) +DlgProgress::DlgProgress(CWnd* pParent /*=NULL*/) + : CDialog(DlgProgress::IDD, pParent) +{ + stop=false; +} + +DlgProgress::~DlgProgress() +{ +} + +void DlgProgress::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_PROGRESS, wProgress); + DDX_Control(pDX, IDC_NAME, wDesc); +} + + +BEGIN_MESSAGE_MAP(DlgProgress, CDialog) + ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1) +END_MESSAGE_MAP() + + +// DlgProgress message handlers + +void DlgProgress::OnBnClickedButton1() +{ + stop=true; +} diff --git a/DDLReader/DlgProgress.h b/DDLReader/DlgProgress.h new file mode 100644 index 0000000..8e6e3fb --- /dev/null +++ b/DDLReader/DlgProgress.h @@ -0,0 +1,28 @@ +#pragma once +#include "t:\h\atlmfc\include\afxcmn.h" +#include "t:\h\atlmfc\include\afxwin.h" + + +// DlgProgress dialog + +class DlgProgress : public CDialog +{ + DECLARE_DYNAMIC(DlgProgress) + +public: + DlgProgress(CWnd* pParent = NULL); // standard constructor + virtual ~DlgProgress(); + +// Dialog Data + enum { IDD = IDD_EXPORTING }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + + DECLARE_MESSAGE_MAP() +public: + CProgressCtrl wProgress; + CStatic wDesc; + afx_msg void OnBnClickedButton1(); + bool stop; +}; diff --git a/DDLReader/IWStringEffect.h b/DDLReader/IWStringEffect.h new file mode 100644 index 0000000..f11bf5e --- /dev/null +++ b/DDLReader/IWStringEffect.h @@ -0,0 +1,36 @@ +#if !defined(AFX_IWSTRINGEFFECT_H__863ADE82_7789_4E54_BE7D_B8F0740FD81B__INCLUDED_) +#define AFX_IWSTRINGEFFECT_H__863ADE82_7789_4E54_BE7D_B8F0740FD81B__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include + +class IWStringEffect +{ +public: + ///function returns extra size that effect needs + /** + @param curSize size of string that enters to the effect + @return count of extra characters needs to effects; + */ + virtual unsigned long GetEffectExtraSize(unsigned long curSize) {return 0;} + + ///function renders begin of string. + /** Function returns number of characters rendered, and must be <= then size returned by GetEffectExtraSize() + @param renderPtr pointer to render buffer + @param curSize size of string that enters to the effect + @return number of characters rendered. Entered string will be rendered behind. + */ + virtual unsigned long PreRenderString(wchar_t *renderPtr,unsigned long curSize) {return 0;} + + ///function renders effect. + /** + @param renderPtr pointer to begin of render buffer. + @param rendered number of characters rendered by previous effect. Value doesn't point to the end + of buffer, function must add result of PreRenderString */ + virtual void RenderString(wchar_t *renderPtr, unsigned long rendered)=0; +}; + +#endif diff --git a/DDLReader/Projects/Skeldal/DDLReader/DDLFile.cpp b/DDLReader/Projects/Skeldal/DDLReader/DDLFile.cpp new file mode 100644 index 0000000..9f5b556 --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/DDLFile.cpp @@ -0,0 +1,93 @@ +#include "stdafx.h" +#include ".\ddlfile.h" + +DDLFile::DDLFile(void) +{ + _hFile=0; +} + +DDLFile::~DDLFile(void) +{ + if (_hFile!=0) CloseHandle(_hFile); +} + + + + +bool DDLFile::OpenDDLFile(WString filename) +{ + _hFile=CreateFile(filename,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL, + OPEN_EXISTING,FILE_FLAG_RANDOM_ACCESS,NULL); + if (_hFile==INVALID_HANDLE_VALUE) + { + _hFile=0; + return false; + } + return true; +} + +bool DDLFile::ReadFile(void *data, size_t sz) +{ + DWORD readed=0; + if (::ReadFile(_hFile,data,sz,&readed,NULL)==FALSE) return false; + if (readed!=sz) return false; + return true; +} + +bool DDLFile::EnumFiles(IDDLFileEnumerator &enmClass) +{ + unsigned long firstGroup; + unsigned long groupEndOffset; + unsigned long endGroups; + int i; + int ngroups; + SetFilePointer(_hFile,0,0,FILE_BEGIN); + if (ReadFile(&firstGroup,sizeof(firstGroup))==false) return false; + if (ReadFile(&groupEndOffset,sizeof(firstGroup))==false) return false; + unsigned long *group=(unsigned long *)alloca(groupEndOffset); + group[0]=firstGroup; + group[1]=groupEndOffset; + ngroups=groupEndOffset/8; + if (groupEndOffset!=8 && ReadFile(group+2,groupEndOffset-8)==false) return false; + SetFilePointer(_hFile,12,0,FILE_CURRENT); + if (ReadFile(&endGroups,sizeof(endGroups))==false) return false; + for (i=0;i(other); + dother.data=0;dother.sz=0; + } + DDLData& operator =(const DDLData &other) + { + DDLData &dother=const_cast(other); + data=other.data;sz=other.sz; + dother.data=0;dother.sz=0; + return *this; + } +}; + +class DDLFile +{ + HANDLE _hFile; + + bool ReadFile(void *data, size_t sz); +public: + DDLFile(void); + ~DDLFile(void); + + bool OpenDDLFile(WString filename); + bool EnumFiles(IDDLFileEnumerator &enmClass); + DDLData ExtractFile(unsigned long offset); + unsigned long GetFileSize(unsigned long offset); +}; diff --git a/DDLReader/Projects/Skeldal/DDLReader/DDLReader.cpp b/DDLReader/Projects/Skeldal/DDLReader/DDLReader.cpp new file mode 100644 index 0000000..2042ba3 --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/DDLReader.cpp @@ -0,0 +1,67 @@ +// DDLReader.cpp : Defines the class behaviors for the application. +// + +#include "stdafx.h" +#include "DDLReader.h" +#include "DDLReaderDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CDDLReaderApp + +BEGIN_MESSAGE_MAP(CDDLReaderApp, CWinApp) + //{{AFX_MSG_MAP(CDDLReaderApp) + // NOTE - the ClassWizard will add and remove mapping macros here. + // DO NOT EDIT what you see in these blocks of generated code! + //}}AFX_MSG + ON_COMMAND(ID_HELP, CWinApp::OnHelp) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CDDLReaderApp construction + +CDDLReaderApp::CDDLReaderApp() +{ + // TODO: add construction code here, + // Place all significant initialization in InitInstance +} + +///////////////////////////////////////////////////////////////////////////// +// The one and only CDDLReaderApp object + +CDDLReaderApp theApp; + +///////////////////////////////////////////////////////////////////////////// +// CDDLReaderApp initialization + +BOOL CDDLReaderApp::InitInstance() +{ + // Standard initialization + // If you are not using these features and wish to reduce the size + // of your final executable, you should remove from the following + // the specific initialization routines you do not need. + + + CDDLReaderDlg dlg; + m_pMainWnd = &dlg; + int nResponse = dlg.DoModal(); + if (nResponse == IDOK) + { + // TODO: Place code here to handle when the dialog is + // dismissed with OK + } + else if (nResponse == IDCANCEL) + { + // TODO: Place code here to handle when the dialog is + // dismissed with Cancel + } + + // Since the dialog has been closed, return FALSE so that we exit the + // application, rather than start the application's message pump. + return FALSE; +} diff --git a/DDLReader/Projects/Skeldal/DDLReader/DDLReader.h b/DDLReader/Projects/Skeldal/DDLReader/DDLReader.h new file mode 100644 index 0000000..08dbe48 --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/DDLReader.h @@ -0,0 +1,49 @@ +// DDLReader.h : main header file for the DDLREADER application +// + +#if !defined(AFX_DDLREADER_H__9FE8F7F8_112D_4735_A4BA_5141A991D609__INCLUDED_) +#define AFX_DDLREADER_H__9FE8F7F8_112D_4735_A4BA_5141A991D609__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "resource.h" // main symbols + +///////////////////////////////////////////////////////////////////////////// +// CDDLReaderApp: +// See DDLReader.cpp for the implementation of this class +// + +class CDDLReaderApp : public CWinApp +{ +public: + CDDLReaderApp(); + +// Overrides + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CDDLReaderApp) + public: + virtual BOOL InitInstance(); + //}}AFX_VIRTUAL + +// Implementation + + //{{AFX_MSG(CDDLReaderApp) + // NOTE - the ClassWizard will add and remove member functions here. + // DO NOT EDIT what you see in these blocks of generated code ! + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + + +///////////////////////////////////////////////////////////////////////////// + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_DDLREADER_H__9FE8F7F8_112D_4735_A4BA_5141A991D609__INCLUDED_) diff --git a/DDLReader/Projects/Skeldal/DDLReader/DDLReader.rc b/DDLReader/Projects/Skeldal/DDLReader/DDLReader.rc new file mode 100644 index 0000000..f1fcb4b --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/DDLReader.rc @@ -0,0 +1,278 @@ +// 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 + +///////////////////////////////////////////////////////////////////////////// +// Czech resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY) +#ifdef _WIN32 +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT +#pragma code_page(1250) +#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 + "#define _AFX_NO_SPLITTER_RESOURCES\r\n" + "#define _AFX_NO_OLE_RESOURCES\r\n" + "#define _AFX_NO_TRACKER_RESOURCES\r\n" + "#define _AFX_NO_PROPERTY_RESOURCES\r\n" + "\r\n" + "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n" + "#ifdef _WIN32\r\n" + "LANGUAGE 9, 1\r\n" + "#pragma code_page(1252)\r\n" + "#endif //_WIN32\r\n" + "#include ""res\\DDLReader.rc2"" // non-Microsoft Visual C++ edited resources\r\n" + "#include ""afxres.rc"" // Standard components\r\n" + "#endif\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDR_MAINFRAME ICON "res\\DDLReader.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_EXPORTING DIALOGEX 0, 0, 186, 82 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | + WS_CAPTION | WS_SYSMENU +CAPTION "Exporting" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_PROGRESS,"msctls_progress32",WS_BORDER | 0x1,7,39, + 172,14 + CTEXT "Exporting",IDC_STATIC,7,7,172,8 + CTEXT "Static",IDC_NAME,7,23,172,8 + PUSHBUTTON "Stop",IDC_BUTTON1,68,61,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_EXPORTING, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 75 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_ABOUTBOX "&About DDLReader..." + IDS_FILEOPENFAILED "Failed to open DDL" + IDC_HEADGROUP "Group" + IDC_HEADFNAME "Filename" + IDC_HEADSIZE "Size" + IDC_HEADOFFSET "Offset" + IDS_DDLFILTER "DDLFiles|*.ddl|All Files|*.*||" + IDC_GROUP_GRAPHICS "Graphics" + IDC_GROUP_SOUNDS "Sounds" + IDC_GROUP_FONTS "Fonts" + IDC_GROUP_BASIC "Basic graphics" +END + +STRINGTABLE +BEGIN + IDC_GROUP_ITEMS "Item graphics" + IDC_GROUP_MONSTERS "Monster graphics" + IDC_GROUP_DIALOGS "Dialog graphics" + IDC_GROUP_UNSPECIFIED "Unspecified" + IDC_GROUP_UNKNOWN "Unknown (%d)" + IDS_UNABLETOCREATEFILE "Unable to create target file: \r\n%1" + IDS_UNABLETOEXTACTDATA "Unable to extract data. General reading error" +END + +#endif // Czech resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOG 0, 0, 235, 55 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About DDLReader" +FONT 8, "MS Sans Serif" +BEGIN + ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20 + LTEXT "DDLReader Version 1.0",IDC_STATIC,40,10,119,8, + SS_NOPREFIX + LTEXT "Copyright (C) 2005",IDC_STATIC,40,25,119,8 + DEFPUSHBUTTON "OK",IDOK,178,7,50,14,WS_GROUP +END + +IDD_DDLREADER_DIALOG DIALOGEX 0, 0, 364, 262 +STYLE DS_SETFONT | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU | WS_THICKFRAME +EXSTYLE WS_EX_APPWINDOW +CAPTION "DDLReader" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + CONTROL "List2",IDC_FILELIST,"SysListView32",LVS_REPORT | + LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,0,14,363,219 + LTEXT "Export to folder:",IDC_POPISEK,0,235,50,8 + EDITTEXT IDC_FOLDER,0,248,263,14,ES_AUTOHSCROLL + PUSHBUTTON "Browse",IDC_BROWSE,268,248,34,14 + PUSHBUTTON "Export",IDC_EXPORT,306,248,58,14 + EDITTEXT IDC_DDLFILE,0,0,313,12,ES_AUTOHSCROLL + PUSHBUTTON "Browse DDL",IDC_DDLBROWSE,314,0,50,12 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "FileDescription", "DDLReader MFC Application" + VALUE "FileVersion", "1, 0, 0, 1" + VALUE "InternalName", "DDLReader" + VALUE "LegalCopyright", "Copyright (C) 2005" + VALUE "OriginalFilename", "DDLReader.EXE" + VALUE "ProductName", "DDLReader Application" + VALUE "ProductVersion", "1, 0, 0, 1" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_ABOUTBOX, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 228 + TOPMARGIN, 7 + BOTTOMMARGIN, 48 + END + + IDD_DDLREADER_DIALOG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 357 + TOPMARGIN, 7 + BOTTOMMARGIN, 255 + END +END +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#define _AFX_NO_SPLITTER_RESOURCES +#define _AFX_NO_OLE_RESOURCES +#define _AFX_NO_TRACKER_RESOURCES +#define _AFX_NO_PROPERTY_RESOURCES + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE 9, 1 +#pragma code_page(1252) +#endif //_WIN32 +#include "res\DDLReader.rc2" // non-Microsoft Visual C++ edited resources +#include "afxres.rc" // Standard components +#endif + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/DDLReader/Projects/Skeldal/DDLReader/DDLReader.sln b/DDLReader/Projects/Skeldal/DDLReader/DDLReader.sln new file mode 100644 index 0000000..cc4c08b --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/DDLReader.sln @@ -0,0 +1,34 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DDLReader", "DDLReader.vcproj", "{A5326507-3420-4D03-B9EB-5583790B412B}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SourceCodeControl) = preSolution + SccNumberOfProjects = 2 + SccProjectName0 = \u0022$/Skeldal/DDLReader\u0022,\u0020NJEAAAAA + SccLocalPath0 = ..\\..\\.. + SccProvider0 = MSSCCI:Microsoft\u0020Visual\u0020SourceSafe + CanCheckoutShared = false + SccProjectFilePathRelativizedFromConnection0 = Projects\\Skeldal\\DDLReader\\ + SolutionUniqueID = {A1A5598F-1F71-475C-8CAA-699B487DC20F} + SccProjectUniqueName1 = DDLReader.vcproj + SccLocalPath1 = ..\\..\\.. + CanCheckoutShared = false + SccProjectFilePathRelativizedFromConnection1 = Projects\\Skeldal\\DDLReader\\ + EndGlobalSection + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {A5326507-3420-4D03-B9EB-5583790B412B}.Debug.ActiveCfg = Debug|Win32 + {A5326507-3420-4D03-B9EB-5583790B412B}.Debug.Build.0 = Debug|Win32 + {A5326507-3420-4D03-B9EB-5583790B412B}.Release.ActiveCfg = Release|Win32 + {A5326507-3420-4D03-B9EB-5583790B412B}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/DDLReader/Projects/Skeldal/DDLReader/DDLReader.vcproj b/DDLReader/Projects/Skeldal/DDLReader/DDLReader.vcproj new file mode 100644 index 0000000..f50a9a4 --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/DDLReader.vcproj @@ -0,0 +1,291 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DDLReader/Projects/Skeldal/DDLReader/DDLReaderDlg.cpp b/DDLReader/Projects/Skeldal/DDLReader/DDLReaderDlg.cpp new file mode 100644 index 0000000..a649500 --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/DDLReaderDlg.cpp @@ -0,0 +1,533 @@ +// DDLReaderDlg.cpp : implementation file +// + +#include "stdafx.h" +#include "DDLReader.h" +#include "DDLReaderDlg.h" +#include ".\ddlreaderdlg.h" +#include "WPathname.h" +#include "DlgProgress.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + +///////////////////////////////////////////////////////////////////////////// +// CAboutDlg dialog used for App About + +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Dialog Data + //{{AFX_DATA(CAboutDlg) + enum { IDD = IDD_ABOUTBOX }; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CAboutDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + //{{AFX_MSG(CAboutDlg) + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +}; + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ + //{{AFX_DATA_INIT(CAboutDlg) + //}}AFX_DATA_INIT +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CAboutDlg) + //}}AFX_DATA_MAP +} + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) + //{{AFX_MSG_MAP(CAboutDlg) + // No message handlers + //}}AFX_MSG_MAP +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CDDLReaderDlg dialog + +CDDLReaderDlg::CDDLReaderDlg(CWnd* pParent /*=NULL*/) + : CDialog(CDDLReaderDlg::IDD, pParent) +{ + //{{AFX_DATA_INIT(CDDLReaderDlg) + vFolder = _T(""); + //}}AFX_DATA_INIT + // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 + m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); +} + +CDDLReaderDlg::~CDDLReaderDlg() +{ + if (!_lastTemp.IsNull()) DeleteFile(_lastTemp); +} + +void CDDLReaderDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + //{{AFX_DATA_MAP(CDDLReaderDlg) + DDX_Control(pDX, IDC_FOLDER, wFolder); + DDX_Control(pDX, IDC_FILELIST, wFileList); + DDX_Control(pDX, IDC_BROWSE, wBrowse); + DDX_Control(pDX, IDC_EXPORT, wExport); + DDX_Text(pDX, IDC_FOLDER, vFolder); + DDX_Control(pDX, IDC_POPISEK, wPopisek); + //}}AFX_DATA_MAP + DDX_Control(pDX, IDC_DDLFILE, wDDLFile); + DDX_Control(pDX, IDC_DDLBROWSE, wDDLBrowse); +} + +BEGIN_MESSAGE_MAP(CDDLReaderDlg, CDialog) + //{{AFX_MSG_MAP(CDDLReaderDlg) + ON_WM_SYSCOMMAND() + ON_WM_PAINT() + ON_WM_QUERYDRAGICON() + //}}AFX_MSG_MAP + ON_WM_SIZE() + ON_WM_GETMINMAXINFO() + ON_EN_KILLFOCUS(IDC_DDLFILE, OnEnKillfocusDdlfile) + ON_BN_CLICKED(IDC_DDLBROWSE, OnBnClickedDdlbrowse) + ON_NOTIFY(LVN_COLUMNCLICK, IDC_FILELIST, OnLvnColumnclickFilelist) + ON_BN_CLICKED(IDC_BROWSE, OnBnClickedBrowse) + ON_BN_CLICKED(IDC_EXPORT, OnBnClickedExport) + ON_NOTIFY(NM_DBLCLK, IDC_FILELIST, OnNMDblclkFilelist) +END_MESSAGE_MAP() + +///////////////////////////////////////////////////////////////////////////// +// CDDLReaderDlg message handlers + +BOOL CDDLReaderDlg::OnInitDialog() +{ + CRect rc; + GetClientRect(&rc); + _dlgSize=rc.Size(); + CDialog::OnInitDialog(); + + // Add "About..." menu item to system menu. + + // IDM_ABOUTBOX must be in the system command range. + ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); + ASSERT(IDM_ABOUTBOX < 0xF000); + + CMenu* pSysMenu = GetSystemMenu(FALSE); + if (pSysMenu != NULL) + { + CString strAboutMenu; + strAboutMenu.LoadString(IDS_ABOUTBOX); + if (!strAboutMenu.IsEmpty()) + { + pSysMenu->AppendMenu(MF_SEPARATOR); + pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); + } + } + + // Set the icon for this dialog. The framework does this automatically + // when the application's main window is not a dialog + SetIcon(m_hIcon, TRUE); // Set big icon + SetIcon(m_hIcon, FALSE); // Set small icon + + CString header; + header.LoadString(IDC_HEADGROUP); + wFileList.InsertColumn(0,header,LVCFMT_CENTER,100,0); + header.LoadString(IDC_HEADFNAME); + wFileList.InsertColumn(1,header,LVCFMT_LEFT,140,1); + header.LoadString(IDC_HEADSIZE); + wFileList.InsertColumn(2,header,LVCFMT_RIGHT,80,2); + header.LoadString(IDC_HEADOFFSET); + wFileList.InsertColumn(3,header,LVCFMT_RIGHT,80,3); + ListView_SetExtendedListViewStyleEx(wFileList,LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP,LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP); + + // TODO: Add extra initialization here + + return TRUE; // return TRUE unless you set the focus to a control +} + +void CDDLReaderDlg::OnSysCommand(UINT nID, LPARAM lParam) +{ + if ((nID & 0xFFF0) == IDM_ABOUTBOX) + { + CAboutDlg dlgAbout; + dlgAbout.DoModal(); + } + else + { + CDialog::OnSysCommand(nID, lParam); + } +} + +// If you add a minimize button to your dialog, you will need the code below +// to draw the icon. For MFC applications using the document/view model, +// this is automatically done for you by the framework. + +void CDDLReaderDlg::OnPaint() +{ + if (IsIconic()) + { + CPaintDC dc(this); // device context for painting + + SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); + + // Center icon in client rectangle + int cxIcon = GetSystemMetrics(SM_CXICON); + int cyIcon = GetSystemMetrics(SM_CYICON); + CRect rect; + GetClientRect(&rect); + int x = (rect.Width() - cxIcon + 1) / 2; + int y = (rect.Height() - cyIcon + 1) / 2; + + // Draw the icon + dc.DrawIcon(x, y, m_hIcon); + } + else + { + CDialog::OnPaint(); + } +} + +// The system calls this to obtain the cursor to display while the user drags +// the minimized window. +HCURSOR CDDLReaderDlg::OnQueryDragIcon() +{ + return (HCURSOR) m_hIcon; +} + +void MoveWindowRel(HDWP &hdwp, CWnd &wnd, int xr,int yr, int xs, int ys) +{ + CRect rc; + wnd.GetWindowRect(&rc); + wnd.GetParent()->ScreenToClient(&rc); + rc.left+=xr; + rc.top+=yr; + rc.bottom+=yr+ys; + rc.right+=xr+xs; + hdwp=DeferWindowPos(hdwp,wnd,NULL,rc.left,rc.top,rc.right-rc.left,rc.bottom-rc.top,SWP_NOZORDER); +} + +void CDDLReaderDlg::OnSize(UINT nType, int cx, int cy) +{ + CDialog::OnSize(nType, cx, cy); + if (nType!=SIZE_MINIMIZED) + { + if (wFileList.GetSafeHwnd()!=0) + { + HDWP dwp=BeginDeferWindowPos(10); + int difx=cx-_dlgSize.cx; + int dify=cy-_dlgSize.cy; + MoveWindowRel(dwp,wFileList,0,0,difx,dify); + MoveWindowRel(dwp,wPopisek,0,dify,0,0); + MoveWindowRel(dwp,wFolder,0,dify,difx,0); + MoveWindowRel(dwp,wExport,difx,dify,0,0); + MoveWindowRel(dwp,wBrowse,difx,dify,0,0); + MoveWindowRel(dwp,wDDLFile,0,0,difx,0); + MoveWindowRel(dwp,wDDLBrowse,difx,0,0,0); + EndDeferWindowPos(dwp); + + } + _dlgSize.cx=cx; + _dlgSize.cy=cy; + } +} + + +void CDDLReaderDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI) +{ + CDialog::OnGetMinMaxInfo(lpMMI); + lpMMI->ptMinTrackSize.x=200; + lpMMI->ptMinTrackSize.y=150; + +} + +void CDDLReaderDlg::OnEnKillfocusDdlfile() +{ + CString name; + wDDLFile.GetWindowText(name); + if (_ddlfile.OpenDDLFile(WString(name.GetString()))==false) + AfxMessageBox(IDS_FILEOPENFAILED); + UpdateList(); +} + +static CString GetGroupName(int group) +{ + int id; + switch (group) + { + case 1: id= IDC_GROUP_GRAPHICS;break; + case 2: id= IDC_GROUP_SOUNDS;break; + case 3: id= IDC_GROUP_FONTS;break; + case 7: id= IDC_GROUP_BASIC;break; + case 8: id= IDC_GROUP_ITEMS;break; + case 9: id= IDC_GROUP_MONSTERS;break; + case 11: id= IDC_GROUP_DIALOGS;break; + case 0: id=IDC_GROUP_UNSPECIFIED;break; + default: id=IDC_GROUP_UNKNOWN;break; + } + CString res; + res.Format(id,group); + return res; +} + +bool CDDLReaderDlg::File(WString name, int group, unsigned long offset) +{ + LVITEM item; + CString grpname=GetGroupName(group); + wchar_t buff[40]; + item.iItem=wFileList.GetItemCount(); + item.iSubItem=0; + item.mask=LVIF_GROUPID|LVIF_TEXT; + item.iGroupId=group; + item.pszText=grpname.LockBuffer(); + int ipos=wFileList.InsertItem(&item); + wFileList.SetItemText(ipos,1,name); + wFileList.SetItemText(ipos,3,_ui64tow(offset,buff,10)); + grpname.UnlockBuffer(); + return true; +} + +void CDDLReaderDlg::UpdateList(void) +{ + CString tmp; + wFileList.DeleteAllItems(); + _ddlfile.EnumFiles(*this); + for (int i=0,cnt=wFileList.GetItemCount();iGetItemText(lParam1,sinfo.index); + sinfo.right=sinfo.list->GetItemText(lParam2,sinfo.index); + switch (sinfo.index) + { + case 0: + case 1: res=wcsicmp(sinfo.left,sinfo.right);break; + case 3: { + int l=_wtoi(sinfo.left); + int r=_wtoi(sinfo.right); + res=(l>r)-(lGetItemText(lParam1,3); + sinfo.right=sinfo.list->GetItemText(lParam2,3); + unsigned long l=_wtoi(sinfo.left); + unsigned long r=_wtoi(sinfo.right); + l=sinfo._ddlfile->GetFileSize(l); + r=sinfo._ddlfile->GetFileSize(r); + res=(l>r)-(llParam2)-(lParam1(pNMHDR); + for (int i=0,cnt=wFileList.GetItemCount();iiSubItem; + sinfo.list=&wFileList; + sinfo._ddlfile=&_ddlfile; + wFileList.SortItems(SortItemsInFileList,(LPARAM)&sinfo); + *pResult = 0; +} + +static int WINAPI PosBrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData) + { + const wchar_t *curpath=(const wchar_t *)lpData; + if (uMsg == BFFM_INITIALIZED) + { + if (curpath && curpath[0]) + { + ::SendMessage(hwnd,BFFM_SETSELECTION,TRUE,(LPARAM)((LPCSTR)curpath)); + ::SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)((LPCSTR)curpath)); + } + } + else if (uMsg == BFFM_SELCHANGED) + { + wchar_t buff[_MAX_PATH]; + if (SHGetPathFromIDList((LPITEMIDLIST)lParam,buff)) + { + ::SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)buff); + } + } + return 0; + }; + +static bool PathBrowser(HWND hWnd, wchar_t *path /* MAX_PATH size */) +{ + BROWSEINFO brw; + memset(&brw,0,sizeof(brw)); + brw.hwndOwner=hWnd; + brw.pidlRoot=NULL; + brw.pszDisplayName=path; + brw.lParam=(LPARAM)path; + brw.ulFlags= BIF_RETURNONLYFSDIRS |BIF_STATUSTEXT|BIF_USENEWUI ; + brw.lpfn = (BFFCALLBACK)(PosBrowseCallbackProc); + LPITEMIDLIST il=SHBrowseForFolder( &brw ); + if (il==NULL) return false; + SHGetPathFromIDList(il,path); + IMalloc *shmalloc; + SHGetMalloc(&shmalloc); + shmalloc->Free(il); + if (path[0]==0) return false; + return true; +} + + +void CDDLReaderDlg::OnBnClickedBrowse() +{ + wchar_t path[MAX_PATH]; + wFolder.GetWindowText(path,MAX_PATH); + if (PathBrowser(*this,path)) + { + wFolder.SetWindowText(path); + } +} + +void CDDLReaderDlg::OnBnClickedExport() +{ + wchar_t path[MAX_PATH]; + wFolder.GetWindowText(path,MAX_PATH); + if (path[0]==0) OnBnClickedBrowse(); + wFolder.GetWindowText(path,MAX_PATH); + if (path[0]==0) return; + WPathname fpath; + fpath.SetDirectory(path); + POSITION pos=wFileList.GetFirstSelectedItemPosition(); + int max=wFileList.GetSelectedCount(); + int cur=0; + DlgProgress pb; + if (max) {pb.Create(IDD_EXPORTING);pb.CenterWindow(this);EnableWindow(FALSE);} + while (pos) + { + MSG msg; + pb.wProgress.SetRange(0,max); + pb.wProgress.SetPos(++cur); + int i=wFileList.GetNextSelectedItem(pos); + CString fname; + unsigned long offset; + fname=wFileList.GetItemText(i,1); + offset=(unsigned long)_wtoi64(wFileList.GetItemText(i,3)); + pb.wDesc.SetWindowText(fname); + if (PeekMessage(&msg,0,0,0,PM_NOREMOVE)==TRUE) AfxPumpMessage(); + if (pb.stop) break; + DDLData data=_ddlfile.ExtractFile(offset); + if (data.data!=NULL) + { + fpath.SetFilename(fname); + HANDLE hFile=CreateFile(fpath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL); + while (hFile==INVALID_HANDLE_VALUE) + { + CString msg; + AfxFormatString1(msg,IDS_UNABLETOCREATEFILE,fpath); + int retry=AfxMessageBox(msg,MB_ABORTRETRYIGNORE); + if (retry==IDABORT) {EnableWindow(TRUE);return;} + if (retry==IDIGNORE) break; + hFile=CreateFile(fpath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL); + } + if (hFile!=INVALID_HANDLE_VALUE) + { + DWORD written; + WriteFile(hFile,data.data,data.sz,&written,NULL); + CloseHandle(hFile); + } + } + else + { + CString msg; + AfxFormatString1(msg,IDS_UNABLETOEXTACTDATA,fpath); + AfxMessageBox(msg,MB_OK|MB_ICONSTOP); + } + } + EnableWindow(TRUE); + + +} + +WPathname CDDLReaderDlg::CreateTemp(int index) +{ + if (!_lastTemp.IsNull()) DeleteFile(_lastTemp); + CString fname; + unsigned long offset; + fname=wFileList.GetItemText(index,1); + offset=(unsigned long)_wtoi64(wFileList.GetItemText(index,3)); + _lastTemp.SetTempDirectory(); + _lastTemp.SetFileTitle(WSC("SkeldalDDLReader")); + _lastTemp.SetExtension(WSC(".")+WString(fname)); + DDLData data=_ddlfile.ExtractFile(offset); + if (data.data) + { + HANDLE hFile=CreateFile(_lastTemp,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL); + DWORD written; + WriteFile(hFile,data.data,data.sz,&written,NULL); + CloseHandle(hFile); + } + return _lastTemp; +} + +void CDDLReaderDlg::OnNMDblclkFilelist(NMHDR *pNMHDR, LRESULT *pResult) +{ + // TODO: Add your control notification handler code here + *pResult = 0; + int index=wFileList.GetNextItem(-1,LVNI_FOCUSED); + WPathname pth=CreateTemp(index); + ShellExecute(*this,0,pth,0,0,SW_NORMAL); +} diff --git a/DDLReader/Projects/Skeldal/DDLReader/DDLReaderDlg.h b/DDLReader/Projects/Skeldal/DDLReader/DDLReaderDlg.h new file mode 100644 index 0000000..e141af8 --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/DDLReaderDlg.h @@ -0,0 +1,76 @@ +// DDLReaderDlg.h : header file +// + +#include "t:\h\atlmfc\include\afxwin.h" +#include "ddlfile.h" +#include "WPathname.h" +#if !defined(AFX_DDLREADERDLG_H__E765355F_0112_4B3E_90CE_111E28FE8EC6__INCLUDED_) +#define AFX_DDLREADERDLG_H__E765355F_0112_4B3E_90CE_111E28FE8EC6__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +///////////////////////////////////////////////////////////////////////////// +// CDDLReaderDlg dialog + +class CDDLReaderDlg : public CDialog, public IDDLFileEnumerator +{ +// Construction + CSize _dlgSize; + WPathname _lastTemp; +public: + CDDLReaderDlg(CWnd* pParent = NULL); // standard constructor + ~CDDLReaderDlg(); + +// Dialog Data + //{{AFX_DATA(CDDLReaderDlg) + enum { IDD = IDD_DDLREADER_DIALOG }; + CEdit wFolder; + CListCtrl wFileList; + CButton wBrowse; + CButton wExport; + CString vFolder; + //}}AFX_DATA + + // ClassWizard generated virtual function overrides + //{{AFX_VIRTUAL(CDDLReaderDlg) + protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + //}}AFX_VIRTUAL + +// Implementation +protected: + HICON m_hIcon; + + // Generated message map functions + //{{AFX_MSG(CDDLReaderDlg) + virtual BOOL OnInitDialog(); + afx_msg void OnSysCommand(UINT nID, LPARAM lParam); + afx_msg void OnPaint(); + afx_msg HCURSOR OnQueryDragIcon(); + //}}AFX_MSG + DECLARE_MESSAGE_MAP() +public: + afx_msg void OnSize(UINT nType, int cx, int cy); + CStatic wPopisek; + CEdit wDDLFile; + CButton wDDLBrowse; + afx_msg void OnGetMinMaxInfo(MINMAXINFO* lpMMI); + DDLFile _ddlfile; + afx_msg void OnEnKillfocusDdlfile(); + void UpdateList(void); + virtual bool File(WString name, int group, unsigned long offset); + afx_msg void OnBnClickedDdlbrowse(); + afx_msg void OnLvnColumnclickFilelist(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnBnClickedBrowse(); + afx_msg void OnBnClickedExport(); + afx_msg void OnNMDblclkFilelist(NMHDR *pNMHDR, LRESULT *pResult); + + WPathname CreateTemp(int index); +}; + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_DDLREADERDLG_H__E765355F_0112_4B3E_90CE_111E28FE8EC6__INCLUDED_) diff --git a/DDLReader/Projects/Skeldal/DDLReader/DlgProgress.cpp b/DDLReader/Projects/Skeldal/DDLReader/DlgProgress.cpp new file mode 100644 index 0000000..cccfd60 --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/DlgProgress.cpp @@ -0,0 +1,41 @@ +// DlgProgress.cpp : implementation file +// + +#include "stdafx.h" +#include "DDLReader.h" +#include "DlgProgress.h" +#include ".\dlgprogress.h" + + +// DlgProgress dialog + +IMPLEMENT_DYNAMIC(DlgProgress, CDialog) +DlgProgress::DlgProgress(CWnd* pParent /*=NULL*/) + : CDialog(DlgProgress::IDD, pParent) +{ + stop=false; +} + +DlgProgress::~DlgProgress() +{ +} + +void DlgProgress::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_PROGRESS, wProgress); + DDX_Control(pDX, IDC_NAME, wDesc); +} + + +BEGIN_MESSAGE_MAP(DlgProgress, CDialog) + ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1) +END_MESSAGE_MAP() + + +// DlgProgress message handlers + +void DlgProgress::OnBnClickedButton1() +{ + stop=true; +} diff --git a/DDLReader/Projects/Skeldal/DDLReader/DlgProgress.h b/DDLReader/Projects/Skeldal/DDLReader/DlgProgress.h new file mode 100644 index 0000000..8e6e3fb --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/DlgProgress.h @@ -0,0 +1,28 @@ +#pragma once +#include "t:\h\atlmfc\include\afxcmn.h" +#include "t:\h\atlmfc\include\afxwin.h" + + +// DlgProgress dialog + +class DlgProgress : public CDialog +{ + DECLARE_DYNAMIC(DlgProgress) + +public: + DlgProgress(CWnd* pParent = NULL); // standard constructor + virtual ~DlgProgress(); + +// Dialog Data + enum { IDD = IDD_EXPORTING }; + +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + + DECLARE_MESSAGE_MAP() +public: + CProgressCtrl wProgress; + CStatic wDesc; + afx_msg void OnBnClickedButton1(); + bool stop; +}; diff --git a/DDLReader/Projects/Skeldal/DDLReader/IWStringEffect.h b/DDLReader/Projects/Skeldal/DDLReader/IWStringEffect.h new file mode 100644 index 0000000..f11bf5e --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/IWStringEffect.h @@ -0,0 +1,36 @@ +#if !defined(AFX_IWSTRINGEFFECT_H__863ADE82_7789_4E54_BE7D_B8F0740FD81B__INCLUDED_) +#define AFX_IWSTRINGEFFECT_H__863ADE82_7789_4E54_BE7D_B8F0740FD81B__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include + +class IWStringEffect +{ +public: + ///function returns extra size that effect needs + /** + @param curSize size of string that enters to the effect + @return count of extra characters needs to effects; + */ + virtual unsigned long GetEffectExtraSize(unsigned long curSize) {return 0;} + + ///function renders begin of string. + /** Function returns number of characters rendered, and must be <= then size returned by GetEffectExtraSize() + @param renderPtr pointer to render buffer + @param curSize size of string that enters to the effect + @return number of characters rendered. Entered string will be rendered behind. + */ + virtual unsigned long PreRenderString(wchar_t *renderPtr,unsigned long curSize) {return 0;} + + ///function renders effect. + /** + @param renderPtr pointer to begin of render buffer. + @param rendered number of characters rendered by previous effect. Value doesn't point to the end + of buffer, function must add result of PreRenderString */ + virtual void RenderString(wchar_t *renderPtr, unsigned long rendered)=0; +}; + +#endif diff --git a/DDLReader/Projects/Skeldal/DDLReader/StdAfx.cpp b/DDLReader/Projects/Skeldal/DDLReader/StdAfx.cpp new file mode 100644 index 0000000..1a90873 --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/StdAfx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// DDLReader.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + + + diff --git a/DDLReader/Projects/Skeldal/DDLReader/StdAfx.h b/DDLReader/Projects/Skeldal/DDLReader/StdAfx.h new file mode 100644 index 0000000..666c5f5 --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/StdAfx.h @@ -0,0 +1,27 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__C5BDACC6_729E_4CA2_B27E_A1F209FB32A7__INCLUDED_) +#define AFX_STDAFX_H__C5BDACC6_729E_4CA2_B27E_A1F209FB32A7__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC support for Internet Explorer 4 Common Controls +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + +#include "wstring.h" + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__C5BDACC6_729E_4CA2_B27E_A1F209FB32A7__INCLUDED_) diff --git a/DDLReader/Projects/Skeldal/DDLReader/WPathname.cpp b/DDLReader/Projects/Skeldal/DDLReader/WPathname.cpp new file mode 100644 index 0000000..fab2f57 --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/WPathname.cpp @@ -0,0 +1,408 @@ +// WPathname.cpp: implementation of the WPathname class. +// +////////////////////////////////////////////////////////////////////// + +#include "WPathname.h" +#include +#include + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +WPathname::WPathname(const wchar_t *name /*=NULL*/) +{ + if (name) SetPathname(name); +} + +WPathname::WPathname(const WString &name) +{ + SetPathname(name); +} + +WPathname::WPathname(const wchar_t *relpath, const WPathname &abspath) +{ + _fullpath=WString(relpath); + int chr=_fullpath.FindLast('\\'); + if (chr!=-1) + { + _path=_fullpath.Left(chr+1); + _filetitle=_fullpath.Right(chr+1); + } + else + { + _filetitle=_fullpath; + } + chr=_filetitle.FindLast('.'); + if (chr!=-1) + { + _extension=_filetitle.Right(chr); + _filetitle=_filetitle.Left(chr); + } + + RelativeToFull(abspath); +} + + +WPathname::WPathname(const WPathname &other) +{ + _fullpath=other._fullpath; + _path=other._path; + _filetitle=other._filetitle; + _extension=other._extension; +} + +void WPathname::SetDrive(wchar_t dr) +{ + if (HasDrive()) + { + if (dr==0) _path=_path.Right(2); + else _path[0]=dr; + } + else if (dr!=0) + { + int np=IsNetworkPath(); + wchar_t buff[2]; + buff[0]=dr; + buff[1]=':'; + buff[2]=0; + if (np) + _path=WString(buff)+_path.Right(np); + else + _path=WString(buff)+_path; + + } + RebuildPath(); +} + +void WPathname::SetDirectory(const wchar_t *dir) +{ + bool copydrv; //directory doesn't contain drive, need copy from original + bool addslash; //directory doesn't ending by backslash, need add it + + int len=wcslen(dir); + copydrv=HasDrive(dir) || !HasDrive(); //copy original drive, if exists and directory doesn't contaion drive + if (wcsncmp(dir,L"\\\\",2)==0) copydrv=true; //network path, don't copy drive + addslash=len && dir[len-1]!='\\'; //add slash + if (copydrv) + _path=WString(dir); + else + _path=_path.Left(2)+WString(dir); + if (addslash) + _path+=WSC("\\"); + + RebuildPath(); +} + +void WPathname::SetFilename(const wchar_t *filename) +{ + WString wfilename=WString(filename); + int dot=wfilename.FindLast('.'); + if (dot==-1) + { + _filetitle=wfilename; + _extension=0; + } + else + { + _filetitle=wfilename.Left(dot); + _extension=wfilename.Right(dot); + } + + RebuildPath(); +} + +void WPathname::SetExtension(const wchar_t *ext) +{ + _extension=WString(ext); + RebuildPath(); +} + +void WPathname::SetFileTitle(const wchar_t *title) +{ + _filetitle=WString(title); + RebuildPath(); +} + +void WPathname::SetPathname(const wchar_t *pathname) +{ + SetPathname(WString(pathname)); +} + +void WPathname::SetPathname(const WString &pathname) +{ + if (pathname.GetLength()==0) SetNull(); + else + { + wchar_t *part; + DWORD needsz=GetFullPathNameW(pathname,0,NULL,&part); + wchar_t *fpth=(wchar_t *)alloca(needsz*sizeof(*fpth)); + GetFullPathNameW(pathname,needsz,fpth,&part); + part=wcsrchr(fpth,'\\'); + if (part) part++;else part=NULL; + if (part) + { + SetFilename(part); + *part=0; + } + else + SetFilename(WString()); + SetDirectory(fpth); + } +} + +const wchar_t *WPathname::GetNameFromPath(const wchar_t *path) +{ + const wchar_t *c=wcsrchr(path,'\\'); + if (c!=NULL) c++;else return path; + return c; +} + +const wchar_t *WPathname::GetExtensionFromPath(const wchar_t *path) +{ + const wchar_t *fname=GetNameFromPath(path); + const wchar_t *c=wcsrchr(fname,'.'); + if (c==NULL) c=wcsrchr(path,0); + return c; +} + +void WPathname::RebuildPath() +{ + _fullpath=_path+_filetitle+_extension; +} + +bool WPathname::GetDirectoryWithDriveWLBS(wchar_t *buff, size_t size) const +{ + size_t psize=wcslen(GetDirectoryWithDrive()); + if (psize>size) return false; + if (psize==0) {buff[0]=0;return true;} + wcsncpy(buff,GetDirectoryWithDrive(),psize-1); + buff[psize-1]=0; + return true; +} + +WString WPathname::GetDirectoryWithDriveWLBS() const +{ + if (_path.GetLength()) return _path.Left(_path.GetLength()-1); + return WString(); +} + +bool WPathname::IsPathValid() const +{ + if (IsNull()) return false; + wchar_t *invalidChars=L"/*?\"<>|"; + const wchar_t *path=GetFullPath(); + if (*path==0) return false; + while (*path) + { + if (wcschr(invalidChars,*path)!=NULL) return false; + path++; + } + return true; +} + +bool WPathname::SetTempDirectory() +{ + wchar_t buff[1]; + DWORD size=GetTempPathW(1,buff); + if (size==0) return false; + WString pth; + wchar_t *p=pth.CreateBuffer(size); + if (GetTempPathW(size,p)==0) return false; + pth.UnlockBuffer(); + _path=pth; + return true; +} + +bool WPathname::SetDirectorySpecial(int nSpecCode) +{ + wchar_t buff[MAX_PATH]; + if (SHGetSpecialFolderPathW(GetForegroundWindow(),buff,nSpecCode,FALSE)!=NOERROR) return false; + SetDirectory(buff); + return true; +} + +bool WPathname::SetTempFile(const wchar_t *prefix, unsigned int unique) +{ + wchar_t tempname[MAX_PATH]; + if (GetTempFileNameW(GetDirectoryWithDrive(),prefix,unique,tempname)==0) return false; + this->SetPathname(tempname); + return true; +} + +WPathname WPathname::GetExePath() +{ + wchar_t buff[MAX_PATH*4]; + GetModuleFileNameW(NULL,buff,sizeof(buff)); + return WPathname(buff); +} + +const wchar_t *WPathname::FullToRelativeProjectRoot(const wchar_t *full, const wchar_t *projectRoot) +{ + const wchar_t *a=full,*b=projectRoot; + while (*a && towlower(*a)==towlower(*b)) {a++;b++;}; + if (*b) return full; + return a; +} + +bool WPathname::FullToRelative(const WPathname &relativeto) +{ + if (relativeto.IsNull() || IsNull()) return false; + bool h1=HasDrive(); + bool h2=relativeto.HasDrive(); + if (h1!=h2) return false; //rozdilny zpusob adresace - nelze vytvorit relatvni cestu + if (h1==true && h2==true && towupper(GetDrive())!=towupper(relativeto.GetDrive())) + return false; //ruzne disky, nelze vytvorit relativni cestu + if (wcsncmp(_path,L"\\\\",2)==0) //sitova cesta + { + int slsh=0; //citac lomitek + const wchar_t *a=_path; + const wchar_t *b=relativeto._path; + while (towupper(*a)==towupper(*b) && *a && slsh<3) //zacatek sitove cesty musi byt stejny + { + if (*a=='\\') slsh++; + a++;b++; + } + if (slsh!=3) return false; //pokud neni stejny, nelze vytvorit relativni cestu + } + int sublevel=0; + const wchar_t *ps1=_path; + const wchar_t *ps2=relativeto._path; + if (h1) {ps1+=2;ps2+=2;} + const wchar_t *sls=ps2; + while (towupper(*ps1)==towupper(*ps2) && *ps1) + { + if (*ps2=='\\') sls=ps2+1; + ps1++;ps2++; + } + ps1-=ps2-sls; + if (sls) + { + while (sls=wcschr(sls,'\\')) + { + sls++; + sublevel++; + } + } + wchar_t *buff=(wchar_t *)alloca((sublevel*3+wcslen(ps1)+1)*sizeof(*buff)); + wchar_t *pos=buff; + for (int i=0;iref._path.GetString()) + { + end--; + while (end>ref._path.GetString() && end[-1]!='\\') end--; + } + beg+=3; + } + else + beg+=2; + } + int partln=end-ref._path; + wchar_t *buff=(wchar_t *)alloca((partln+wcslen(beg)+1)*sizeof(*buff)); + wcsncpy(buff,ref._path,partln); + wcscpy(buff+partln,beg); + SetDrive(0); + SetDirectory(buff); + return true; +} + +int WPathname::IsNetworkPath() const +{ + if (wcsncmp(_path,L"\\\\",2)==0) //sitova cesta + { + const wchar_t *p=_path+2; + const wchar_t *c=wcschr(p,'\\'); + if (c) return c-_path; + } + return 0; +} + +void WPathname::SetServerName(const wchar_t *server) +{ + if (HasDrive()) SetDrive(0); + else + { + int np=IsNetworkPath(); + _path=_path.Right(np); + } + + _path=WSC("\\\\")+WString(server)+WSC("\\"); + RebuildPath(); +} + +void WPathname::SetNull() +{ + _fullpath=_path=_filetitle=_extension=0; +} + +bool WPathname::GetPartFromPath(const wchar_t *path, int partnum, wchar_t *buff, int bufsize, int mode) +{ + const wchar_t *scan=path; + while (*scan=='\\') scan++; + while (partnum && *scan) + { + while (*scan!='\\' && *scan) scan++; + while (*scan=='\\') scan++; + partnum--; + } + if (*scan==0) + { + buff[0]=0; + return false; + } + int pt=0; + if (mode==-1) + { + pt=scan-path; + if (pt>bufsize) + { + buff[0]=0; + return true; + } + else + memcpy(buff,path,pt); + } + bool nlast=false; + while (*scan && (mode==1 || !nlast) && pt 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "WString.h" + +#ifndef ASSERT +#ifdef _DEBUG +#define ASSERT(x) assert(x) +#else +#define ASSERT(x) +#endif +#endif + +#define WPathnameCompare(op) bool operator op (const WPathname &other) const \ +{if (IsNull() || other.IsNull()) return false;else return wcsicmp(_fullpath,other._fullpath) op 0;}\ + bool operator op (const wchar_t *other) const \ +{ASSERT(!other || other[0]!=0);\ + if (IsNull() || other==NULL) return false;else return wcsicmp(_fullpath,other) op 0;} + +/** class WPathname simplifying manipulation with WPathnames, filenames, general paths, and +also supports convert from absolute path to relative respectively */ + + + +class WPathname +{ + ///object value and data + /**The implementation of WPathname creates only one buffer for all variables. It can + increase speed by effective memory use. Strings are stored one after another separated + by zero byte. Evry time any string changed, implementation recalculate buffer usage, and + decide, whether it should resize buffer or not. + + _fullpath also points to string contain full path with filename, + it is dominant value of the class + */ + WString _fullpath; + WString _path; /// + If name is provided, WPathname will expand it into full name with drive and folder name. + @param name optional argument to inicialize object + */ + WPathname(const wchar_t *name=NULL); + WPathname(const WString &name); + + ///Construct WPathname class + /** + @param relpath Relative path or uncomplette path or single filename with extension. + WPathname will expand this WPathname into full using absolute path provided by the second + argument. + @param abspath Absolute path used as reference to folder - the origin of relative path + provided in the first argument. + */ + WPathname(const wchar_t *relpath, const WPathname &abspath); + + ///Construct WPathname as copy of another WPathname + WPathname(const WPathname &other); + + + ///Function returns the current drive letter. + /** Before usage, ensure, that current WPathname contain drive. + In network path drive letter is missing. + In this case, result is undefined. To ensure, use HasDrive function + @return the drive letter of current path. + */ + wchar_t GetDrive() const + { + if (IsNull()) return 0; + return _path[0]; + } + + ///Static function determines, if argument contain a drive information. + /** + @param dir directory to inspect + @return true, if directory contain drive.

+ This function is independed, it don't need any WPathname variable declared. + */ + static bool HasDrive(const wchar_t *dir) + {return (dir[0]>='A' && dir[0]<='Z' || dir[0]>='a' && dir[0]<='z') && dir[1]==':';} + + ///Function determines, if current WPathname contain a drive information + /** + @return true, if current WPathname contain a drive information + */ + bool HasDrive() const + { + if (IsNull()) return false; + return HasDrive(_path); + } + + + ///Function returns current folder name + /** + if current folder name contain drive, only folder name is returned (without drive). + In other cases (relative or network drives) returns full path. + @return folder name or full path. Pointer is valid until any first change in object. + Do not invoke release function at pointer! + */ + const wchar_t *GetDirectory() const + { + if (HasDrive()) return _path.GetString()+3; + else return _path.GetString()+IsNetworkPath(); + } + + const wchar_t *GetDirectoryWithDrive() const + { + return _path; + } + + ///Function returns current filename with extension + /** + @return current filename with extension. Pointer is valid until any first change in object. + Do not invoke release function at pointer! + */ + const wchar_t *GetFilename() const + { + if (IsNull()) return NULL; + const wchar_t *blk=wcsrchr(_fullpath,'\\'); + if (blk) blk=blk+1;else blk=_fullpath; + return blk; + } + + ///Function returns current extension (with starting dot) + /** + @return current extension. Pointer is valid until any first change in object. + Do not invoke release function at pointer! + */ + const wchar_t *GetExtension() const + {return _extension;} + + ///Function returns current filename without extension (without dot) + /** + @return current filename without extension (without dot). Pointer is valid until any first change in object. + Do not invoke release function at pointer! + */ + const wchar_t *GetTitle() const + {return _filetitle;} + + ///Function changes current drive. + /**If object contain WPathname with drive, then current drive is changed and function returns. + If object contain network path, then computer name is changed to the drive name. + If object contain relative path, then whole path is replaced by path on root on drive. + @param dr new drive letter. This parameter can be set to zero. It means, that current + driver is deleted, and path is converted to relative path from root. Note: Zero c + cannot be used with network paths and relative paths, and finnaly has no effect to the object + */ + + void SetDrive(wchar_t dr); + + ///Sets new directory for object + /** if object contain a drive letter and argument dir doesn't, then current drive is remain + and only directory part is replaced. If current path is network path or relative path, + then whole path is replaced by new one. + If argument dir contain drive letter, then whole path is replaced too. + @param dir contain new WPathname. Backslash should be the last wchar_tacter in string + */ + void SetDirectory(const wchar_t *dir); + + ///Sets new filename for object. + /** + If filename contain dot, function assumes, that filename is provided with extension. + Otherwise, current extension remains untouched. + @param filename new filename for object + */ + + void SetFilename(const wchar_t *filename); + + ///Sets new extension for object. + /** + If ext doesn't starting with dot, function adds it. + @param ext new extension for object + */ + void SetExtension(const wchar_t *ext); + + ///Sets new file title + /** Function changes file title, extension remains untouched. + if title contains extension (dot inside its name), this extension doesn't change + current extension. For example, if current extension is ".cpp" and filetitle contain + "source.h", then result is "source.h.cpp" + @param title a new title for object. + */ + + void SetFileTitle(const wchar_t *title); + + ///Function returns full WPathname. + /** + @return current WPathname. Pointer is valid until any first change in object. + Do not invoke release function at pointer! + */ + + const wchar_t *GetFullPath() const + {return _fullpath;} + + ///Sets WPathname + /** Function has same effect as constructor. But it can be used + anytime during object lifetime. It simply replaces current WPathname with newer. WPathname + in argument is expanded to full WPathname, current directory is used as reference. + @param WPathname new WPathname + */ + void SetPathname(const wchar_t *pathname); + void SetPathname(const WString &pathname); + + WPathname& operator=(const wchar_t *other) + {SetPathname(other);return *this;} + + WPathname& operator=(const WString &other) + {SetPathname(other);return *this;} + + WPathname& operator=(const WPathname& other) + { + _fullpath=other._fullpath; + _path=other._path; + _filetitle=other._filetitle; + _extension=other._extension; + return *this; + } + + ///converts object to string + operator const wchar_t *() const + {return GetFullPath();} + + ///Static function to help getting filename from WPathname + /** Function finds last backslash / and return pointer to first wchar_tacter after it. + Pointer stays valid until original path is destroyed or until original path is changed + @param path WPathname to inspect as string + @return pointer to filename + */ + static const wchar_t *GetNameFromPath(const wchar_t *path); + + ///Static function to help getting extension from WPathname + /** Function finds last dot '.' in filename return pointer to it (extension with dot). + Pointer stays valid until original path is destroyed or until original path is changed + @param path WPathname to inspect as string + @return pointer to extension + */ + static const wchar_t *GetExtensionFromPath(const wchar_t *path); + + ///Function sets server name for network path + /** If current path is network path, then changes server name to newer. Otherwise + it remove drive letter, and insert server name before remain path + @param server server name without slashes + */ + void SetServerName(const wchar_t *server); + + ///Function inspects current path and returns, whether contain server name + /**@return zero, if current path is not valid network path. Nonzero if path contain + server name. Then value returned count wchar_tacters containing server name with precedent + slashes. + */ + int IsNetworkPath() const; + + ///Function converts current relative path into absolute path + /** + If current path is not relative, function do nothing. + @param ref reference to path, against which path is relative. + @return true if path has been converted, or false, if conversion is impossible + */ + bool RelativeToFull(const WPathname &ref); + + ///Function converts current absolute path into relative path + /** + If current path is not relative, function do nothing. Both paths must be on the same + drive or network computer. + + @param ref reference to path, against which path should be relative. + @return true if path has been converted, or false, if conversion is impossible + */ + bool FullToRelative(const WPathname &relativeto); + + WPathname& operator+=(const wchar_t *relativePath) + {*this=WPathname(relativePath,*this);return *this;} + + WPathname operator+(const wchar_t *relativePath) + {WPathname out(relativePath,*this);return out;} + + bool IsNull() const {return _fullpath.GetLength()==0;} + + void SetNull(); + + WPathnameCompare(<) + WPathnameCompare(>) + WPathnameCompare(==) + WPathnameCompare(>=) + WPathnameCompare(<=) + WPathnameCompare(!=) + + + ///Function gets part of WPathname + /** + @param path subject of examine + @param partnum zero-base index of part of WPathname. Index 0 mostly contain drive or server, in case of + relative path, there is the name of the first folder or dots. + @param buff buffer for store result + @param bufsize count wchar_tacters in buffer; + @param mode mode=0, gets only name of part. + mode=1, get current part and remain parts of path. + mode=-1, gets all parts till current + @return Function returns true, if it was succesful, and it was not last part. Function returns + false, if it was succesful, and it was last part. Function returns false and sets buffer empty, + if an error occured. Function returns true and sets buffer empty, if buffer is too small to hold data + */ + static bool GetPartFromPath(const wchar_t *path, int partnum, wchar_t *buff, int bufsize, int mode=0); + + ///Function gets part of object + /** + @param partnum zero-base index of part of WPathname. Index 0 mostly contain drive or server, in case of + relative path, there is the name of the first folder or dots. + @param buff buffer for store result + @param bufsize count wchar_tacters in buffer; + @param mode mode=0, gets only name of part. + mode=1, get current part and remain parts of path. + mode=-1, gets all parts till current + @return Function returns true, if it was succesful, and it was not last part. Function returns + false, if it was succesful, and it was last part. Function returns false and sets buffer empty, + if an error occured. Function returns true and sets buffer empty, if buffer is too small to hold data + */ + bool GetPart(int partnum, wchar_t *buff, int bufsize,int mode=0) const + { + return GetPartFromPath(this->_fullpath,partnum,buff,bufsize,mode); + } + + /// Get Directory With Drive Without Last Back Slash + /** Retrieves into buffer directory with drive and removes last backslash + @param buff buffer that retrieves path + @param size size of buffer + @return true, if success, failed if buffer is too small*/ + + + bool GetDirectoryWithDriveWLBS(wchar_t *buff, size_t size) const; + + WString GetDirectoryWithDriveWLBS() const; + + + /// function checks, if path is valid and returns true, if does. + bool IsPathValid() const; + + /// Sets special directory. + /** + @param bSpecCode this value may be operation-system + depend. Windows implementation using CSIDL_XXXX constants, which is described in SHGetSpecialFolderLocation function + description + @return true, if function were successful + */ + bool SetDirectorySpecial(int nSpecCode); + + ///Sets temporaly directory. + bool SetTempDirectory(); + + ///Guess temporaly file name + /** + @param prefix prefix string for name + @param unique if unique is non-zero, it is used for new temporaly file. If unique is zero, function guess own unique + value. + @return true if function were successful + */ + bool SetTempFile(const wchar_t *prefix=L"tmp", unsigned int unique=NULL); + + ///Returns path of current executable. + /**It useful, when accessing folder, from when current module has been executed */ + static WPathname GetExePath(); + + ///Solves most used conversion from fullpath to path relative to project root + /** + @param full full WPathname with drive + @param projectRoot project root path + @return function returns pointer to full path, where starts relative part. If + fullpath doesn't contain project root path, it returns pointer to full. + @example FullToProjectRoot("x:\\project\\data\\example.txt","x:\\project"); //result is "data\\example.txt" + */ + + static const wchar_t *FullToRelativeProjectRoot(const wchar_t *full, const wchar_t *projectRoot); + + +protected: + ///Function only rebuild _fullpath string. + /** It doesn't check space for string! This function is used, when length of path is excepted + the same or smaller, then current. + */ + void RebuildPath(); + + +}; + + + +#endif // !defined(AFX_WPathname_H__158F59D5_B422_4FA6_86AC_10B5EC48C81B__INCLUDED_) diff --git a/DDLReader/Projects/Skeldal/DDLReader/WString.cpp b/DDLReader/Projects/Skeldal/DDLReader/WString.cpp new file mode 100644 index 0000000..a7e61e7 --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/WString.cpp @@ -0,0 +1,193 @@ +// WString.cpp: implementation of the WString class. +// +////////////////////////////////////////////////////////////////////// + +#include "WString.h" +#include +#include + + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +WString::WString(const char *sbstring, unsigned int codePage) +{ + if (sbstring==NULL || *sbstring==0) + { + _ref=NULL; + } + else + { + size_t reqBuff=MultiByteToWideChar(codePage,0,sbstring,-1,NULL,0); + + _ref=WStringMemory::AllocString(NULL,reqBuff); + _ref->AddRef(); + wchar_t *str=const_cast(_ref->GetStringFromMemBlock()); + + MultiByteToWideChar(codePage,0,sbstring,-1,str,reqBuff); + } +} + +int WString::FormatV(wchar_t *format, va_list lst) +{ + size_t curSize=4096; + int written; + do + { + _ref=WStringMemory::AllocString(NULL,curSize); + wchar_t *str=const_cast(_ref->GetStringFromMemBlock()); + written=_vsnwprintf(str,curSize,format,lst); + if (written<0) + { + curSize*=2; + WStringMemory::FreeProxy(_ref); + } + } + while (written<-1); + _ref->RecalcLength(); + _ref->AddRef(); + return written; +} + +int WString::Format(wchar_t *format, ...) +{ + va_list valst; + va_start(valst,format); + return FormatV(format,valst); +} + + +int WString::ScanStringV(const wchar_t *format, va_list lst) const +{ + unsigned long *ptr=(unsigned long *)lst; + return swscanf(GetString(),format,ptr[0],ptr[1],ptr[2],ptr[3],ptr[4],ptr[5],ptr[6],ptr[7],ptr[8],ptr[9], + ptr[10],ptr[11],ptr[12],ptr[13],ptr[14],ptr[15],ptr[16],ptr[17],ptr[18],ptr[19]); + +} + +int WString::ScanString(const wchar_t *format, ...) const +{ + va_list valst; + va_start(valst,format); + return ScanStringV(format,valst); +} + +bool WString::ReplaceOnce(const WString &findWhat,const WString &replaceWith) +{ + int pos=Find(findWhat); + if (pos==-1) return false; + (*this)=Left(pos)+replaceWith+Right(pos+replaceWith.GetLength()); + return true; +} + +bool WString::ReplaceAll(const WString &findWhat,const WString &replaceWith) +{ + WString process=*this; + WString result; + int pos; + bool processed=false; + while ((pos=process.Find(findWhat))!=-1) + { + result=result+process.Left(pos)+replaceWith; + process=process.Right(pos+findWhat.GetLength()); + processed=true; + } + *this=result+process; + return processed; +} + +WString WString::TrimLeft() const +{ + return TrimLeft(L" \r\n\t"); +} + +WString WString::TrimRight() const +{ + return TrimRight(L" \r\n\t"); +} + +WString WString::TrimLeft(wchar_t *trimChars) const +{ + const wchar_t *proStr=GetString(); + int p=0; + while (proStr[p] && wcschr(trimChars,proStr[p]!=NULL)) p++; + return Right(p); +} + +WString WString::TrimRight(wchar_t *trimChars) const +{ + const wchar_t *proStr=GetString(); + int p=GetLength()-1; + while (p>=0 && wcschr(trimChars,proStr[p]!=NULL)) p--; + return Left(p+1); +} + +WString WString::Upper() const +{ + return WString(WStringMemory::AllocProxy(WStringProxy(_ref,WStringProxy::EfUpper))); +} + +WString WString::Lower() const +{ + return WString(WStringMemory::AllocProxy(WStringProxy(_ref,WStringProxy::EfLower))); +} + +WString WString::Reverse() const +{ + return WString(WStringMemory::AllocProxy(WStringProxy(_ref,WStringProxy::EfReverse))); +} + +WString WString::Effect(IWStringEffect *effect) const +{ + return WString(WStringMemory::AllocProxy(WStringProxy(_ref,effect))); +} + +void WString::SetUTF7(const char *utf7) +{ + *this=WString(utf7,CP_UTF7); +} + +void WString::SetUTF8(const char *utf8) +{ + *this=WString(utf8,CP_UTF8); +} + +const char *WString::AsSBString(unsigned int codePage, WString &holder) +{ + const wchar_t *str=GetString(); + size_t reqsize=WideCharToMultiByte(codePage,0,str,-1,NULL,0,NULL,NULL); + WStringProxy *holderProxy=WStringMemory::AllocString(NULL,reqsize/2); //reqsize/2+(2 bytes) + char *mbstr=reinterpret_cast(const_cast(holderProxy->GetStringFromMemBlock())); + WideCharToMultiByte(codePage,0,str,-1,mbstr,reqsize,NULL,NULL); + holder=WString(holderProxy); + return mbstr; +} + +const char *WString::AsUTF7(WString &holder) +{ + return AsSBString(CP_UTF7,holder); +} + +const char *WString::AsUTF8(WString &holder) +{ + return AsSBString(CP_UTF8,holder); +} + +void WString::ReadFromStream(size_t (*streamReader)(wchar_t *buffer, size_t bufferLen, void *context),void *context) +{ + _ref->Release(); + _ref=NULL; + wchar_t buff[256]; + size_t rd; + while ((rd=streamReader(buff,sizeof(buff)/sizeof(wchar_t),context))!=0) + { + *this=*this+WString(buff,rd); + } +} + +const WString WStringConst(const wchar_t *text) +{ + return WString(WStringMemory::AllocProxy(WStringProxy(text))); +} + diff --git a/DDLReader/Projects/Skeldal/DDLReader/WString.h b/DDLReader/Projects/Skeldal/DDLReader/WString.h new file mode 100644 index 0000000..a244adb --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/WString.h @@ -0,0 +1,496 @@ +// WString.h: interface for the WString class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_WSTRING_H__481164FB_3BB7_4824_B0E3_8B371F0AAF3A__INCLUDED_) +#define AFX_WSTRING_H__481164FB_3BB7_4824_B0E3_8B371F0AAF3A__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "WStringProxy.h" +#include + +class WString +{ + mutable WStringProxy *_ref; + + + +public: + ///constructs empty string + WString():_ref(0) {} + + ///constructs string. + explicit WString(const wchar_t *string):_ref(string==NULL?NULL:WStringMemory::AllocString(string,0)) {_ref->AddRef();}; + + ///constructs string from wide-char array with specified length + WString(const wchar_t *string, size_t sz):_ref(WStringMemory::AllocString(string,sz)) {_ref->AddRef();}; + + ///copy constructor + /**constructor doesn't copy the string, only reference. + String is shared until it is changed + */ + WString(const WString &other):_ref(other._ref) {_ref->AddRef();} + + ///constructs string from multi-byte string. codePage specified code page of string + WString(const char *sbstring, unsigned int codePage); + + ///constructs string from string-proxy. Used internally with WStringMemory::AllocXXX functions + WString(WStringProxy *proxy):_ref(proxy) {_ref->AddRef();} + + ///assignment operator + /** assignment operator doesn't copy the string only reference. + String is shared until it is changed */ + WString &operator=(const WString &other) + {other._ref->AddRef();_ref->Release();_ref=other._ref;return *this;} + + ///Destructor - releases reference + ~WString() {_ref->Release();} + + ///function converts instance of WString to wchar_t pointer + /** + Function will perform RenderString, if it is needed. + */ + const wchar_t *GetString() const + { + if (_ref==NULL) return L""; + WStringProxy *str=_ref->RenderString(); + if (_ref!=str) + { + str->AddRef();_ref->Release();_ref=str; + } + return _ref->GetStringFromMemBlock(); + } + + ///operator can convert WString to wchar_t pointer anytime + operator const wchar_t *() const {return GetString();} + + ///function returns count of characters in string + /** function doesn't need to render string, so it can be called anytime + without loosing the benefit of "pseudo-strings" boosting */ + size_t GetLength() const + { + if (_ref) return _ref->GetLength(); + else return 0; + } + + ///function creates string as sum of this and another string + /** function creates "pseudo-string" that represents sum of two string. + pseudo-string is rendered to "real-string" automatically, when it is needed */ + WString operator+(const WString other) const + { + if (_ref==NULL) return other; + if (other._ref==NULL) return *this; + return WString(WStringMemory::AllocProxy(WStringProxy(_ref,other._ref))); + } + + WString &operator+=(const WString other) + { + *this=*this+other; + return *this; + } + + ///function creates string as substring of another string + /** function creates "pseudo-string" that represents substring of anothers string. + Pseudo-string is rendered to "real-string" automatically, when it is needed */ + WString Mid(size_t begin, size_t len) const + { + if (begin==0) return Left(len); + if (_ref==NULL || begin>GetLength()) return WString(); + if (begin+len>GetLength()) return Right(begin); + return WString(WStringMemory::AllocProxy(WStringProxy(_ref,begin,len))); + } + + WString Left(size_t len) const + { + if (_ref==NULL) return WString(); + if (len>=GetLength()) return *this; + return WString(WStringMemory::AllocProxy(WStringProxy(_ref,0,len))); + } + + WString Right(size_t begin) const + { + if (_ref==NULL || begin>GetLength()) return WString(); + if (begin==0) return *this; + return WString(WStringMemory::AllocProxy(WStringProxy(_ref,begin,GetLength()-begin))); + } + + WString RightR(size_t count) const + { + if (_ref==NULL || count==0) return WString(); + if (count>=GetLength()) return *this; + return WString(WStringMemory::AllocProxy(WStringProxy(_ref,GetLength()-count,count))); + } + + WString Delete(size_t begin, size_t count) const + { + if (_ref==NULL) return WString(); + if (begin==0) return Right(count); + if (begin+count>=GetLength()) return Left(begin); + return WString(WStringMemory::AllocProxy(WStringProxy(Left(begin)._ref,Right(begin+count)._ref))); + } + + WString Insert(const WString &what, size_t index) const + { + if (_ref==NULL) return what; + if (index==0) return what+*this; + if (index>=GetLength()) return *this+what; + return Left(index)+what+Right(index); + } + + /// function allows to access any char in string + wchar_t operator[](int index) const + { + assert(index<=(int)GetLength() && index>=0); + return GetString()[index]; + } + + /// functions allows lock string for accesing it directly. + /** Function returns pointer to buffer which holds string. + Buffer size is equal to string length plus terminating zero. + Application can modify content of buffer. + If string is shared with another WString object, LockBuffer + creates copy of string + Do not forger to call UnlockBuffer, when you finish modifiing the content + */ + wchar_t *LockBuffer() + { + if (_ref==NULL) return NULL; + GetString(); + WStringMemory::LockProxy(_ref); + if (_ref->IsShared()) + { + WStringMemory::UnlockProxy(_ref); + _ref->Release(); + _ref=WStringMemory::AllocString(_ref->GetStringFromMemBlock(),0); + _ref->AddRef(); + WStringMemory::LockProxy(_ref); + } + return const_cast(_ref->GetStringFromMemBlock()); + } + + /// Function creates buffer for string and returns its address + /** Application can use buffer in functions, that cannot work with + WString objects. Size of buffer is specified by sz value, and it is in characters. + Application must call UnlockBuffer after writes all data into buffer. + + NOTE: Prevoius content of string is lost. + NOTE: sz specifies buffer size without terminating zero character + */ + wchar_t *CreateBuffer(size_t sz) + { + _ref->Release(); + _ref=WStringMemory::AllocString(NULL,sz); + _ref->AddRef(); + WStringMemory::LockProxy(_ref); + return const_cast(_ref->GetStringFromMemBlock()); + } + + /// Function creates buffer, and copies string into it. + /** Parameter sz specifies size of new buffer in characters + When sz is smaller then size of string, string is truncated + When sz is larger then size of string, string is copied unchanged, + but extra characters can be appended. + + NOTE: sz specifies buffer size without terminating zero character + */ + wchar_t *CreateBufferCopy(size_t sz) + { + WString save=*this; + wchar_t *wbuff=CreateBuffer(sz); + int minsz=__min(sz,save.GetLength()); + wcsncpy(wbuff,save.GetString(),minsz); + return wbuff; + } + + /// Function unlocks internal buffer + /** parameter sz specifies final lenght of string in buffer. Default + value -1 forces function calc size by own + */ + void UnlockBuffer(int sz=-1) + { + if (_ref==NULL) return; + wchar_t *wbuff=const_cast(_ref->GetStringFromMemBlock()); + if (sz<0) sz=wcslen(wbuff); + else wbuff[sz]=0; + if (sz!=(signed)_ref->GetLength()) + { + _ref->RecalcLength(); + WStringMemory::UnlockProxy(_ref); + } + } + + class WStringAtCharHelper + { + WString &_str; + size_t _index; + public: + WStringAtCharHelper(WString &str,size_t index):_str(str),_index(index) {} + WString &operator=(wchar_t z) + { + wchar_t *buff=_str.LockBuffer(); + assert(buff && _index<_str.GetLength()); + buff[_index]=z; + _str.UnlockBuffer(); + return _str; + } + operator wchar_t() + { + assert(_index<_str.GetLength()); + return ((const wchar_t *)_str)[_index]; + } + }; + + /// Function will return helper object, which can access single character in string + /** + Using array operator is slower than accessing characters by LockBuffer function + */ + WStringAtCharHelper operator[](int index) + { + return WStringAtCharHelper(*this,index); + } + + int Find(wchar_t z,size_t from=0) const + { + if (from>=GetLength()) return -1; + const wchar_t *res=wcschr(GetString()+from,z); + if (res) return res-GetString(); + else return -1; + } + + int FindLast(wchar_t z) const + { + const wchar_t *res=wcsrchr(GetString(),z); + if (res) return res-GetString(); + else return -1; + } + + int Find(const wchar_t *z,size_t from=0) const + { + if (z==NULL) return -1; + if (from>=GetLength()) return -1; + const wchar_t *res=wcsstr(GetString()+from,z); + if (res) return res-GetString(); + else return -1; + } + + int FormatV(wchar_t *format, va_list lst); + + int Format(wchar_t *format, ...); + + ///Scans string for format + /** function is limited, item count is limited up to 20 items */ + int ScanStringV(const wchar_t *format, va_list lst) const; + + ///Scans string for format + /** function is limited, item count is limited up to 20 items */ + int ScanString(const wchar_t *format, ...) const; + + bool ReplaceOnce(const WString &findWhat,const WString &replaceWith); + + bool ReplaceAll(const WString &findWhat,const WString &replaceWith); + + WString TrimLeft() const; + + WString TrimRight() const; + + WString TrimLeft(wchar_t *trimChars) const; + + WString TrimRight(wchar_t *trimChars) const; + + ///Function splits string into two + /** Left part of string is returned. + Right part of string is leaved in object + @param splitPos split position. + @return if splitPos==0, function returns empty string. if splitPos>=length, function + moves string from object to result*/ + WString Split(size_t splitPos) + { + WString result=Left(splitPos); + *this=Right(splitPos); + return result; + } + + bool IsEmpty() const {return _ref==NULL;} + + void Empty() const {_ref->Release();_ref=NULL;} + + int Compare(const wchar_t *other) const + { + return wcscmp(*this,other); + } + + bool operator>(const WString &other) const {return Compare(other)>0;} + bool operator<(const WString &other) const {return Compare(other)<0;} + bool operator>=(const WString &other) const {return Compare(other)>=0;} + bool operator<=(const WString &other) const {return Compare(other)<=0;} + bool operator!=(const WString &other) const {return Compare(other)<=0;} + bool operator==(const WString &other) const {return Compare(other)<=0;} + + WString Upper() const; + WString Lower() const; + WString Reverse() const; + + ///Applies user effect on string + /** pointer should be static allocated object, or must be valid during lifetime of resulting string */ + WString Effect(IWStringEffect *effect) const; + + void SetUTF7(const char *utf7); + void SetUTF8(const char *utf8); + + ///Function converts string to SingleByte string + /** + @param codePage Platform depends code page of result + @param holder Object that holds result. Result pointer is valid during lifetime of holder. Once holder + released, pointer is invalidated. You can get resulting pointer anytime from holder reintepreting + wchar_t to char + @result pointer to string + */ + const char *AsSBString(unsigned int codePage, WString &holder); + + ///Returns multibyte string in UTF7 codepage + /**See AsSBString description*/ + const char *AsUTF7(WString &holder); + + ///Returns multibyte string in UTF7 codepage + /**See AsSBString description*/ + const char *AsUTF8(WString &holder); + + + ///Function reads string from stream + /** + Function calls streamReader repeatly until function returns zero. In each call, streamReader returns + number of characters, that has been readed. + @param sreamReader pointer to function which provides reading from a stream + @param context user defined context pointer (most in cases, pointer to stream is passed) + @param buffer space allocated for data readed from stream + @param bufferLen maximum count of characters can be written to buffer + @return streamReader returns number of characters, that has been written to buffer. Function must return zero + to stop reading + */ + void ReadFromStream(size_t (*streamReader)(wchar_t *buffer, size_t bufferLen, void *context),void *context); + + WString operator() (int from) const {return from<0?RightR(-from):Right(from);} + WString operator() (int from, int to) const + { + if (from>=0) + return to<0?Mid(from,-to):Mid(from,to-from); + else + return to<0?Mid(GetLength()+from,-to):Mid(GetLength()+from,GetLength()-from-to); + } + + ///Enables global string sharing. + /** Function Share allows share strings that contains same text. It can reduce memory + usage. Function is useful when there is many objects that contains string with same text. + + Basically, two strings is shared, if one string is created as copy of another string. Strings + is sharing they content, until one of them is modified. + + Calling Share function, string is registered for global sharing. If string with same content is already + registered, then content of current string is released, and string is shared. + + To successfully share two strings, both strings must call Share() function. Sharing is provided until one + of strings is modified. After modifications are done, Share function of modified string must be called again. + + Remember: Global sharing can reduce amount of memory, if there are multiple strings that containging + the same content. But sharing of each unique string takes small piece of memory to store sharing + informations. + + To share string automatically, use WSharedString class + WSC strings cannot be shared! + */ + void Share() const + { + WStringProxy *curref=_ref; + GetString(); + _ref=WStringMemory::ShareString(curref); + _ref->AddRef(); + curref->Release(); + } + + ///Disables global string sharing + /** Function unregisters string from global sharing database. If string is shared, function doesn't break + it. But all strings that currently sharing content will not be shared with newly created strings. + */ + void Unshare() + { + WStringMemory::UnshareString(_ref); + } +}; + +///Function will create constant WString +/** function will not copy content of string. Only creates reference to string + Using WStringConst is faster for strings in code +@exmple result=a+WStringConst(L"text")+b; +*/ +const WString WStringConst(const wchar_t *text); + +///Macro to easy convert incode string to WString +/** +function also marks text wide. +@example WString text=WSC("Hello world"); +*/ +#define WSC(x) WStringConst(L##x) +///Macro to easy convert any wchar_t buffer to constant WString +/** +IMPORTANT NOTE!: Buffer must exists until string is rendered. +If you are using WSCB in function, don't forget call GetString before function exits +If you are excepting additional string operations outside function, using standard +WString conversion can be more effecient. +*/ +#define WSCB(x) WStringConst(x) + + + +class WSharedString: public WString +{ +public: + WSharedString() {} + + ///constructs string. + explicit WSharedString(const wchar_t *string):WString(string) {Share();} + + ///constructs string from wide-char array with specified length + WSharedString(const wchar_t *string, size_t sz):WString(string,sz) {Share();}; + + ///copy constructor + /**constructor doesn't copy the string, only reference. + String is shared until it is changed + */ + WSharedString(const WSharedString &other):WString(other) {} + WSharedString(const WString &other):WString(other) {Share();} + + ///constructs string from multi-byte string. codePage specified code page of string + WSharedString(const char *sbstring, unsigned int codePage):WString(sbstring,codePage) {Share();} + + ///assignment operator + /** assignment operator doesn't copy the string only reference. + String is shared until it is changed */ + WSharedString &operator=(const WString &other) + {WString::operator =(other);Share();return *this;} + + const wchar_t *GetString() const + { + const wchar_t *res=WString::GetString(); + Share(); + return res; + } + operator const wchar_t *() const {return GetString();} + wchar_t operator[](int index) const + { + assert(index<=(int)GetLength() && index>=0); + return GetString()[index]; + } + + void UnlockBuffer(int sz=-1) + { + WString::UnlockBuffer(sz); + Share(); + } + +}; + + +#endif // !defined(AFX_WSTRING_H__481164FB_3BB7_4824_B0E3_8B371F0AAF3A__INCLUDED_) diff --git a/DDLReader/Projects/Skeldal/DDLReader/WStringMemory.cpp b/DDLReader/Projects/Skeldal/DDLReader/WStringMemory.cpp new file mode 100644 index 0000000..947ed02 --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/WStringMemory.cpp @@ -0,0 +1,397 @@ +// WStringMemorySingleThread.cpp: implementation of the WStringMemory class. +// +////////////////////////////////////////////////////////////////////// + +#include +#include +#include "WStringMemory.h" +#include "WStringProxy.h" +#include +#include +#include + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +#ifdef _MT //multithreading +#define WSTRING_MT +#endif + +#ifdef WSTRING_MT //multithreading + + +struct WStringMTLock +{ + WStringProxy *_lockProxy; + LONG _recursionCount; + DWORD _owner; + HANDLE _event; + WStringMTLock(WStringProxy *x):_lockProxy(x) {} + WStringMTLock():_lockProxy(NULL) {} + + bool operator==(const WStringMTLock &other) const {return _lockProxy==other._lockProxy;} + bool operator!=(const WStringMTLock &other) const {return _lockProxy!=other._lockProxy;} + bool operator>=(const WStringMTLock &other) const {return _lockProxy>=other._lockProxy;} + bool operator<=(const WStringMTLock &other) const {return _lockProxy<=other._lockProxy;} + bool operator>(const WStringMTLock &other) const {return _lockProxy>other._lockProxy;} + bool operator<(const WStringMTLock &other) const {return _lockProxy *GLockDB=NULL; //Lock proxy database + +static void exitMT() +{ + DeleteCriticalSection(&GLocker); +} + + +static void OnStartup() +{ + InitializeCriticalSection(&GLocker); + atexit(exitMT); +} + +#define ON_STARTUP_PRIORITY_NORMAL OnStartup +#include + +#endif + + + +#define WS_MAXFREELISTS 32 +#define WS_FREELISTSTEP 32 +#define WS_TOTALMAXFREEKBYTES 256 + +#define WS_MAXIMUMFASTALLOC (WS_MAXFREELISTS*WS_FREELISTSTEP) + +#define WS_MAXFREEBYTES PerSlotMaxAlloc + + +static size_t PerSlotMaxAlloc=(WS_TOTALMAXFREEKBYTES*1024/WS_MAXFREELISTS); +static WStringProxy *FreeList=NULL; +static void **StringFreeList[WS_MAXFREELISTS]; +static size_t StringFreeBytes[WS_MAXFREELISTS]; +static bool InitManager=true; + + +static void InitManagerPointers() +{ + memset(StringFreeList,0,sizeof(StringFreeList)); + memset(StringFreeBytes,0,sizeof(StringFreeBytes)); + InitManager=false; +} + +static void *AllocStringBlock(size_t sz) +{ + if (InitManager) InitManagerPointers(); + if (sz>WS_MAXIMUMFASTALLOC) return malloc(sz); + int pos=(sz+WS_FREELISTSTEP-1)/WS_FREELISTSTEP; + void **nxt=StringFreeList[pos]; + if (nxt==0) + { + printf("malloc %d\n",pos*WS_FREELISTSTEP); + return malloc(pos*WS_FREELISTSTEP); + } + printf("fast_alloc %d\n",pos*WS_FREELISTSTEP); + StringFreeList[pos]=(void **)(*nxt); + StringFreeBytes[pos]-=_msize(nxt); + return nxt; +} + +static void DeallocStringBlock(void *ptr) +{ + size_t sz=_msize(ptr); + if (sz>WS_MAXIMUMFASTALLOC) {free(ptr);return;} + int pos=(sz+WS_FREELISTSTEP-1)/WS_FREELISTSTEP; + if (sz+StringFreeBytes[pos]>WS_MAXFREEBYTES) + { + printf("free %d\n",sz); + free(ptr);return; + } + void **proxy=(void **)ptr; + *proxy=(void *)StringFreeList[pos]; + StringFreeList[pos]=proxy; + StringFreeBytes[pos]+=sz; + printf("fast_free %d\n",sz); +} + + +static inline void *operator new(size_t alloc,size_t sz) +{ + return AllocStringBlock(sz+alloc); +} + +static inline void operator delete(void *p,size_t alloc) +{ + DeallocStringBlock(p); +} + +static inline void *operator new(size_t sz,void *ptr) +{ + return ptr; +} + +static inline void operator delete(void *ptr,void *p) +{ +} + +WStringProxy * WStringMemory::AllocString(const wchar_t *text, size_t size) +{ +#ifdef WSTRING_MT + EnterCriticalSection(&GLocker); +#endif + assert(size!=0 || text!=0); + if (size==0) size=wcslen(text); + WStringProxy *proxy=new((size+1)*sizeof(wchar_t)) WStringProxy(size,0,0); + wchar_t *alloctext=const_cast(proxy->GetStringFromMemBlock()); + if (text) wcsncpy(alloctext,text,size); + alloctext[size]=0; + if (proxy->_redirect==0) + { + proxy->_redirect=alloctext; + proxy->_blockData2=1; + } +#ifdef WSTRING_MT + LeaveCriticalSection(&GLocker); +#endif + return proxy; +} + +WStringProxy * WStringMemory::AllocProxy(const WStringProxy &templateProxy) +{ + WStringProxy * res; +#ifdef WSTRING_MT + EnterCriticalSection(&GLocker); +#endif + if (FreeList==NULL) res=new WStringProxy(templateProxy); + else + { + WStringProxy *alloc=FreeList; + FreeList=alloc->_baseString; + res=new((void *)alloc) WStringProxy(templateProxy); + } +#ifdef WSTRING_MT + LeaveCriticalSection(&GLocker); +#endif + return res; +} + +void WStringMemory::FreeProxy(WStringProxy *proxy) +{ +#ifdef WSTRING_MT + EnterCriticalSection(&GLocker); +#endif + if (proxy->_operation==proxy->OpMemBlck && !(proxy->_blockData2==0 && proxy->_redirect!=NULL)) + { + if (proxy->_blockData2==2) UnshareString(proxy); + DeallocStringBlock(proxy); + } + else + { + proxy->~WStringProxy(); + proxy->_baseString=FreeList; + FreeList=proxy; + } +#ifdef WSTRING_MT + LeaveCriticalSection(&GLocker); +#endif +} + +#ifdef WSTRING_MT + +void WStringMemory::LockProxy( WStringProxy *proxy) +{ +nextTry: + EnterCriticalSection(&GLocker); + WStringMTLock srch(proxy),*found; + if (GLockDB==NULL) GLockDB=new BTree(16); + found=GLockDB->Find(srch); + if (found==NULL) + { + srch._event=NULL; + srch._owner=GetCurrentThreadId(); + srch._recursionCount=1; + GLockDB->Add(srch); + } + else + { + if (found->_owner!=GetCurrentThreadId()) + { + HANDLE w=found->_event; + if (w==0) {w=found->_event=CreateEvent(NULL,TRUE,FALSE,NULL);} + LeaveCriticalSection(&GLocker); //leave section + WaitForSingleObject(w,INFINITE); + goto nextTry; + } + else + { + found->_recursionCount++; + } + } + LeaveCriticalSection(&GLocker); //leave section +} + +void WStringMemory::UnlockProxy( WStringProxy *proxy) +{ + EnterCriticalSection(&GLocker); + WStringMTLock srch(proxy),*found; + found=GLockDB->Find(srch); + if (found) + { + if (--found->_recursionCount==0) + { + if (found->_event!=NULL) + { + SetEvent(found->_event); + CloseHandle(found->_event); + } + GLockDB->Remove(*found); + } + } + LeaveCriticalSection(&GLocker); +} + + +void WStringMemory::AddRefProxy(WStringProxy *proxy) +{ + InterlockedIncrement(reinterpret_cast(&proxy->_refCount)); +} + +bool WStringMemory::ReleaseRefProxy(WStringProxy *proxy) +{ + LONG res=InterlockedDecrement(reinterpret_cast(&proxy->_refCount)); + if (res<0) res=InterlockedIncrement(reinterpret_cast(&proxy->_refCount)); + return res==0; +} + +#else +void WStringMemory::LockProxy( WStringProxy *proxy) +{ + //not needed in single thread environment +} + +void WStringMemory::UnlockProxy( WStringProxy *proxy) +{ + //not needed in single thread environment +} + + +void WStringMemory::AddRefProxy(WStringProxy *proxy) +{ + //no special handling in single thread environment + ++proxy->_refCount; +} + +bool WStringMemory::ReleaseRefProxy(WStringProxy *proxy) +{ + //no special handling in single thread environment + if (proxy->_refCount) --proxy->_refCount; + return proxy->_refCount==0; +} + +#endif +void WStringMemory::FreeExtra() +{ +#ifdef WSTRING_MT + EnterCriticalSection(&GLocker); +#endif + while (FreeList) + { + void *proxy=FreeList; + FreeList=FreeList->_baseString; + free(proxy); + } + for (int i=0;i_redirect,other._str->_redirect); + } + + bool operator==(const ShareDBItem& other) const {return Compare(other)==0;} + bool operator>=(const ShareDBItem& other) const {return Compare(other)>=0;} + bool operator<=(const ShareDBItem& other) const {return Compare(other)<=0;} + bool operator!=(const ShareDBItem& other) const {return Compare(other)!=0;} + bool operator>(const ShareDBItem& other) const {return Compare(other)>0;} + bool operator<(const ShareDBItem& other) const {return Compare(other)<0;} +}; + +static BTree *GDB=NULL; + +WStringProxy *WStringMemory::ShareString(WStringProxy *proxy) +{ + if (proxy->_operation!=WStringProxy::OpMemBlck || proxy->_blockData2==0 || proxy->_blockData2==2) return proxy; + +#ifdef WSTRING_MT + EnterCriticalSection(&GLocker); +#endif + + if (GDB==NULL) GDB=new BTree; + + proxy->_blockData2=2; //block is subject of sharing + proxy->_redirect=proxy->GetStringFromMemBlock(); //setup pointer to string + ShareDBItem *found=GDB->Find(ShareDBItem(proxy)); + if (found) {proxy->_blockData2=1;proxy=found->_str;} + else GDB->Add(ShareDBItem(proxy)); +#ifdef WSTRING_MT + LeaveCriticalSection(&GLocker); +#endif + return proxy; +} + +void WStringMemory::UnshareString(WStringProxy *proxy) +{ + if (proxy->_operation!=WStringProxy::OpMemBlck || proxy->_blockData2!=2) return; + if (GDB==NULL) return; +#ifdef WSTRING_MT + EnterCriticalSection(&GLocker); +#endif + GDB->Remove(ShareDBItem(proxy)); + proxy->_blockData2=1; +#ifdef WSTRING_MT + LeaveCriticalSection(&GLocker); +#endif +} \ No newline at end of file diff --git a/DDLReader/Projects/Skeldal/DDLReader/WStringMemory.h b/DDLReader/Projects/Skeldal/DDLReader/WStringMemory.h new file mode 100644 index 0000000..a81b08e --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/WStringMemory.h @@ -0,0 +1,61 @@ +// WStringMemory.h: interface for the WStringMemory class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_WSTRINGMEMORY_H__79693029_4788_4099_9A97_92AF310A7AD5__INCLUDED_) +#define AFX_WSTRINGMEMORY_H__79693029_4788_4099_9A97_92AF310A7AD5__INCLUDED_ + +#include + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +class WStringProxy; + +class WStringMemory +{ +public: + + static WStringProxy * AllocString(const wchar_t *text, size_t size); + static WStringProxy * AllocProxy(const WStringProxy &templateProxy); + static void FreeProxy(WStringProxy *proxy); + static void LockProxy(WStringProxy *proxy); + static void UnlockProxy(WStringProxy *proxy); + + //Releases extra memory leaved for future fast allocations + static void FreeExtra(); + + //Support addref for proxy - Single- or Multi- thread support + static void AddRefProxy(WStringProxy *proxy); + + //Support addref for proxy - Single- or Multi- thread support + //returns true, when counter reached zero + static bool ReleaseRefProxy(WStringProxy *proxy); + + ///Gets statistics about memory manager + /** + @param details optional pointer to 32 size_t items. Array will be filled + with sizes of each string fastalloc group. + @return function returns total bytes allocated for string fast allocation. + (This number should be below 256KB) + */ + static size_t GetStatistics(size_t *details=NULL); + + ///Function allows sharing the strings + /** This function is called by WString::Share function + Function mark proxy shared. If string is same as shared, + it returns pointer to proxy with proxy of string that contains + the same text. + Read description of WString::Share for more informations + */ + static WStringProxy *ShareString(WStringProxy *proxy); + + ///Function disables sharing of the string + static void UnshareString(WStringProxy *proxy); + +}; + + + +#endif // !defined(AFX_WSTRINGMEMORY_H__79693029_4788_4099_9A97_92AF310A7AD5__INCLUDED_) diff --git a/DDLReader/Projects/Skeldal/DDLReader/WStringProxy.cpp b/DDLReader/Projects/Skeldal/DDLReader/WStringProxy.cpp new file mode 100644 index 0000000..6b93900 --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/WStringProxy.cpp @@ -0,0 +1,185 @@ +// WStringProxy.cpp: implementation of the WStringProxy class. +// +////////////////////////////////////////////////////////////////////// + + +#include "WStringProxy.h" + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +/** Funkce vytvo transitivn uzvr. +to znamen, e zru vechny zetzen redirecty. +*/ +WStringProxy *WStringProxy::TransitivniUzaver() +{ + if (_operation==OpSubstr && _offset==0 && _stringSize==_baseString->GetLength()) + { + WStringProxy *next=_baseString->TransitivniUzaver(); + if (next==NULL) return this; + next->AddRef(); + _baseString->Release(); + _baseString=next; + return next; + } + return NULL; +} + +/** Main render procedure +It creates allocates buffer proxy and renders tree into it +Then turns self into redirect proxy a redirect self into newly created string +Rerurns pointer to newly created proxy +*/ +WStringProxy *WStringProxy::RenderString() +{ + if (_operation==OpMemBlck) return this; + + WStringProxy *pp=TransitivniUzaver(); + if (pp!=NULL) return pp->_baseString->RenderString(); + + WStringProxy *newProxy=WStringMemory::AllocString(NULL,_stringSize); + wchar_t *renderPtr=const_cast(newProxy->GetStringFromMemBlock()); + + RenderStringToBuffer(renderPtr); + + newProxy->AddRef(); + this->~WStringProxy(); + _operation=OpSubstr; + _offset=0; + _baseString=newProxy; + + return newProxy; +} + +/** Function renders simple effect into buffer +Function needs buffer with nul terminated string +*/ +void WStringProxy::RenderSimpleEffect(wchar_t *renderPtr) +{ + assert(_operation==OpEffect); + switch (_effect) + { + case EfLower: wcslwr(renderPtr);break; + case EfUpper: wcsupr(renderPtr);break; + case EfReverse: wcsrev(renderPtr);break; + } + +} + +/** Light phase of rendering. Used to render string that is not +created from substring. This part is optimized for concat and user effects +When substring must be rendered, function call RenderStringToBufferSubstr to +render substring. +*/ +void WStringProxy::RenderStringToBuffer(wchar_t *renderPtr) +{ + WStringMemory::LockProxy(this); + switch (_operation) + { + case OpConcat: + _baseString->RenderStringToBuffer(renderPtr); + _secondString->RenderStringToBuffer(renderPtr+_baseString->GetLength()); + break; + case OpSubstr: + { + _baseString->RenderStringToBufferSubstr(renderPtr,_offset,GetLength()); + } + break; + case OpMemBlck: + { + const wchar_t *str=GetStringFromMemBlock(); + wcsncpy(renderPtr,str,_stringSize); + } + break; + case OpEffect: + { + unsigned long offset=0; + renderPtr[_stringSize]=0; //we can append zero, because right side of string is not yet rendered + //if this is end of string, one extra character for zero is also allocated. + //efect functions can rely on it. + if (_blockData2>=256) offset=_userEffect->PreRenderString(renderPtr,_baseString->GetLength()); //call prerender to prepare begin of buffer + _baseString->RenderStringToBuffer(renderPtr+offset); //render string to rest of buffer + if (_blockData2>=256) _userEffect->RenderString(renderPtr,_baseString->GetLength()); //apply effect to buffer + else RenderSimpleEffect(renderPtr); + } + break; + }; + WStringMemory::UnlockProxy(this); +} + +/** +Deep phase of rendering. Function can render substrings, or render substring of two +concated strings. Function can also perform partial effect on string. Function cannot +handle partial user effect, so this effects are converted to things strings. +*/ +void WStringProxy::RenderStringToBufferSubstr(wchar_t *renderPtr, size_t offset, size_t size) +{ + WStringMemory::LockProxy(this); + switch (_operation) + { + case OpConcat: + { + //process substring of concat + //count characters in buffer + size_t rendered; + //when string starts in left string + if (_baseString->GetLength()>offset) + { + //calculate total characters that may be rendered + rendered=_baseString->GetLength()-offset; + //but limit it to request size + if (rendered>size) rendered=size; + //render substring into buffer + _baseString->RenderStringToBufferSubstr(renderPtr,offset,rendered); + } + else + //no character has been rendered + rendered=0; + + //there is still characters remained to render. We will take it from second string + if (size-rendered>0) + { + if (offset>_baseString->GetLength()) offset-=_baseString->GetLength(); + else offset=0; + _secondString->RenderStringToBufferSubstr(renderPtr+rendered,offset,size-rendered); + } + } + break; + case OpSubstr: + { //rendering substrings is very easy + offset+=_offset; //add offset of substring + assert(offset+size<=GetLength()); //check length + //render substring + this->RenderStringToBufferSubstr(renderPtr,offset,size); + } + break; + case OpMemBlck: + { + //rendering from memory, final stop in recursion + //Get pointer string + const wchar_t *str=GetStringFromMemBlock(); + //copy substring from string into render buffer + wcsncpy(renderPtr,str+offset,size); + } + break; + case OpEffect: + if (_blockData2>=256) //interface cannot handle partial rendering + { + RenderString(); //convert proxy to simple redirect and render it + RenderStringToBufferSubstr(renderPtr,offset,size); //now we are able to cut out part + } + else + { + //all standard effects maps string 1:1 + //first get content of substring into buffer + _baseString->RenderStringToBufferSubstr(renderPtr,offset,size); + //we can append zero, because right side of string is not yet rendered + renderPtr[size]=0; + //process effect on target + RenderSimpleEffect(renderPtr); + } + break; + }; + WStringMemory::UnlockProxy(this); +} \ No newline at end of file diff --git a/DDLReader/Projects/Skeldal/DDLReader/WStringProxy.h b/DDLReader/Projects/Skeldal/DDLReader/WStringProxy.h new file mode 100644 index 0000000..e5f470b --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/WStringProxy.h @@ -0,0 +1,232 @@ +// WStringProxy.h: interface for the WStringProxy class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_WSTRINGPROXY_H__863ADE82_7789_4E54_BE7D_B8F0740FD81B__INCLUDED_) +#define AFX_WSTRINGPROXY_H__863ADE82_7789_4E54_BE7D_B8F0740FD81B__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "WStringMemory.h" +#include "IWStringEffect.h" +#include +#include +#include +#include + +/* +List of proxy types + +Memory_Proxy _operation=OpMemBlck + _blockData==0 and _blockData2==0 + or + _blockData!=0 and _blockData2!=0 + (_redirect - debug pointer) + (_blockData - 1) + +Proxy_Const _operation=OpMemBlck + _redirect - pointer to string + _blockData2=0 + +Proxy_Shared _operation=OpMemBlck + _redirect - pointer to string + _blockData2=2; + +Proxy_Immediate _operation=OpMemBlck + _blockData>0xFFFF + _blockData2>0xFFFF + both parameters are used by immediate memory manager + +Proxy_Concat _operation=OpConcat + _baseString and _secondString is valid + +Proxy_Link _operation=OpSubstr + _baseString is valid + _stringSize==_baseString->_stringSize + _offset==0; + NOTE: Can be used without rendering + +Proxy_RightSub _operation=OpSubstr + _baseString is valid + _offset<=_baseString->_stringSize + _stringSize==_baseString->_stringSize-_offset + NOTE: Can be used without rendering + +Proxy_SubString _operation=OpSubstr + _baseString is valid + _offset<=_baseString->_stringSize + _stringSize<=_baseString->_stringSize-_offset + +Proxy_Effect _operation=OpEffect + _baseString is valid + _stringSize=_baseString->_stringSize + _effect defining effect code < 0xFFFF + +Proxy_UserEffect _operation=OpEffect + _baseString is valid + _stringSize=_baseString->_stringSize + _effect>0xFFFF + _userEffect defining pointer to effect interface + +*/ +class WStringProxy +{ +public: + enum Operation + { + OpConcat=0, //proxy contains two links to concat it + OpSubstr=1, //proxy contains link to another proxy and specified substring + OpMemBlck=-2, //proxy contains informations about following string + OpEffect=-1, //proxy describing some efect with string + }; + + enum Effect + { + EfLower, //effect lower case + EfUpper, //effect upper case + EfReverse, //effect reverse string + }; +public: + + unsigned long _refCount; //reference count + unsigned long _stringSize:30; //string size in characters (maximum size 1073741823 characters ~ 2147483646 bytes) + Operation _operation:2; //operation with string or proxy type + + union + { + WStringProxy *_baseString; //pointer to next proxy referenced by this proxy + unsigned long _blockData; //user defined block data for OpMemBlock proxy type + const wchar_t *_redirect; //used for OpMemBlock, when _blockData2 is zero. + }; + + union + { + WStringProxy *_secondString; //pointer to second string for OpConcat + unsigned long _offset; //offset of substring for OpSubstr + Effect _effect; //effect selector for OpEffect + IWStringEffect *_userEffect; //user effect defined by IWStringEffect interface (valid when _effect is invalid) + unsigned long _blockData2; //user defined block data for OpMemBlock proxy type - exception: if this value is zero, member _redirect is valid + + }; + + + void RenderStringToBuffer(wchar_t *renderPtr); + void RenderStringToBufferSubstr(wchar_t *renderPtr, size_t offset, size_t size); + WStringProxy *TransitivniUzaver(); + void RenderSimpleEffect(wchar_t *renderPtr); + +public: + WStringProxy():_refCount(0),_operation(OpSubstr),_stringSize(0),_baseString(0),_secondString(0) {} //inicializes empty string proxy + + WStringProxy(WStringProxy *other): + _refCount(0), + _stringSize(other->GetLength()), + _baseString(other), + _operation(OpSubstr), + _offset(0) + {_baseString->AddRef();} + + WStringProxy(WStringProxy *other, unsigned long offset, unsigned long size): + _refCount(0), + _stringSize(size), + _baseString(other), + _operation(OpSubstr), + _offset(offset) + {_baseString->AddRef();} + + WStringProxy(WStringProxy *a, WStringProxy *b): + _refCount(0), + _stringSize(a->GetLength()+b->GetLength()), + _baseString(a), + _operation(OpConcat), + _secondString(b) + {_baseString->AddRef();_secondString->AddRef();} + + WStringProxy(WStringProxy *a, Effect effect): + _refCount(0), + _stringSize(a->GetLength()), + _baseString(a), + _operation(OpEffect), + _effect(effect) + {_baseString->AddRef();} + + WStringProxy(WStringProxy *a, IWStringEffect *userEffect): + _refCount(0), + _stringSize(a->GetLength()+userEffect->GetEffectExtraSize(a->GetLength())), + _baseString(a), + _operation(OpEffect), + _userEffect(userEffect) + {_baseString->AddRef();} + + WStringProxy(unsigned long size, unsigned long user1, unsigned long user2): + _refCount(0), + _stringSize(size), + _operation(OpMemBlck), + _blockData(user1), + _blockData2(user2) + {} + + WStringProxy(const wchar_t *imText): + _refCount(0), + _stringSize(wcslen(imText)), + _redirect(imText), + _blockData2(0), + _operation(OpMemBlck) + {} + + WStringProxy(const WStringProxy &other) + { + memcpy(this,&other,sizeof(*this)); + if (_operation!=OpMemBlck) _baseString->AddRef(); + if (_operation==OpConcat) _secondString->AddRef(); + } + + WStringProxy& operator=(const WStringProxy &other) + { + WStringProxy::~WStringProxy(); //call destructor to destruct current proxy + memcpy(this,&other,sizeof(*this)); //construct new proxy from template + if (_operation!=OpMemBlck) _baseString->AddRef(); + if (_operation==OpConcat) _secondString->AddRef(); + } + + WStringProxy *RenderString(); + + ~WStringProxy() + { + if (_operation!=OpMemBlck) _baseString->Release(); + if (_operation==OpConcat) _secondString->Release(); + } + + + unsigned long GetLength() {return _stringSize;} + void AddRef() {if (this) WStringMemory::AddRefProxy(this);} + void Release() {if (this) if (WStringMemory::ReleaseRefProxy(this)) WStringMemory::FreeProxy(this);} + + const wchar_t *GetString() + { + if (_operation==OpMemBlck) return (const wchar_t *)(this+1); + WStringProxy *p=RenderString(); + (*this)=*p; + return (const wchar_t *)(p+1); + } + + const wchar_t *GetStringFromMemBlock() + { + assert(_operation==OpMemBlck); + if (_blockData2==0 && _redirect!=NULL) return _redirect; + else return (const wchar_t *)(this+1); + } + + bool IsShared() {return _refCount>1;} + + void RecalcLength() + { + const wchar_t *str=GetStringFromMemBlock(); + _stringSize=wcslen(str); + } + +}; + +#endif // !defined(AFX_WSTRINGPROXY_H__863ADE82_7789_4E54_BE7D_B8F0740FD81B__INCLUDED_) diff --git a/DDLReader/Projects/Skeldal/DDLReader/res/DDLReader.ico b/DDLReader/Projects/Skeldal/DDLReader/res/DDLReader.ico new file mode 100644 index 0000000000000000000000000000000000000000..7eef0bcbe6580a6f464d688906172c2d9de44262 GIT binary patch literal 1078 zcmc&zF>b>!3}jLb9s)T}@Kod(893@u8ajANzT`op9^o+)S?=nU(FD@%0s)Sg^oyC8{H z9myetc;MEP)59v(LMa~xK8Yu^jIR*H22uCFiq5%C{s7(PJi>o15i^bmX4(vPxWAio z9ryY#AU_jfnd047-@`)XzL?%iS$gQyFP{44kS9X)fN{{QoL~hO-&=q&20Zr*cxFAt PkaNE{wR~2C$NfnjhSXWT literal 0 HcmV?d00001 diff --git a/DDLReader/Projects/Skeldal/DDLReader/resource.h b/DDLReader/Projects/Skeldal/DDLReader/resource.h new file mode 100644 index 0000000..2625141 --- /dev/null +++ b/DDLReader/Projects/Skeldal/DDLReader/resource.h @@ -0,0 +1,49 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by DDLReader.rc +// +#define IDM_ABOUTBOX 0x0010 +#define IDD_ABOUTBOX 100 +#define IDS_ABOUTBOX 101 +#define IDD_DDLREADER_DIALOG 102 +#define IDS_FILEOPENFAILED 102 +#define IDC_HEADGROUP 103 +#define IDC_HEADFNAME 104 +#define IDC_HEADSIZE 105 +#define IDC_HEADOFFSET 106 +#define IDS_DDLFILTER 107 +#define IDC_GROUP_GRAPHICS 108 +#define IDC_GROUP_SOUNDS 109 +#define IDC_GROUP_FONTS 110 +#define IDC_GROUP_BASIC 111 +#define IDC_GROUP_ITEMS 112 +#define IDC_GROUP_MONSTERS 113 +#define IDC_GROUP_DIALOGS 114 +#define IDC_GROUP_UNSPECIFIED 115 +#define IDC_GROUP_UNKNOWN 116 +#define IDS_UNABLETOCREATEFILE 117 +#define IDS_UNABLETOEXTACTDATA 118 +#define IDR_MAINFRAME 128 +#define IDD_PROGRESS 129 +#define IDD_EXPORTING 129 +#define IDC_FILELIST 1001 +#define IDC_FOLDER 1002 +#define IDC_BROWSE 1003 +#define IDC_EXPORT 1004 +#define IDC_POPISEK 1005 +#define IDC_DDLFILE 1006 +#define IDC_DDLBROWSE 1007 +#define IDC_PROGRESS 1008 +#define IDC_NAME 1009 +#define IDC_BUTTON1 1010 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 130 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1011 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/DDLReader/StdAfx.cpp b/DDLReader/StdAfx.cpp new file mode 100644 index 0000000..1a90873 --- /dev/null +++ b/DDLReader/StdAfx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// DDLReader.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + + + diff --git a/DDLReader/StdAfx.h b/DDLReader/StdAfx.h new file mode 100644 index 0000000..666c5f5 --- /dev/null +++ b/DDLReader/StdAfx.h @@ -0,0 +1,27 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__C5BDACC6_729E_4CA2_B27E_A1F209FB32A7__INCLUDED_) +#define AFX_STDAFX_H__C5BDACC6_729E_4CA2_B27E_A1F209FB32A7__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers + +#include // MFC core and standard components +#include // MFC extensions +#include // MFC support for Internet Explorer 4 Common Controls +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // MFC support for Windows Common Controls +#endif // _AFX_NO_AFXCMN_SUPPORT + +#include "wstring.h" + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__C5BDACC6_729E_4CA2_B27E_A1F209FB32A7__INCLUDED_) diff --git a/DDLReader/WPathname.cpp b/DDLReader/WPathname.cpp new file mode 100644 index 0000000..fab2f57 --- /dev/null +++ b/DDLReader/WPathname.cpp @@ -0,0 +1,408 @@ +// WPathname.cpp: implementation of the WPathname class. +// +////////////////////////////////////////////////////////////////////// + +#include "WPathname.h" +#include +#include + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +WPathname::WPathname(const wchar_t *name /*=NULL*/) +{ + if (name) SetPathname(name); +} + +WPathname::WPathname(const WString &name) +{ + SetPathname(name); +} + +WPathname::WPathname(const wchar_t *relpath, const WPathname &abspath) +{ + _fullpath=WString(relpath); + int chr=_fullpath.FindLast('\\'); + if (chr!=-1) + { + _path=_fullpath.Left(chr+1); + _filetitle=_fullpath.Right(chr+1); + } + else + { + _filetitle=_fullpath; + } + chr=_filetitle.FindLast('.'); + if (chr!=-1) + { + _extension=_filetitle.Right(chr); + _filetitle=_filetitle.Left(chr); + } + + RelativeToFull(abspath); +} + + +WPathname::WPathname(const WPathname &other) +{ + _fullpath=other._fullpath; + _path=other._path; + _filetitle=other._filetitle; + _extension=other._extension; +} + +void WPathname::SetDrive(wchar_t dr) +{ + if (HasDrive()) + { + if (dr==0) _path=_path.Right(2); + else _path[0]=dr; + } + else if (dr!=0) + { + int np=IsNetworkPath(); + wchar_t buff[2]; + buff[0]=dr; + buff[1]=':'; + buff[2]=0; + if (np) + _path=WString(buff)+_path.Right(np); + else + _path=WString(buff)+_path; + + } + RebuildPath(); +} + +void WPathname::SetDirectory(const wchar_t *dir) +{ + bool copydrv; //directory doesn't contain drive, need copy from original + bool addslash; //directory doesn't ending by backslash, need add it + + int len=wcslen(dir); + copydrv=HasDrive(dir) || !HasDrive(); //copy original drive, if exists and directory doesn't contaion drive + if (wcsncmp(dir,L"\\\\",2)==0) copydrv=true; //network path, don't copy drive + addslash=len && dir[len-1]!='\\'; //add slash + if (copydrv) + _path=WString(dir); + else + _path=_path.Left(2)+WString(dir); + if (addslash) + _path+=WSC("\\"); + + RebuildPath(); +} + +void WPathname::SetFilename(const wchar_t *filename) +{ + WString wfilename=WString(filename); + int dot=wfilename.FindLast('.'); + if (dot==-1) + { + _filetitle=wfilename; + _extension=0; + } + else + { + _filetitle=wfilename.Left(dot); + _extension=wfilename.Right(dot); + } + + RebuildPath(); +} + +void WPathname::SetExtension(const wchar_t *ext) +{ + _extension=WString(ext); + RebuildPath(); +} + +void WPathname::SetFileTitle(const wchar_t *title) +{ + _filetitle=WString(title); + RebuildPath(); +} + +void WPathname::SetPathname(const wchar_t *pathname) +{ + SetPathname(WString(pathname)); +} + +void WPathname::SetPathname(const WString &pathname) +{ + if (pathname.GetLength()==0) SetNull(); + else + { + wchar_t *part; + DWORD needsz=GetFullPathNameW(pathname,0,NULL,&part); + wchar_t *fpth=(wchar_t *)alloca(needsz*sizeof(*fpth)); + GetFullPathNameW(pathname,needsz,fpth,&part); + part=wcsrchr(fpth,'\\'); + if (part) part++;else part=NULL; + if (part) + { + SetFilename(part); + *part=0; + } + else + SetFilename(WString()); + SetDirectory(fpth); + } +} + +const wchar_t *WPathname::GetNameFromPath(const wchar_t *path) +{ + const wchar_t *c=wcsrchr(path,'\\'); + if (c!=NULL) c++;else return path; + return c; +} + +const wchar_t *WPathname::GetExtensionFromPath(const wchar_t *path) +{ + const wchar_t *fname=GetNameFromPath(path); + const wchar_t *c=wcsrchr(fname,'.'); + if (c==NULL) c=wcsrchr(path,0); + return c; +} + +void WPathname::RebuildPath() +{ + _fullpath=_path+_filetitle+_extension; +} + +bool WPathname::GetDirectoryWithDriveWLBS(wchar_t *buff, size_t size) const +{ + size_t psize=wcslen(GetDirectoryWithDrive()); + if (psize>size) return false; + if (psize==0) {buff[0]=0;return true;} + wcsncpy(buff,GetDirectoryWithDrive(),psize-1); + buff[psize-1]=0; + return true; +} + +WString WPathname::GetDirectoryWithDriveWLBS() const +{ + if (_path.GetLength()) return _path.Left(_path.GetLength()-1); + return WString(); +} + +bool WPathname::IsPathValid() const +{ + if (IsNull()) return false; + wchar_t *invalidChars=L"/*?\"<>|"; + const wchar_t *path=GetFullPath(); + if (*path==0) return false; + while (*path) + { + if (wcschr(invalidChars,*path)!=NULL) return false; + path++; + } + return true; +} + +bool WPathname::SetTempDirectory() +{ + wchar_t buff[1]; + DWORD size=GetTempPathW(1,buff); + if (size==0) return false; + WString pth; + wchar_t *p=pth.CreateBuffer(size); + if (GetTempPathW(size,p)==0) return false; + pth.UnlockBuffer(); + _path=pth; + return true; +} + +bool WPathname::SetDirectorySpecial(int nSpecCode) +{ + wchar_t buff[MAX_PATH]; + if (SHGetSpecialFolderPathW(GetForegroundWindow(),buff,nSpecCode,FALSE)!=NOERROR) return false; + SetDirectory(buff); + return true; +} + +bool WPathname::SetTempFile(const wchar_t *prefix, unsigned int unique) +{ + wchar_t tempname[MAX_PATH]; + if (GetTempFileNameW(GetDirectoryWithDrive(),prefix,unique,tempname)==0) return false; + this->SetPathname(tempname); + return true; +} + +WPathname WPathname::GetExePath() +{ + wchar_t buff[MAX_PATH*4]; + GetModuleFileNameW(NULL,buff,sizeof(buff)); + return WPathname(buff); +} + +const wchar_t *WPathname::FullToRelativeProjectRoot(const wchar_t *full, const wchar_t *projectRoot) +{ + const wchar_t *a=full,*b=projectRoot; + while (*a && towlower(*a)==towlower(*b)) {a++;b++;}; + if (*b) return full; + return a; +} + +bool WPathname::FullToRelative(const WPathname &relativeto) +{ + if (relativeto.IsNull() || IsNull()) return false; + bool h1=HasDrive(); + bool h2=relativeto.HasDrive(); + if (h1!=h2) return false; //rozdilny zpusob adresace - nelze vytvorit relatvni cestu + if (h1==true && h2==true && towupper(GetDrive())!=towupper(relativeto.GetDrive())) + return false; //ruzne disky, nelze vytvorit relativni cestu + if (wcsncmp(_path,L"\\\\",2)==0) //sitova cesta + { + int slsh=0; //citac lomitek + const wchar_t *a=_path; + const wchar_t *b=relativeto._path; + while (towupper(*a)==towupper(*b) && *a && slsh<3) //zacatek sitove cesty musi byt stejny + { + if (*a=='\\') slsh++; + a++;b++; + } + if (slsh!=3) return false; //pokud neni stejny, nelze vytvorit relativni cestu + } + int sublevel=0; + const wchar_t *ps1=_path; + const wchar_t *ps2=relativeto._path; + if (h1) {ps1+=2;ps2+=2;} + const wchar_t *sls=ps2; + while (towupper(*ps1)==towupper(*ps2) && *ps1) + { + if (*ps2=='\\') sls=ps2+1; + ps1++;ps2++; + } + ps1-=ps2-sls; + if (sls) + { + while (sls=wcschr(sls,'\\')) + { + sls++; + sublevel++; + } + } + wchar_t *buff=(wchar_t *)alloca((sublevel*3+wcslen(ps1)+1)*sizeof(*buff)); + wchar_t *pos=buff; + for (int i=0;iref._path.GetString()) + { + end--; + while (end>ref._path.GetString() && end[-1]!='\\') end--; + } + beg+=3; + } + else + beg+=2; + } + int partln=end-ref._path; + wchar_t *buff=(wchar_t *)alloca((partln+wcslen(beg)+1)*sizeof(*buff)); + wcsncpy(buff,ref._path,partln); + wcscpy(buff+partln,beg); + SetDrive(0); + SetDirectory(buff); + return true; +} + +int WPathname::IsNetworkPath() const +{ + if (wcsncmp(_path,L"\\\\",2)==0) //sitova cesta + { + const wchar_t *p=_path+2; + const wchar_t *c=wcschr(p,'\\'); + if (c) return c-_path; + } + return 0; +} + +void WPathname::SetServerName(const wchar_t *server) +{ + if (HasDrive()) SetDrive(0); + else + { + int np=IsNetworkPath(); + _path=_path.Right(np); + } + + _path=WSC("\\\\")+WString(server)+WSC("\\"); + RebuildPath(); +} + +void WPathname::SetNull() +{ + _fullpath=_path=_filetitle=_extension=0; +} + +bool WPathname::GetPartFromPath(const wchar_t *path, int partnum, wchar_t *buff, int bufsize, int mode) +{ + const wchar_t *scan=path; + while (*scan=='\\') scan++; + while (partnum && *scan) + { + while (*scan!='\\' && *scan) scan++; + while (*scan=='\\') scan++; + partnum--; + } + if (*scan==0) + { + buff[0]=0; + return false; + } + int pt=0; + if (mode==-1) + { + pt=scan-path; + if (pt>bufsize) + { + buff[0]=0; + return true; + } + else + memcpy(buff,path,pt); + } + bool nlast=false; + while (*scan && (mode==1 || !nlast) && pt 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "WString.h" + +#ifndef ASSERT +#ifdef _DEBUG +#define ASSERT(x) assert(x) +#else +#define ASSERT(x) +#endif +#endif + +#define WPathnameCompare(op) bool operator op (const WPathname &other) const \ +{if (IsNull() || other.IsNull()) return false;else return wcsicmp(_fullpath,other._fullpath) op 0;}\ + bool operator op (const wchar_t *other) const \ +{ASSERT(!other || other[0]!=0);\ + if (IsNull() || other==NULL) return false;else return wcsicmp(_fullpath,other) op 0;} + +/** class WPathname simplifying manipulation with WPathnames, filenames, general paths, and +also supports convert from absolute path to relative respectively */ + + + +class WPathname +{ + ///object value and data + /**The implementation of WPathname creates only one buffer for all variables. It can + increase speed by effective memory use. Strings are stored one after another separated + by zero byte. Evry time any string changed, implementation recalculate buffer usage, and + decide, whether it should resize buffer or not. + + _fullpath also points to string contain full path with filename, + it is dominant value of the class + */ + WString _fullpath; + WString _path; /// + If name is provided, WPathname will expand it into full name with drive and folder name. + @param name optional argument to inicialize object + */ + WPathname(const wchar_t *name=NULL); + WPathname(const WString &name); + + ///Construct WPathname class + /** + @param relpath Relative path or uncomplette path or single filename with extension. + WPathname will expand this WPathname into full using absolute path provided by the second + argument. + @param abspath Absolute path used as reference to folder - the origin of relative path + provided in the first argument. + */ + WPathname(const wchar_t *relpath, const WPathname &abspath); + + ///Construct WPathname as copy of another WPathname + WPathname(const WPathname &other); + + + ///Function returns the current drive letter. + /** Before usage, ensure, that current WPathname contain drive. + In network path drive letter is missing. + In this case, result is undefined. To ensure, use HasDrive function + @return the drive letter of current path. + */ + wchar_t GetDrive() const + { + if (IsNull()) return 0; + return _path[0]; + } + + ///Static function determines, if argument contain a drive information. + /** + @param dir directory to inspect + @return true, if directory contain drive.

+ This function is independed, it don't need any WPathname variable declared. + */ + static bool HasDrive(const wchar_t *dir) + {return (dir[0]>='A' && dir[0]<='Z' || dir[0]>='a' && dir[0]<='z') && dir[1]==':';} + + ///Function determines, if current WPathname contain a drive information + /** + @return true, if current WPathname contain a drive information + */ + bool HasDrive() const + { + if (IsNull()) return false; + return HasDrive(_path); + } + + + ///Function returns current folder name + /** + if current folder name contain drive, only folder name is returned (without drive). + In other cases (relative or network drives) returns full path. + @return folder name or full path. Pointer is valid until any first change in object. + Do not invoke release function at pointer! + */ + const wchar_t *GetDirectory() const + { + if (HasDrive()) return _path.GetString()+3; + else return _path.GetString()+IsNetworkPath(); + } + + const wchar_t *GetDirectoryWithDrive() const + { + return _path; + } + + ///Function returns current filename with extension + /** + @return current filename with extension. Pointer is valid until any first change in object. + Do not invoke release function at pointer! + */ + const wchar_t *GetFilename() const + { + if (IsNull()) return NULL; + const wchar_t *blk=wcsrchr(_fullpath,'\\'); + if (blk) blk=blk+1;else blk=_fullpath; + return blk; + } + + ///Function returns current extension (with starting dot) + /** + @return current extension. Pointer is valid until any first change in object. + Do not invoke release function at pointer! + */ + const wchar_t *GetExtension() const + {return _extension;} + + ///Function returns current filename without extension (without dot) + /** + @return current filename without extension (without dot). Pointer is valid until any first change in object. + Do not invoke release function at pointer! + */ + const wchar_t *GetTitle() const + {return _filetitle;} + + ///Function changes current drive. + /**If object contain WPathname with drive, then current drive is changed and function returns. + If object contain network path, then computer name is changed to the drive name. + If object contain relative path, then whole path is replaced by path on root on drive. + @param dr new drive letter. This parameter can be set to zero. It means, that current + driver is deleted, and path is converted to relative path from root. Note: Zero c + cannot be used with network paths and relative paths, and finnaly has no effect to the object + */ + + void SetDrive(wchar_t dr); + + ///Sets new directory for object + /** if object contain a drive letter and argument dir doesn't, then current drive is remain + and only directory part is replaced. If current path is network path or relative path, + then whole path is replaced by new one. + If argument dir contain drive letter, then whole path is replaced too. + @param dir contain new WPathname. Backslash should be the last wchar_tacter in string + */ + void SetDirectory(const wchar_t *dir); + + ///Sets new filename for object. + /** + If filename contain dot, function assumes, that filename is provided with extension. + Otherwise, current extension remains untouched. + @param filename new filename for object + */ + + void SetFilename(const wchar_t *filename); + + ///Sets new extension for object. + /** + If ext doesn't starting with dot, function adds it. + @param ext new extension for object + */ + void SetExtension(const wchar_t *ext); + + ///Sets new file title + /** Function changes file title, extension remains untouched. + if title contains extension (dot inside its name), this extension doesn't change + current extension. For example, if current extension is ".cpp" and filetitle contain + "source.h", then result is "source.h.cpp" + @param title a new title for object. + */ + + void SetFileTitle(const wchar_t *title); + + ///Function returns full WPathname. + /** + @return current WPathname. Pointer is valid until any first change in object. + Do not invoke release function at pointer! + */ + + const wchar_t *GetFullPath() const + {return _fullpath;} + + ///Sets WPathname + /** Function has same effect as constructor. But it can be used + anytime during object lifetime. It simply replaces current WPathname with newer. WPathname + in argument is expanded to full WPathname, current directory is used as reference. + @param WPathname new WPathname + */ + void SetPathname(const wchar_t *pathname); + void SetPathname(const WString &pathname); + + WPathname& operator=(const wchar_t *other) + {SetPathname(other);return *this;} + + WPathname& operator=(const WString &other) + {SetPathname(other);return *this;} + + WPathname& operator=(const WPathname& other) + { + _fullpath=other._fullpath; + _path=other._path; + _filetitle=other._filetitle; + _extension=other._extension; + return *this; + } + + ///converts object to string + operator const wchar_t *() const + {return GetFullPath();} + + ///Static function to help getting filename from WPathname + /** Function finds last backslash / and return pointer to first wchar_tacter after it. + Pointer stays valid until original path is destroyed or until original path is changed + @param path WPathname to inspect as string + @return pointer to filename + */ + static const wchar_t *GetNameFromPath(const wchar_t *path); + + ///Static function to help getting extension from WPathname + /** Function finds last dot '.' in filename return pointer to it (extension with dot). + Pointer stays valid until original path is destroyed or until original path is changed + @param path WPathname to inspect as string + @return pointer to extension + */ + static const wchar_t *GetExtensionFromPath(const wchar_t *path); + + ///Function sets server name for network path + /** If current path is network path, then changes server name to newer. Otherwise + it remove drive letter, and insert server name before remain path + @param server server name without slashes + */ + void SetServerName(const wchar_t *server); + + ///Function inspects current path and returns, whether contain server name + /**@return zero, if current path is not valid network path. Nonzero if path contain + server name. Then value returned count wchar_tacters containing server name with precedent + slashes. + */ + int IsNetworkPath() const; + + ///Function converts current relative path into absolute path + /** + If current path is not relative, function do nothing. + @param ref reference to path, against which path is relative. + @return true if path has been converted, or false, if conversion is impossible + */ + bool RelativeToFull(const WPathname &ref); + + ///Function converts current absolute path into relative path + /** + If current path is not relative, function do nothing. Both paths must be on the same + drive or network computer. + + @param ref reference to path, against which path should be relative. + @return true if path has been converted, or false, if conversion is impossible + */ + bool FullToRelative(const WPathname &relativeto); + + WPathname& operator+=(const wchar_t *relativePath) + {*this=WPathname(relativePath,*this);return *this;} + + WPathname operator+(const wchar_t *relativePath) + {WPathname out(relativePath,*this);return out;} + + bool IsNull() const {return _fullpath.GetLength()==0;} + + void SetNull(); + + WPathnameCompare(<) + WPathnameCompare(>) + WPathnameCompare(==) + WPathnameCompare(>=) + WPathnameCompare(<=) + WPathnameCompare(!=) + + + ///Function gets part of WPathname + /** + @param path subject of examine + @param partnum zero-base index of part of WPathname. Index 0 mostly contain drive or server, in case of + relative path, there is the name of the first folder or dots. + @param buff buffer for store result + @param bufsize count wchar_tacters in buffer; + @param mode mode=0, gets only name of part. + mode=1, get current part and remain parts of path. + mode=-1, gets all parts till current + @return Function returns true, if it was succesful, and it was not last part. Function returns + false, if it was succesful, and it was last part. Function returns false and sets buffer empty, + if an error occured. Function returns true and sets buffer empty, if buffer is too small to hold data + */ + static bool GetPartFromPath(const wchar_t *path, int partnum, wchar_t *buff, int bufsize, int mode=0); + + ///Function gets part of object + /** + @param partnum zero-base index of part of WPathname. Index 0 mostly contain drive or server, in case of + relative path, there is the name of the first folder or dots. + @param buff buffer for store result + @param bufsize count wchar_tacters in buffer; + @param mode mode=0, gets only name of part. + mode=1, get current part and remain parts of path. + mode=-1, gets all parts till current + @return Function returns true, if it was succesful, and it was not last part. Function returns + false, if it was succesful, and it was last part. Function returns false and sets buffer empty, + if an error occured. Function returns true and sets buffer empty, if buffer is too small to hold data + */ + bool GetPart(int partnum, wchar_t *buff, int bufsize,int mode=0) const + { + return GetPartFromPath(this->_fullpath,partnum,buff,bufsize,mode); + } + + /// Get Directory With Drive Without Last Back Slash + /** Retrieves into buffer directory with drive and removes last backslash + @param buff buffer that retrieves path + @param size size of buffer + @return true, if success, failed if buffer is too small*/ + + + bool GetDirectoryWithDriveWLBS(wchar_t *buff, size_t size) const; + + WString GetDirectoryWithDriveWLBS() const; + + + /// function checks, if path is valid and returns true, if does. + bool IsPathValid() const; + + /// Sets special directory. + /** + @param bSpecCode this value may be operation-system + depend. Windows implementation using CSIDL_XXXX constants, which is described in SHGetSpecialFolderLocation function + description + @return true, if function were successful + */ + bool SetDirectorySpecial(int nSpecCode); + + ///Sets temporaly directory. + bool SetTempDirectory(); + + ///Guess temporaly file name + /** + @param prefix prefix string for name + @param unique if unique is non-zero, it is used for new temporaly file. If unique is zero, function guess own unique + value. + @return true if function were successful + */ + bool SetTempFile(const wchar_t *prefix=L"tmp", unsigned int unique=NULL); + + ///Returns path of current executable. + /**It useful, when accessing folder, from when current module has been executed */ + static WPathname GetExePath(); + + ///Solves most used conversion from fullpath to path relative to project root + /** + @param full full WPathname with drive + @param projectRoot project root path + @return function returns pointer to full path, where starts relative part. If + fullpath doesn't contain project root path, it returns pointer to full. + @example FullToProjectRoot("x:\\project\\data\\example.txt","x:\\project"); //result is "data\\example.txt" + */ + + static const wchar_t *FullToRelativeProjectRoot(const wchar_t *full, const wchar_t *projectRoot); + + +protected: + ///Function only rebuild _fullpath string. + /** It doesn't check space for string! This function is used, when length of path is excepted + the same or smaller, then current. + */ + void RebuildPath(); + + +}; + + + +#endif // !defined(AFX_WPathname_H__158F59D5_B422_4FA6_86AC_10B5EC48C81B__INCLUDED_) diff --git a/DDLReader/WString.cpp b/DDLReader/WString.cpp new file mode 100644 index 0000000..1fa0cd6 --- /dev/null +++ b/DDLReader/WString.cpp @@ -0,0 +1,194 @@ +// WString.cpp: implementation of the WString class. +// +////////////////////////////////////////////////////////////////////// + +#include "WString.h" +#include +#include + + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +WString::WString(const char *sbstring, unsigned int codePage) +{ + if (sbstring==NULL || *sbstring==0) + { + _ref=NULL; + } + else + { + size_t reqBuff=MultiByteToWideChar(codePage,0,sbstring,-1,NULL,0); + + _ref=WStringMemory::AllocString(NULL,reqBuff); + _ref->AddRef(); + wchar_t *str=const_cast(_ref->GetStringFromMemBlock()); + + MultiByteToWideChar(codePage,0,sbstring,-1,str,reqBuff); + } +} + +int WString::FormatV(wchar_t *format, va_list lst) +{ + size_t curSize=4096; + int written; + do + { + _ref=WStringMemory::AllocString(NULL,curSize); + wchar_t *str=const_cast(_ref->GetStringFromMemBlock()); + written=_vsnwprintf(str,curSize,format,lst); + if (written<0) + { + curSize*=2; + WStringMemory::FreeProxy(_ref); + } + } + while (written<-1); + _ref->RecalcLength(); + _ref->AddRef(); + return written; +} + +int WString::Format(wchar_t *format, ...) +{ + va_list valst; + va_start(valst,format); + return FormatV(format,valst); +} + + +int WString::ScanStringV(const wchar_t *format, va_list lst) const +{ + unsigned long *ptr=(unsigned long *)lst; + return swscanf(GetString(),format,ptr[0],ptr[1],ptr[2],ptr[3],ptr[4],ptr[5],ptr[6],ptr[7],ptr[8],ptr[9], + ptr[10],ptr[11],ptr[12],ptr[13],ptr[14],ptr[15],ptr[16],ptr[17],ptr[18],ptr[19]); + +} + +int WString::ScanString(const wchar_t *format, ...) const +{ + va_list valst; + va_start(valst,format); + return ScanStringV(format,valst); +} + +bool WString::ReplaceOnce(const WString &findWhat,const WString &replaceWith) +{ + int pos=Find(findWhat); + if (pos==-1) return false; + (*this)=Left(pos)+replaceWith+Right(pos+replaceWith.GetLength()); + return true; +} + +bool WString::ReplaceAll(const WString &findWhat,const WString &replaceWith) +{ + WString process=*this; + WString result; + int pos; + bool processed=false; + while ((pos=process.Find(findWhat))!=-1) + { + result=result+process.Left(pos)+replaceWith; + process=process.Right(pos+findWhat.GetLength()); + processed=true; + } + *this=result+process; + return processed; +} + +WString WString::TrimLeft() const +{ + return TrimLeft(L" \r\n\t"); +} + +WString WString::TrimRight() const +{ + return TrimRight(L" \r\n\t"); +} + +WString WString::TrimLeft(wchar_t *trimChars) const +{ + const wchar_t *proStr=GetString(); + int p=0; + while (proStr[p] && wcschr(trimChars,proStr[p]!=NULL)) p++; + return Right(p); +} + +WString WString::TrimRight(wchar_t *trimChars) const +{ + const wchar_t *proStr=GetString(); + int p=GetLength()-1; + while (p>=0 && wcschr(trimChars,proStr[p]!=NULL)) p--; + return Left(p+1); +} + +WString WString::Upper() const +{ + return WString(WStringMemory::AllocProxy(WStringProxy(_ref,WStringProxy::EfUpper))); +} + +WString WString::Lower() const +{ + return WString(WStringMemory::AllocProxy(WStringProxy(_ref,WStringProxy::EfLower))); +} + +WString WString::Reverse() const +{ + return WString(WStringMemory::AllocProxy(WStringProxy(_ref,WStringProxy::EfReverse))); +} + +WString WString::Effect(IWStringEffect *effect) const +{ + return WString(WStringMemory::AllocProxy(WStringProxy(_ref,effect))); +} + +void WString::SetUTF7(const char *utf7) +{ + *this=WString(utf7,CP_UTF7); +} + +void WString::SetUTF8(const char *utf8) +{ + *this=WString(utf8,CP_UTF8); +} + +const char *WString::AsSBString(unsigned int codePage, WString &holder) +{ + const wchar_t *str=GetString(); + if (str[0]==0) return ""; + size_t reqsize=WideCharToMultiByte(codePage,0,str,-1,NULL,0,NULL,NULL); + WStringProxy *holderProxy=WStringMemory::AllocString(NULL,reqsize/2); //reqsize/2+(2 bytes) + char *mbstr=reinterpret_cast(const_cast(holderProxy->GetStringFromMemBlock())); + WideCharToMultiByte(codePage,0,str,-1,mbstr,reqsize,NULL,NULL); + holder=WString(holderProxy); + return mbstr; +} + +const char *WString::AsUTF7(WString &holder) +{ + return AsSBString(CP_UTF7,holder); +} + +const char *WString::AsUTF8(WString &holder) +{ + return AsSBString(CP_UTF8,holder); +} + +void WString::ReadFromStream(size_t (*streamReader)(wchar_t *buffer, size_t bufferLen, void *context),void *context) +{ + _ref->Release(); + _ref=NULL; + wchar_t buff[256]; + size_t rd; + while ((rd=streamReader(buff,sizeof(buff)/sizeof(wchar_t),context))!=0) + { + *this=*this+WString(buff,rd); + } +} + +const WString WStringConst(const wchar_t *text) +{ + return WString(WStringMemory::AllocProxy(WStringProxy(text))); +} + diff --git a/DDLReader/WString.h b/DDLReader/WString.h new file mode 100644 index 0000000..a244adb --- /dev/null +++ b/DDLReader/WString.h @@ -0,0 +1,496 @@ +// WString.h: interface for the WString class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_WSTRING_H__481164FB_3BB7_4824_B0E3_8B371F0AAF3A__INCLUDED_) +#define AFX_WSTRING_H__481164FB_3BB7_4824_B0E3_8B371F0AAF3A__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "WStringProxy.h" +#include + +class WString +{ + mutable WStringProxy *_ref; + + + +public: + ///constructs empty string + WString():_ref(0) {} + + ///constructs string. + explicit WString(const wchar_t *string):_ref(string==NULL?NULL:WStringMemory::AllocString(string,0)) {_ref->AddRef();}; + + ///constructs string from wide-char array with specified length + WString(const wchar_t *string, size_t sz):_ref(WStringMemory::AllocString(string,sz)) {_ref->AddRef();}; + + ///copy constructor + /**constructor doesn't copy the string, only reference. + String is shared until it is changed + */ + WString(const WString &other):_ref(other._ref) {_ref->AddRef();} + + ///constructs string from multi-byte string. codePage specified code page of string + WString(const char *sbstring, unsigned int codePage); + + ///constructs string from string-proxy. Used internally with WStringMemory::AllocXXX functions + WString(WStringProxy *proxy):_ref(proxy) {_ref->AddRef();} + + ///assignment operator + /** assignment operator doesn't copy the string only reference. + String is shared until it is changed */ + WString &operator=(const WString &other) + {other._ref->AddRef();_ref->Release();_ref=other._ref;return *this;} + + ///Destructor - releases reference + ~WString() {_ref->Release();} + + ///function converts instance of WString to wchar_t pointer + /** + Function will perform RenderString, if it is needed. + */ + const wchar_t *GetString() const + { + if (_ref==NULL) return L""; + WStringProxy *str=_ref->RenderString(); + if (_ref!=str) + { + str->AddRef();_ref->Release();_ref=str; + } + return _ref->GetStringFromMemBlock(); + } + + ///operator can convert WString to wchar_t pointer anytime + operator const wchar_t *() const {return GetString();} + + ///function returns count of characters in string + /** function doesn't need to render string, so it can be called anytime + without loosing the benefit of "pseudo-strings" boosting */ + size_t GetLength() const + { + if (_ref) return _ref->GetLength(); + else return 0; + } + + ///function creates string as sum of this and another string + /** function creates "pseudo-string" that represents sum of two string. + pseudo-string is rendered to "real-string" automatically, when it is needed */ + WString operator+(const WString other) const + { + if (_ref==NULL) return other; + if (other._ref==NULL) return *this; + return WString(WStringMemory::AllocProxy(WStringProxy(_ref,other._ref))); + } + + WString &operator+=(const WString other) + { + *this=*this+other; + return *this; + } + + ///function creates string as substring of another string + /** function creates "pseudo-string" that represents substring of anothers string. + Pseudo-string is rendered to "real-string" automatically, when it is needed */ + WString Mid(size_t begin, size_t len) const + { + if (begin==0) return Left(len); + if (_ref==NULL || begin>GetLength()) return WString(); + if (begin+len>GetLength()) return Right(begin); + return WString(WStringMemory::AllocProxy(WStringProxy(_ref,begin,len))); + } + + WString Left(size_t len) const + { + if (_ref==NULL) return WString(); + if (len>=GetLength()) return *this; + return WString(WStringMemory::AllocProxy(WStringProxy(_ref,0,len))); + } + + WString Right(size_t begin) const + { + if (_ref==NULL || begin>GetLength()) return WString(); + if (begin==0) return *this; + return WString(WStringMemory::AllocProxy(WStringProxy(_ref,begin,GetLength()-begin))); + } + + WString RightR(size_t count) const + { + if (_ref==NULL || count==0) return WString(); + if (count>=GetLength()) return *this; + return WString(WStringMemory::AllocProxy(WStringProxy(_ref,GetLength()-count,count))); + } + + WString Delete(size_t begin, size_t count) const + { + if (_ref==NULL) return WString(); + if (begin==0) return Right(count); + if (begin+count>=GetLength()) return Left(begin); + return WString(WStringMemory::AllocProxy(WStringProxy(Left(begin)._ref,Right(begin+count)._ref))); + } + + WString Insert(const WString &what, size_t index) const + { + if (_ref==NULL) return what; + if (index==0) return what+*this; + if (index>=GetLength()) return *this+what; + return Left(index)+what+Right(index); + } + + /// function allows to access any char in string + wchar_t operator[](int index) const + { + assert(index<=(int)GetLength() && index>=0); + return GetString()[index]; + } + + /// functions allows lock string for accesing it directly. + /** Function returns pointer to buffer which holds string. + Buffer size is equal to string length plus terminating zero. + Application can modify content of buffer. + If string is shared with another WString object, LockBuffer + creates copy of string + Do not forger to call UnlockBuffer, when you finish modifiing the content + */ + wchar_t *LockBuffer() + { + if (_ref==NULL) return NULL; + GetString(); + WStringMemory::LockProxy(_ref); + if (_ref->IsShared()) + { + WStringMemory::UnlockProxy(_ref); + _ref->Release(); + _ref=WStringMemory::AllocString(_ref->GetStringFromMemBlock(),0); + _ref->AddRef(); + WStringMemory::LockProxy(_ref); + } + return const_cast(_ref->GetStringFromMemBlock()); + } + + /// Function creates buffer for string and returns its address + /** Application can use buffer in functions, that cannot work with + WString objects. Size of buffer is specified by sz value, and it is in characters. + Application must call UnlockBuffer after writes all data into buffer. + + NOTE: Prevoius content of string is lost. + NOTE: sz specifies buffer size without terminating zero character + */ + wchar_t *CreateBuffer(size_t sz) + { + _ref->Release(); + _ref=WStringMemory::AllocString(NULL,sz); + _ref->AddRef(); + WStringMemory::LockProxy(_ref); + return const_cast(_ref->GetStringFromMemBlock()); + } + + /// Function creates buffer, and copies string into it. + /** Parameter sz specifies size of new buffer in characters + When sz is smaller then size of string, string is truncated + When sz is larger then size of string, string is copied unchanged, + but extra characters can be appended. + + NOTE: sz specifies buffer size without terminating zero character + */ + wchar_t *CreateBufferCopy(size_t sz) + { + WString save=*this; + wchar_t *wbuff=CreateBuffer(sz); + int minsz=__min(sz,save.GetLength()); + wcsncpy(wbuff,save.GetString(),minsz); + return wbuff; + } + + /// Function unlocks internal buffer + /** parameter sz specifies final lenght of string in buffer. Default + value -1 forces function calc size by own + */ + void UnlockBuffer(int sz=-1) + { + if (_ref==NULL) return; + wchar_t *wbuff=const_cast(_ref->GetStringFromMemBlock()); + if (sz<0) sz=wcslen(wbuff); + else wbuff[sz]=0; + if (sz!=(signed)_ref->GetLength()) + { + _ref->RecalcLength(); + WStringMemory::UnlockProxy(_ref); + } + } + + class WStringAtCharHelper + { + WString &_str; + size_t _index; + public: + WStringAtCharHelper(WString &str,size_t index):_str(str),_index(index) {} + WString &operator=(wchar_t z) + { + wchar_t *buff=_str.LockBuffer(); + assert(buff && _index<_str.GetLength()); + buff[_index]=z; + _str.UnlockBuffer(); + return _str; + } + operator wchar_t() + { + assert(_index<_str.GetLength()); + return ((const wchar_t *)_str)[_index]; + } + }; + + /// Function will return helper object, which can access single character in string + /** + Using array operator is slower than accessing characters by LockBuffer function + */ + WStringAtCharHelper operator[](int index) + { + return WStringAtCharHelper(*this,index); + } + + int Find(wchar_t z,size_t from=0) const + { + if (from>=GetLength()) return -1; + const wchar_t *res=wcschr(GetString()+from,z); + if (res) return res-GetString(); + else return -1; + } + + int FindLast(wchar_t z) const + { + const wchar_t *res=wcsrchr(GetString(),z); + if (res) return res-GetString(); + else return -1; + } + + int Find(const wchar_t *z,size_t from=0) const + { + if (z==NULL) return -1; + if (from>=GetLength()) return -1; + const wchar_t *res=wcsstr(GetString()+from,z); + if (res) return res-GetString(); + else return -1; + } + + int FormatV(wchar_t *format, va_list lst); + + int Format(wchar_t *format, ...); + + ///Scans string for format + /** function is limited, item count is limited up to 20 items */ + int ScanStringV(const wchar_t *format, va_list lst) const; + + ///Scans string for format + /** function is limited, item count is limited up to 20 items */ + int ScanString(const wchar_t *format, ...) const; + + bool ReplaceOnce(const WString &findWhat,const WString &replaceWith); + + bool ReplaceAll(const WString &findWhat,const WString &replaceWith); + + WString TrimLeft() const; + + WString TrimRight() const; + + WString TrimLeft(wchar_t *trimChars) const; + + WString TrimRight(wchar_t *trimChars) const; + + ///Function splits string into two + /** Left part of string is returned. + Right part of string is leaved in object + @param splitPos split position. + @return if splitPos==0, function returns empty string. if splitPos>=length, function + moves string from object to result*/ + WString Split(size_t splitPos) + { + WString result=Left(splitPos); + *this=Right(splitPos); + return result; + } + + bool IsEmpty() const {return _ref==NULL;} + + void Empty() const {_ref->Release();_ref=NULL;} + + int Compare(const wchar_t *other) const + { + return wcscmp(*this,other); + } + + bool operator>(const WString &other) const {return Compare(other)>0;} + bool operator<(const WString &other) const {return Compare(other)<0;} + bool operator>=(const WString &other) const {return Compare(other)>=0;} + bool operator<=(const WString &other) const {return Compare(other)<=0;} + bool operator!=(const WString &other) const {return Compare(other)<=0;} + bool operator==(const WString &other) const {return Compare(other)<=0;} + + WString Upper() const; + WString Lower() const; + WString Reverse() const; + + ///Applies user effect on string + /** pointer should be static allocated object, or must be valid during lifetime of resulting string */ + WString Effect(IWStringEffect *effect) const; + + void SetUTF7(const char *utf7); + void SetUTF8(const char *utf8); + + ///Function converts string to SingleByte string + /** + @param codePage Platform depends code page of result + @param holder Object that holds result. Result pointer is valid during lifetime of holder. Once holder + released, pointer is invalidated. You can get resulting pointer anytime from holder reintepreting + wchar_t to char + @result pointer to string + */ + const char *AsSBString(unsigned int codePage, WString &holder); + + ///Returns multibyte string in UTF7 codepage + /**See AsSBString description*/ + const char *AsUTF7(WString &holder); + + ///Returns multibyte string in UTF7 codepage + /**See AsSBString description*/ + const char *AsUTF8(WString &holder); + + + ///Function reads string from stream + /** + Function calls streamReader repeatly until function returns zero. In each call, streamReader returns + number of characters, that has been readed. + @param sreamReader pointer to function which provides reading from a stream + @param context user defined context pointer (most in cases, pointer to stream is passed) + @param buffer space allocated for data readed from stream + @param bufferLen maximum count of characters can be written to buffer + @return streamReader returns number of characters, that has been written to buffer. Function must return zero + to stop reading + */ + void ReadFromStream(size_t (*streamReader)(wchar_t *buffer, size_t bufferLen, void *context),void *context); + + WString operator() (int from) const {return from<0?RightR(-from):Right(from);} + WString operator() (int from, int to) const + { + if (from>=0) + return to<0?Mid(from,-to):Mid(from,to-from); + else + return to<0?Mid(GetLength()+from,-to):Mid(GetLength()+from,GetLength()-from-to); + } + + ///Enables global string sharing. + /** Function Share allows share strings that contains same text. It can reduce memory + usage. Function is useful when there is many objects that contains string with same text. + + Basically, two strings is shared, if one string is created as copy of another string. Strings + is sharing they content, until one of them is modified. + + Calling Share function, string is registered for global sharing. If string with same content is already + registered, then content of current string is released, and string is shared. + + To successfully share two strings, both strings must call Share() function. Sharing is provided until one + of strings is modified. After modifications are done, Share function of modified string must be called again. + + Remember: Global sharing can reduce amount of memory, if there are multiple strings that containging + the same content. But sharing of each unique string takes small piece of memory to store sharing + informations. + + To share string automatically, use WSharedString class + WSC strings cannot be shared! + */ + void Share() const + { + WStringProxy *curref=_ref; + GetString(); + _ref=WStringMemory::ShareString(curref); + _ref->AddRef(); + curref->Release(); + } + + ///Disables global string sharing + /** Function unregisters string from global sharing database. If string is shared, function doesn't break + it. But all strings that currently sharing content will not be shared with newly created strings. + */ + void Unshare() + { + WStringMemory::UnshareString(_ref); + } +}; + +///Function will create constant WString +/** function will not copy content of string. Only creates reference to string + Using WStringConst is faster for strings in code +@exmple result=a+WStringConst(L"text")+b; +*/ +const WString WStringConst(const wchar_t *text); + +///Macro to easy convert incode string to WString +/** +function also marks text wide. +@example WString text=WSC("Hello world"); +*/ +#define WSC(x) WStringConst(L##x) +///Macro to easy convert any wchar_t buffer to constant WString +/** +IMPORTANT NOTE!: Buffer must exists until string is rendered. +If you are using WSCB in function, don't forget call GetString before function exits +If you are excepting additional string operations outside function, using standard +WString conversion can be more effecient. +*/ +#define WSCB(x) WStringConst(x) + + + +class WSharedString: public WString +{ +public: + WSharedString() {} + + ///constructs string. + explicit WSharedString(const wchar_t *string):WString(string) {Share();} + + ///constructs string from wide-char array with specified length + WSharedString(const wchar_t *string, size_t sz):WString(string,sz) {Share();}; + + ///copy constructor + /**constructor doesn't copy the string, only reference. + String is shared until it is changed + */ + WSharedString(const WSharedString &other):WString(other) {} + WSharedString(const WString &other):WString(other) {Share();} + + ///constructs string from multi-byte string. codePage specified code page of string + WSharedString(const char *sbstring, unsigned int codePage):WString(sbstring,codePage) {Share();} + + ///assignment operator + /** assignment operator doesn't copy the string only reference. + String is shared until it is changed */ + WSharedString &operator=(const WString &other) + {WString::operator =(other);Share();return *this;} + + const wchar_t *GetString() const + { + const wchar_t *res=WString::GetString(); + Share(); + return res; + } + operator const wchar_t *() const {return GetString();} + wchar_t operator[](int index) const + { + assert(index<=(int)GetLength() && index>=0); + return GetString()[index]; + } + + void UnlockBuffer(int sz=-1) + { + WString::UnlockBuffer(sz); + Share(); + } + +}; + + +#endif // !defined(AFX_WSTRING_H__481164FB_3BB7_4824_B0E3_8B371F0AAF3A__INCLUDED_) diff --git a/DDLReader/WStringMemory.cpp b/DDLReader/WStringMemory.cpp new file mode 100644 index 0000000..947ed02 --- /dev/null +++ b/DDLReader/WStringMemory.cpp @@ -0,0 +1,397 @@ +// WStringMemorySingleThread.cpp: implementation of the WStringMemory class. +// +////////////////////////////////////////////////////////////////////// + +#include +#include +#include "WStringMemory.h" +#include "WStringProxy.h" +#include +#include +#include + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +#ifdef _MT //multithreading +#define WSTRING_MT +#endif + +#ifdef WSTRING_MT //multithreading + + +struct WStringMTLock +{ + WStringProxy *_lockProxy; + LONG _recursionCount; + DWORD _owner; + HANDLE _event; + WStringMTLock(WStringProxy *x):_lockProxy(x) {} + WStringMTLock():_lockProxy(NULL) {} + + bool operator==(const WStringMTLock &other) const {return _lockProxy==other._lockProxy;} + bool operator!=(const WStringMTLock &other) const {return _lockProxy!=other._lockProxy;} + bool operator>=(const WStringMTLock &other) const {return _lockProxy>=other._lockProxy;} + bool operator<=(const WStringMTLock &other) const {return _lockProxy<=other._lockProxy;} + bool operator>(const WStringMTLock &other) const {return _lockProxy>other._lockProxy;} + bool operator<(const WStringMTLock &other) const {return _lockProxy *GLockDB=NULL; //Lock proxy database + +static void exitMT() +{ + DeleteCriticalSection(&GLocker); +} + + +static void OnStartup() +{ + InitializeCriticalSection(&GLocker); + atexit(exitMT); +} + +#define ON_STARTUP_PRIORITY_NORMAL OnStartup +#include + +#endif + + + +#define WS_MAXFREELISTS 32 +#define WS_FREELISTSTEP 32 +#define WS_TOTALMAXFREEKBYTES 256 + +#define WS_MAXIMUMFASTALLOC (WS_MAXFREELISTS*WS_FREELISTSTEP) + +#define WS_MAXFREEBYTES PerSlotMaxAlloc + + +static size_t PerSlotMaxAlloc=(WS_TOTALMAXFREEKBYTES*1024/WS_MAXFREELISTS); +static WStringProxy *FreeList=NULL; +static void **StringFreeList[WS_MAXFREELISTS]; +static size_t StringFreeBytes[WS_MAXFREELISTS]; +static bool InitManager=true; + + +static void InitManagerPointers() +{ + memset(StringFreeList,0,sizeof(StringFreeList)); + memset(StringFreeBytes,0,sizeof(StringFreeBytes)); + InitManager=false; +} + +static void *AllocStringBlock(size_t sz) +{ + if (InitManager) InitManagerPointers(); + if (sz>WS_MAXIMUMFASTALLOC) return malloc(sz); + int pos=(sz+WS_FREELISTSTEP-1)/WS_FREELISTSTEP; + void **nxt=StringFreeList[pos]; + if (nxt==0) + { + printf("malloc %d\n",pos*WS_FREELISTSTEP); + return malloc(pos*WS_FREELISTSTEP); + } + printf("fast_alloc %d\n",pos*WS_FREELISTSTEP); + StringFreeList[pos]=(void **)(*nxt); + StringFreeBytes[pos]-=_msize(nxt); + return nxt; +} + +static void DeallocStringBlock(void *ptr) +{ + size_t sz=_msize(ptr); + if (sz>WS_MAXIMUMFASTALLOC) {free(ptr);return;} + int pos=(sz+WS_FREELISTSTEP-1)/WS_FREELISTSTEP; + if (sz+StringFreeBytes[pos]>WS_MAXFREEBYTES) + { + printf("free %d\n",sz); + free(ptr);return; + } + void **proxy=(void **)ptr; + *proxy=(void *)StringFreeList[pos]; + StringFreeList[pos]=proxy; + StringFreeBytes[pos]+=sz; + printf("fast_free %d\n",sz); +} + + +static inline void *operator new(size_t alloc,size_t sz) +{ + return AllocStringBlock(sz+alloc); +} + +static inline void operator delete(void *p,size_t alloc) +{ + DeallocStringBlock(p); +} + +static inline void *operator new(size_t sz,void *ptr) +{ + return ptr; +} + +static inline void operator delete(void *ptr,void *p) +{ +} + +WStringProxy * WStringMemory::AllocString(const wchar_t *text, size_t size) +{ +#ifdef WSTRING_MT + EnterCriticalSection(&GLocker); +#endif + assert(size!=0 || text!=0); + if (size==0) size=wcslen(text); + WStringProxy *proxy=new((size+1)*sizeof(wchar_t)) WStringProxy(size,0,0); + wchar_t *alloctext=const_cast(proxy->GetStringFromMemBlock()); + if (text) wcsncpy(alloctext,text,size); + alloctext[size]=0; + if (proxy->_redirect==0) + { + proxy->_redirect=alloctext; + proxy->_blockData2=1; + } +#ifdef WSTRING_MT + LeaveCriticalSection(&GLocker); +#endif + return proxy; +} + +WStringProxy * WStringMemory::AllocProxy(const WStringProxy &templateProxy) +{ + WStringProxy * res; +#ifdef WSTRING_MT + EnterCriticalSection(&GLocker); +#endif + if (FreeList==NULL) res=new WStringProxy(templateProxy); + else + { + WStringProxy *alloc=FreeList; + FreeList=alloc->_baseString; + res=new((void *)alloc) WStringProxy(templateProxy); + } +#ifdef WSTRING_MT + LeaveCriticalSection(&GLocker); +#endif + return res; +} + +void WStringMemory::FreeProxy(WStringProxy *proxy) +{ +#ifdef WSTRING_MT + EnterCriticalSection(&GLocker); +#endif + if (proxy->_operation==proxy->OpMemBlck && !(proxy->_blockData2==0 && proxy->_redirect!=NULL)) + { + if (proxy->_blockData2==2) UnshareString(proxy); + DeallocStringBlock(proxy); + } + else + { + proxy->~WStringProxy(); + proxy->_baseString=FreeList; + FreeList=proxy; + } +#ifdef WSTRING_MT + LeaveCriticalSection(&GLocker); +#endif +} + +#ifdef WSTRING_MT + +void WStringMemory::LockProxy( WStringProxy *proxy) +{ +nextTry: + EnterCriticalSection(&GLocker); + WStringMTLock srch(proxy),*found; + if (GLockDB==NULL) GLockDB=new BTree(16); + found=GLockDB->Find(srch); + if (found==NULL) + { + srch._event=NULL; + srch._owner=GetCurrentThreadId(); + srch._recursionCount=1; + GLockDB->Add(srch); + } + else + { + if (found->_owner!=GetCurrentThreadId()) + { + HANDLE w=found->_event; + if (w==0) {w=found->_event=CreateEvent(NULL,TRUE,FALSE,NULL);} + LeaveCriticalSection(&GLocker); //leave section + WaitForSingleObject(w,INFINITE); + goto nextTry; + } + else + { + found->_recursionCount++; + } + } + LeaveCriticalSection(&GLocker); //leave section +} + +void WStringMemory::UnlockProxy( WStringProxy *proxy) +{ + EnterCriticalSection(&GLocker); + WStringMTLock srch(proxy),*found; + found=GLockDB->Find(srch); + if (found) + { + if (--found->_recursionCount==0) + { + if (found->_event!=NULL) + { + SetEvent(found->_event); + CloseHandle(found->_event); + } + GLockDB->Remove(*found); + } + } + LeaveCriticalSection(&GLocker); +} + + +void WStringMemory::AddRefProxy(WStringProxy *proxy) +{ + InterlockedIncrement(reinterpret_cast(&proxy->_refCount)); +} + +bool WStringMemory::ReleaseRefProxy(WStringProxy *proxy) +{ + LONG res=InterlockedDecrement(reinterpret_cast(&proxy->_refCount)); + if (res<0) res=InterlockedIncrement(reinterpret_cast(&proxy->_refCount)); + return res==0; +} + +#else +void WStringMemory::LockProxy( WStringProxy *proxy) +{ + //not needed in single thread environment +} + +void WStringMemory::UnlockProxy( WStringProxy *proxy) +{ + //not needed in single thread environment +} + + +void WStringMemory::AddRefProxy(WStringProxy *proxy) +{ + //no special handling in single thread environment + ++proxy->_refCount; +} + +bool WStringMemory::ReleaseRefProxy(WStringProxy *proxy) +{ + //no special handling in single thread environment + if (proxy->_refCount) --proxy->_refCount; + return proxy->_refCount==0; +} + +#endif +void WStringMemory::FreeExtra() +{ +#ifdef WSTRING_MT + EnterCriticalSection(&GLocker); +#endif + while (FreeList) + { + void *proxy=FreeList; + FreeList=FreeList->_baseString; + free(proxy); + } + for (int i=0;i_redirect,other._str->_redirect); + } + + bool operator==(const ShareDBItem& other) const {return Compare(other)==0;} + bool operator>=(const ShareDBItem& other) const {return Compare(other)>=0;} + bool operator<=(const ShareDBItem& other) const {return Compare(other)<=0;} + bool operator!=(const ShareDBItem& other) const {return Compare(other)!=0;} + bool operator>(const ShareDBItem& other) const {return Compare(other)>0;} + bool operator<(const ShareDBItem& other) const {return Compare(other)<0;} +}; + +static BTree *GDB=NULL; + +WStringProxy *WStringMemory::ShareString(WStringProxy *proxy) +{ + if (proxy->_operation!=WStringProxy::OpMemBlck || proxy->_blockData2==0 || proxy->_blockData2==2) return proxy; + +#ifdef WSTRING_MT + EnterCriticalSection(&GLocker); +#endif + + if (GDB==NULL) GDB=new BTree; + + proxy->_blockData2=2; //block is subject of sharing + proxy->_redirect=proxy->GetStringFromMemBlock(); //setup pointer to string + ShareDBItem *found=GDB->Find(ShareDBItem(proxy)); + if (found) {proxy->_blockData2=1;proxy=found->_str;} + else GDB->Add(ShareDBItem(proxy)); +#ifdef WSTRING_MT + LeaveCriticalSection(&GLocker); +#endif + return proxy; +} + +void WStringMemory::UnshareString(WStringProxy *proxy) +{ + if (proxy->_operation!=WStringProxy::OpMemBlck || proxy->_blockData2!=2) return; + if (GDB==NULL) return; +#ifdef WSTRING_MT + EnterCriticalSection(&GLocker); +#endif + GDB->Remove(ShareDBItem(proxy)); + proxy->_blockData2=1; +#ifdef WSTRING_MT + LeaveCriticalSection(&GLocker); +#endif +} \ No newline at end of file diff --git a/DDLReader/WStringMemory.h b/DDLReader/WStringMemory.h new file mode 100644 index 0000000..a81b08e --- /dev/null +++ b/DDLReader/WStringMemory.h @@ -0,0 +1,61 @@ +// WStringMemory.h: interface for the WStringMemory class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_WSTRINGMEMORY_H__79693029_4788_4099_9A97_92AF310A7AD5__INCLUDED_) +#define AFX_WSTRINGMEMORY_H__79693029_4788_4099_9A97_92AF310A7AD5__INCLUDED_ + +#include + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +class WStringProxy; + +class WStringMemory +{ +public: + + static WStringProxy * AllocString(const wchar_t *text, size_t size); + static WStringProxy * AllocProxy(const WStringProxy &templateProxy); + static void FreeProxy(WStringProxy *proxy); + static void LockProxy(WStringProxy *proxy); + static void UnlockProxy(WStringProxy *proxy); + + //Releases extra memory leaved for future fast allocations + static void FreeExtra(); + + //Support addref for proxy - Single- or Multi- thread support + static void AddRefProxy(WStringProxy *proxy); + + //Support addref for proxy - Single- or Multi- thread support + //returns true, when counter reached zero + static bool ReleaseRefProxy(WStringProxy *proxy); + + ///Gets statistics about memory manager + /** + @param details optional pointer to 32 size_t items. Array will be filled + with sizes of each string fastalloc group. + @return function returns total bytes allocated for string fast allocation. + (This number should be below 256KB) + */ + static size_t GetStatistics(size_t *details=NULL); + + ///Function allows sharing the strings + /** This function is called by WString::Share function + Function mark proxy shared. If string is same as shared, + it returns pointer to proxy with proxy of string that contains + the same text. + Read description of WString::Share for more informations + */ + static WStringProxy *ShareString(WStringProxy *proxy); + + ///Function disables sharing of the string + static void UnshareString(WStringProxy *proxy); + +}; + + + +#endif // !defined(AFX_WSTRINGMEMORY_H__79693029_4788_4099_9A97_92AF310A7AD5__INCLUDED_) diff --git a/DDLReader/WStringProxy.cpp b/DDLReader/WStringProxy.cpp new file mode 100644 index 0000000..6b93900 --- /dev/null +++ b/DDLReader/WStringProxy.cpp @@ -0,0 +1,185 @@ +// WStringProxy.cpp: implementation of the WStringProxy class. +// +////////////////////////////////////////////////////////////////////// + + +#include "WStringProxy.h" + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +/** Funkce vytvo transitivn uzvr. +to znamen, e zru vechny zetzen redirecty. +*/ +WStringProxy *WStringProxy::TransitivniUzaver() +{ + if (_operation==OpSubstr && _offset==0 && _stringSize==_baseString->GetLength()) + { + WStringProxy *next=_baseString->TransitivniUzaver(); + if (next==NULL) return this; + next->AddRef(); + _baseString->Release(); + _baseString=next; + return next; + } + return NULL; +} + +/** Main render procedure +It creates allocates buffer proxy and renders tree into it +Then turns self into redirect proxy a redirect self into newly created string +Rerurns pointer to newly created proxy +*/ +WStringProxy *WStringProxy::RenderString() +{ + if (_operation==OpMemBlck) return this; + + WStringProxy *pp=TransitivniUzaver(); + if (pp!=NULL) return pp->_baseString->RenderString(); + + WStringProxy *newProxy=WStringMemory::AllocString(NULL,_stringSize); + wchar_t *renderPtr=const_cast(newProxy->GetStringFromMemBlock()); + + RenderStringToBuffer(renderPtr); + + newProxy->AddRef(); + this->~WStringProxy(); + _operation=OpSubstr; + _offset=0; + _baseString=newProxy; + + return newProxy; +} + +/** Function renders simple effect into buffer +Function needs buffer with nul terminated string +*/ +void WStringProxy::RenderSimpleEffect(wchar_t *renderPtr) +{ + assert(_operation==OpEffect); + switch (_effect) + { + case EfLower: wcslwr(renderPtr);break; + case EfUpper: wcsupr(renderPtr);break; + case EfReverse: wcsrev(renderPtr);break; + } + +} + +/** Light phase of rendering. Used to render string that is not +created from substring. This part is optimized for concat and user effects +When substring must be rendered, function call RenderStringToBufferSubstr to +render substring. +*/ +void WStringProxy::RenderStringToBuffer(wchar_t *renderPtr) +{ + WStringMemory::LockProxy(this); + switch (_operation) + { + case OpConcat: + _baseString->RenderStringToBuffer(renderPtr); + _secondString->RenderStringToBuffer(renderPtr+_baseString->GetLength()); + break; + case OpSubstr: + { + _baseString->RenderStringToBufferSubstr(renderPtr,_offset,GetLength()); + } + break; + case OpMemBlck: + { + const wchar_t *str=GetStringFromMemBlock(); + wcsncpy(renderPtr,str,_stringSize); + } + break; + case OpEffect: + { + unsigned long offset=0; + renderPtr[_stringSize]=0; //we can append zero, because right side of string is not yet rendered + //if this is end of string, one extra character for zero is also allocated. + //efect functions can rely on it. + if (_blockData2>=256) offset=_userEffect->PreRenderString(renderPtr,_baseString->GetLength()); //call prerender to prepare begin of buffer + _baseString->RenderStringToBuffer(renderPtr+offset); //render string to rest of buffer + if (_blockData2>=256) _userEffect->RenderString(renderPtr,_baseString->GetLength()); //apply effect to buffer + else RenderSimpleEffect(renderPtr); + } + break; + }; + WStringMemory::UnlockProxy(this); +} + +/** +Deep phase of rendering. Function can render substrings, or render substring of two +concated strings. Function can also perform partial effect on string. Function cannot +handle partial user effect, so this effects are converted to things strings. +*/ +void WStringProxy::RenderStringToBufferSubstr(wchar_t *renderPtr, size_t offset, size_t size) +{ + WStringMemory::LockProxy(this); + switch (_operation) + { + case OpConcat: + { + //process substring of concat + //count characters in buffer + size_t rendered; + //when string starts in left string + if (_baseString->GetLength()>offset) + { + //calculate total characters that may be rendered + rendered=_baseString->GetLength()-offset; + //but limit it to request size + if (rendered>size) rendered=size; + //render substring into buffer + _baseString->RenderStringToBufferSubstr(renderPtr,offset,rendered); + } + else + //no character has been rendered + rendered=0; + + //there is still characters remained to render. We will take it from second string + if (size-rendered>0) + { + if (offset>_baseString->GetLength()) offset-=_baseString->GetLength(); + else offset=0; + _secondString->RenderStringToBufferSubstr(renderPtr+rendered,offset,size-rendered); + } + } + break; + case OpSubstr: + { //rendering substrings is very easy + offset+=_offset; //add offset of substring + assert(offset+size<=GetLength()); //check length + //render substring + this->RenderStringToBufferSubstr(renderPtr,offset,size); + } + break; + case OpMemBlck: + { + //rendering from memory, final stop in recursion + //Get pointer string + const wchar_t *str=GetStringFromMemBlock(); + //copy substring from string into render buffer + wcsncpy(renderPtr,str+offset,size); + } + break; + case OpEffect: + if (_blockData2>=256) //interface cannot handle partial rendering + { + RenderString(); //convert proxy to simple redirect and render it + RenderStringToBufferSubstr(renderPtr,offset,size); //now we are able to cut out part + } + else + { + //all standard effects maps string 1:1 + //first get content of substring into buffer + _baseString->RenderStringToBufferSubstr(renderPtr,offset,size); + //we can append zero, because right side of string is not yet rendered + renderPtr[size]=0; + //process effect on target + RenderSimpleEffect(renderPtr); + } + break; + }; + WStringMemory::UnlockProxy(this); +} \ No newline at end of file diff --git a/DDLReader/WStringProxy.h b/DDLReader/WStringProxy.h new file mode 100644 index 0000000..e5f470b --- /dev/null +++ b/DDLReader/WStringProxy.h @@ -0,0 +1,232 @@ +// WStringProxy.h: interface for the WStringProxy class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_WSTRINGPROXY_H__863ADE82_7789_4E54_BE7D_B8F0740FD81B__INCLUDED_) +#define AFX_WSTRINGPROXY_H__863ADE82_7789_4E54_BE7D_B8F0740FD81B__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "WStringMemory.h" +#include "IWStringEffect.h" +#include +#include +#include +#include + +/* +List of proxy types + +Memory_Proxy _operation=OpMemBlck + _blockData==0 and _blockData2==0 + or + _blockData!=0 and _blockData2!=0 + (_redirect - debug pointer) + (_blockData - 1) + +Proxy_Const _operation=OpMemBlck + _redirect - pointer to string + _blockData2=0 + +Proxy_Shared _operation=OpMemBlck + _redirect - pointer to string + _blockData2=2; + +Proxy_Immediate _operation=OpMemBlck + _blockData>0xFFFF + _blockData2>0xFFFF + both parameters are used by immediate memory manager + +Proxy_Concat _operation=OpConcat + _baseString and _secondString is valid + +Proxy_Link _operation=OpSubstr + _baseString is valid + _stringSize==_baseString->_stringSize + _offset==0; + NOTE: Can be used without rendering + +Proxy_RightSub _operation=OpSubstr + _baseString is valid + _offset<=_baseString->_stringSize + _stringSize==_baseString->_stringSize-_offset + NOTE: Can be used without rendering + +Proxy_SubString _operation=OpSubstr + _baseString is valid + _offset<=_baseString->_stringSize + _stringSize<=_baseString->_stringSize-_offset + +Proxy_Effect _operation=OpEffect + _baseString is valid + _stringSize=_baseString->_stringSize + _effect defining effect code < 0xFFFF + +Proxy_UserEffect _operation=OpEffect + _baseString is valid + _stringSize=_baseString->_stringSize + _effect>0xFFFF + _userEffect defining pointer to effect interface + +*/ +class WStringProxy +{ +public: + enum Operation + { + OpConcat=0, //proxy contains two links to concat it + OpSubstr=1, //proxy contains link to another proxy and specified substring + OpMemBlck=-2, //proxy contains informations about following string + OpEffect=-1, //proxy describing some efect with string + }; + + enum Effect + { + EfLower, //effect lower case + EfUpper, //effect upper case + EfReverse, //effect reverse string + }; +public: + + unsigned long _refCount; //reference count + unsigned long _stringSize:30; //string size in characters (maximum size 1073741823 characters ~ 2147483646 bytes) + Operation _operation:2; //operation with string or proxy type + + union + { + WStringProxy *_baseString; //pointer to next proxy referenced by this proxy + unsigned long _blockData; //user defined block data for OpMemBlock proxy type + const wchar_t *_redirect; //used for OpMemBlock, when _blockData2 is zero. + }; + + union + { + WStringProxy *_secondString; //pointer to second string for OpConcat + unsigned long _offset; //offset of substring for OpSubstr + Effect _effect; //effect selector for OpEffect + IWStringEffect *_userEffect; //user effect defined by IWStringEffect interface (valid when _effect is invalid) + unsigned long _blockData2; //user defined block data for OpMemBlock proxy type - exception: if this value is zero, member _redirect is valid + + }; + + + void RenderStringToBuffer(wchar_t *renderPtr); + void RenderStringToBufferSubstr(wchar_t *renderPtr, size_t offset, size_t size); + WStringProxy *TransitivniUzaver(); + void RenderSimpleEffect(wchar_t *renderPtr); + +public: + WStringProxy():_refCount(0),_operation(OpSubstr),_stringSize(0),_baseString(0),_secondString(0) {} //inicializes empty string proxy + + WStringProxy(WStringProxy *other): + _refCount(0), + _stringSize(other->GetLength()), + _baseString(other), + _operation(OpSubstr), + _offset(0) + {_baseString->AddRef();} + + WStringProxy(WStringProxy *other, unsigned long offset, unsigned long size): + _refCount(0), + _stringSize(size), + _baseString(other), + _operation(OpSubstr), + _offset(offset) + {_baseString->AddRef();} + + WStringProxy(WStringProxy *a, WStringProxy *b): + _refCount(0), + _stringSize(a->GetLength()+b->GetLength()), + _baseString(a), + _operation(OpConcat), + _secondString(b) + {_baseString->AddRef();_secondString->AddRef();} + + WStringProxy(WStringProxy *a, Effect effect): + _refCount(0), + _stringSize(a->GetLength()), + _baseString(a), + _operation(OpEffect), + _effect(effect) + {_baseString->AddRef();} + + WStringProxy(WStringProxy *a, IWStringEffect *userEffect): + _refCount(0), + _stringSize(a->GetLength()+userEffect->GetEffectExtraSize(a->GetLength())), + _baseString(a), + _operation(OpEffect), + _userEffect(userEffect) + {_baseString->AddRef();} + + WStringProxy(unsigned long size, unsigned long user1, unsigned long user2): + _refCount(0), + _stringSize(size), + _operation(OpMemBlck), + _blockData(user1), + _blockData2(user2) + {} + + WStringProxy(const wchar_t *imText): + _refCount(0), + _stringSize(wcslen(imText)), + _redirect(imText), + _blockData2(0), + _operation(OpMemBlck) + {} + + WStringProxy(const WStringProxy &other) + { + memcpy(this,&other,sizeof(*this)); + if (_operation!=OpMemBlck) _baseString->AddRef(); + if (_operation==OpConcat) _secondString->AddRef(); + } + + WStringProxy& operator=(const WStringProxy &other) + { + WStringProxy::~WStringProxy(); //call destructor to destruct current proxy + memcpy(this,&other,sizeof(*this)); //construct new proxy from template + if (_operation!=OpMemBlck) _baseString->AddRef(); + if (_operation==OpConcat) _secondString->AddRef(); + } + + WStringProxy *RenderString(); + + ~WStringProxy() + { + if (_operation!=OpMemBlck) _baseString->Release(); + if (_operation==OpConcat) _secondString->Release(); + } + + + unsigned long GetLength() {return _stringSize;} + void AddRef() {if (this) WStringMemory::AddRefProxy(this);} + void Release() {if (this) if (WStringMemory::ReleaseRefProxy(this)) WStringMemory::FreeProxy(this);} + + const wchar_t *GetString() + { + if (_operation==OpMemBlck) return (const wchar_t *)(this+1); + WStringProxy *p=RenderString(); + (*this)=*p; + return (const wchar_t *)(p+1); + } + + const wchar_t *GetStringFromMemBlock() + { + assert(_operation==OpMemBlck); + if (_blockData2==0 && _redirect!=NULL) return _redirect; + else return (const wchar_t *)(this+1); + } + + bool IsShared() {return _refCount>1;} + + void RecalcLength() + { + const wchar_t *str=GetStringFromMemBlock(); + _stringSize=wcslen(str); + } + +}; + +#endif // !defined(AFX_WSTRINGPROXY_H__863ADE82_7789_4E54_BE7D_B8F0740FD81B__INCLUDED_) diff --git a/DDLReader/res/DDLReader.ico b/DDLReader/res/DDLReader.ico new file mode 100644 index 0000000000000000000000000000000000000000..7eef0bcbe6580a6f464d688906172c2d9de44262 GIT binary patch literal 1078 zcmc&zF>b>!3}jLb9s)T}@Kod(893@u8ajANzT`op9^o+)S?=nU(FD@%0s)Sg^oyC8{H z9myetc;MEP)59v(LMa~xK8Yu^jIR*H22uCFiq5%C{s7(PJi>o15i^bmX4(vPxWAio z9ryY#AU_jfnd047-@`)XzL?%iS$gQyFP{44kS9X)fN{{QoL~hO-&=q&20Zr*cxFAt PkaNE{wR~2C$NfnjhSXWT literal 0 HcmV?d00001 diff --git a/DDLReader/res/DDLReader.rc2 b/DDLReader/res/DDLReader.rc2 new file mode 100644 index 0000000..35693f0 --- /dev/null +++ b/DDLReader/res/DDLReader.rc2 @@ -0,0 +1,13 @@ +// +// DDLREADER.RC2 - resources Microsoft Visual C++ does not edit directly +// + +#ifdef APSTUDIO_INVOKED + #error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// Add manually edited resources here... + +///////////////////////////////////////////////////////////////////////////// diff --git a/DDLReader/resource.h b/DDLReader/resource.h new file mode 100644 index 0000000..2625141 --- /dev/null +++ b/DDLReader/resource.h @@ -0,0 +1,49 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by DDLReader.rc +// +#define IDM_ABOUTBOX 0x0010 +#define IDD_ABOUTBOX 100 +#define IDS_ABOUTBOX 101 +#define IDD_DDLREADER_DIALOG 102 +#define IDS_FILEOPENFAILED 102 +#define IDC_HEADGROUP 103 +#define IDC_HEADFNAME 104 +#define IDC_HEADSIZE 105 +#define IDC_HEADOFFSET 106 +#define IDS_DDLFILTER 107 +#define IDC_GROUP_GRAPHICS 108 +#define IDC_GROUP_SOUNDS 109 +#define IDC_GROUP_FONTS 110 +#define IDC_GROUP_BASIC 111 +#define IDC_GROUP_ITEMS 112 +#define IDC_GROUP_MONSTERS 113 +#define IDC_GROUP_DIALOGS 114 +#define IDC_GROUP_UNSPECIFIED 115 +#define IDC_GROUP_UNKNOWN 116 +#define IDS_UNABLETOCREATEFILE 117 +#define IDS_UNABLETOEXTACTDATA 118 +#define IDR_MAINFRAME 128 +#define IDD_PROGRESS 129 +#define IDD_EXPORTING 129 +#define IDC_FILELIST 1001 +#define IDC_FOLDER 1002 +#define IDC_BROWSE 1003 +#define IDC_EXPORT 1004 +#define IDC_POPISEK 1005 +#define IDC_DDLFILE 1006 +#define IDC_DDLBROWSE 1007 +#define IDC_PROGRESS 1008 +#define IDC_NAME 1009 +#define IDC_BUTTON1 1010 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 130 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1011 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/FONT/BIG.FON b/FONT/BIG.FON new file mode 100644 index 0000000000000000000000000000000000000000..8034176ce49d08c2a54ffdd189e1b4665f2e4ae9 GIT binary patch literal 12309 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

_BnTbhe|Z(p>|wL0aw3g0$E@WG6w~DOyMtn8Fx$ zQMB?sdulA!RMHmTumg9aPP|nQCDGA^*gnC(ZXljvbfnxi;?@FblN2V!2uc7x<#L88L7{Gi19>d@~;i~bF(GuN3C2N%A?et zOCH&eIzJUNg%zZ;lY|B3#!{-~Xcs!E!DXYdk_b~~@0a*+XJbqdq;B11H6aR4G&MD? ztK!NGT&)MK*wSWIi1v__}LzmJ7(QA zS$8KQt_kGiiaM({|F=p7Qp+vMDc` zN4GE{Q%qM-5ZkL3dh^2h^8JX2*x9HeU8;6;u~8xO&|ox)>VZ-X0+@;_8~qXSw{VB| zEw4#gd8@FNnRUKlWql%q3OS3)ctqh-t=;W8t?Q#qhw3ci~et{OK}=N35U0%)5;I24lk$$VCO=4EQ@M##0xl+f@u zG7p{fCf>6QpIp`fjnE74dd(+<*++%BE*1_n#R?SSGu-jqX~CRLFB2QrrL56@a;u52 zK4DB`TyhP0Ra6LanIC!^=P3nF0TA-7Mv6L$`TQWAXuu3)_i_zB?8P!`S*4je3NwE7nIq!B_JW5Um}1ty}6%KX2oop;pA$%P5-` z1T(ZghjJy(oDo41UZ@@l<5D>{y)g zq$OLs2@9duiRysQ8U%YCaibzGOGI&;Fq0__>)~s+bG_iGdbzpKQ`E3dRf^3)3Uqa# zVZL}V4}fMMr!FFmKuyiGf?b)K_0+aB;T!u%VT_w*3Qm;qfrs9I!3K1-JF2dOZRofv!|R8 z!Xs`+qat+H`|U$)rg@pEMs83{E6ymFVsA8c*qQb$u(WbZKy(soDX_8c(K{*}Zbe`7 zj-K0`_eoc3XTPo32)9xxVN^+hXd*9wgX>-=yTEC}6)rd9hbj55$_G2i+fSSw85rS! z>|AdelGASnQ@U!OI5Ez>VX7>!-0VZen4=<%)mU$xVo$K^3RLFZmEx>oaK_wYS{y*A ze`HnLC)qAcallTd6MO|?sS6_HD;{R6M31;6ahp6#*B)6c_VM#3V2>3%uY5gosfEjA zm+oTioeS!8;1y7;%O{;I;S`C^-+{wn8BxAAAP4othN0P)KtPh5l9eSLC8Rto6&@OcEY~}ab=KM9HZ*;MhCWwnih8je2 zq-(F7pXS6kgS$uVd&k$@w%HTwV^b3Z)x~$lVKiSV=~r|8T?SZA*F=2)q_L2I93V(b za`3||@_`#|(E%_0c%U7`U}df=2fXji{ijLEqvq$#fbR}h9H6r_pA@^1#jMjAb+bcl z^5`873mqJ|a^6tDgfuT;8$)�ZC!^-Eu_~t#}?$aW|%+iLtr;*8oaAx~H?$ttgm+ z1lqU6pebf8JZEFbGow-L&lw7D)J&hy)sxu?Fmm3ofHDi^IJ<+C)__WP_QWfe}O z9c>65dSDC5bTy?L_MyJT98TwYY|r%q^W51RJR~F+|1m^dNGKg%Qx>M*xbcWVW7uM( z7KETL!&s6%Om>dp*Ryb8100k^)KJX^&IrE5ECVqs5JLD_+f>@pVR9guaQA4SZ_L`_ zWZ`0y(lK--LlOv#x@W6kLiSC6Pc7>T-p;9;a$8kkbIu0BL&bYp_xZ(SQRb_9aL4v?j zvQgGz)`TsgL6KNtPLCNaqy~88Ge_V$3_vbZDF6eqXQIU_l*Uq5(N_*ekas{=a^;@( z|k75MSwjG#P zdO}S&pQ_<6|4M2GHrYWay;hoczAURZyNm%CRfa8GWXT^rmh3Tut=!X0qr2>`|GDx| z?OPF*vWZURsBA+=4QVt`HeQYQxFdRG@)>%ppV51fIzOfJ18H1Z%Ie|P5YstDtNX7Y zh=N`j1|IJ5&B2QCChyYcGB1uF>4O*N{R0k6k$zjUd#evl-K#pcuI@H&?wk?Q&3@qc z16%!SjlWA-T9qjgaa9S03C1?p@Ax^mm)RN;Luo6U--PLxH)F<)=><)4H9~okJVsw< zNnAt08NBPk!9*Rr4HLiV_iw~IKOO0svj**{3BeuDLyj~>Kv*Sw@|nP%9iV7F2lam` z7Ac!`Su(K!f0wx)MgrY9t?rSXL$_(hYo()%MG1j|)c>bKXn1brrTo-9@y#x||50j3 zYB#!KZFr5@gTvUy{m~s(+4sKsEedghZoecxLQtTZZ^2}g)&TUu%R}oqGo_fTq0LEw ziyC?FbJARmjYFpbhj2OQk|CpfJWlZ=TK-F3rSw)oE}EgF1T|yu^MBu)Ty71Z602S+k;s>t9MK)E&YnN zw?tHaOvETyHX@;$nH>noE)UPg&pB*`<70vBIMY?$p0cWQ4yRBsV)ApAxU%-aOZr?p3q)F1YD3zRdthE~VLttJfxHNqvD(H}B41V{&%CqCliYS+%{f9M*b zf8FZm9n?uqL;)yGaUAIz{3GjN0R*R$zu6#enODs2zTc87uCI?)0$hBD>&ZU4O5V!6 pvR4>$ouScJ;?3&@&9q2{$JjJK#l+a literal 0 HcmV?d00001 diff --git a/FONT/BOLDCZ.FON b/FONT/BOLDCZ.FON new file mode 100644 index 0000000000000000000000000000000000000000..be5e16c7bc204cc269f8460b692ba38ff6f14220 GIT binary patch literal 9034 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�%Ku9Ak($R!UbWvQ_>Kw54fVA2Vtzc^TT%@>GHQDssUwIr@ zXBZHBF?KG{KC8{@p1aLFE}bkq+I`uK3z1Utg&&gprw0E=EXn6jAA6*oqxHR%nTGoK zl5FLj>HSvm_9Q8FoTK!Ga;e4;gOVx?)kCY9cl$Fq{clOIgF``99DrO6vQt|er;`Kf zeYa3+m-MesgNQraXzm&fb@s;_g^+t}{5I~L;>lh-u*JV;kYA0#UU<$uax5bWwmWPF z+jEm6siJEcN)=p5SC@>YJx;^CiX+?@>Sw4s)4@QghhPOPc{*Vlgk`-RU4iXpF`CtHNbcguQH_2{%$|xq&eYd#SnE;cX=? zj}UoKv|2r?GTTVE=B1WH;*%s(Lfh9^kK_x5J^(!8?-t@Fb9U?5)UH8u@!st)kI8Xo zlnFx;X|d-V`x@G_Q=cR$dWMTbM%96VclwX=R@u-D6>M30c;Fcf1ky+kKm z(MjnaVrisvYcg4Nw78R?;9;@GD=za|ku$5o`YgO)_5U={T_bavay7q1MlUKtONJtP z@PK~iH@!gq!3&#X&v)L1sd4;X>{8!r$1H^ylukUejnlL+F}*6Dqp0F`;i7he**|@J zY&YKehP%DXpwFT}#tNR>Oxa`?ZSmD&BdQ~!^oKv_YJLrK?pVAAUMmdQ;j4xFA@M#@!@R1@u7h01L zMyhvy;%MLmf^WX-{a zUN26O&OPT;9^kwXY|HK$)Hzdp)h|dVVZom zOVAPXv$__UWv%lqF*AOWBqz}7I!bd=oP~vXe7IjTRPeGmvo0E(af_}W2z@nkeP$(F zUE(;Z;n(%d_t;H;BIz#z3%1m-#c5}ubUJUQA0HA#DTI(;K-tmiY5PMKbwR(>WLRnx zd0l!s@eHS+L8X_)1>v3^-?L(WArWFyF=B#q!m< F`d^Q?u>$}A literal 0 HcmV?d00001 diff --git a/FONT/EUROMODE.FON b/FONT/EUROMODE.FON new file mode 100644 index 0000000000000000000000000000000000000000..398e4db5fde92ef7fb20e129993750138df2844f GIT binary patch literal 12673 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 literal 0 HcmV?d00001 diff --git a/FONT/FONT6X9.FON b/FONT/FONT6X9.FON new file mode 100644 index 0000000000000000000000000000000000000000..ddc1006824c1d914493610523dc7b6014ac50dd6 GIT binary patch literal 5593 zcmbuDJE$CG6vt;~cV}m3_H|!{Scrm1B(0!`f)Nxng@~16lR^;VqcDxw1SEo$*qB01 zp@68S>0PbRh_Cnt$wa%qX$PPMrTLg zj{Y9qQXj2v-FdnGsQ#+{vA$CGo12>3nunSfo41-TnqQjT=Faia@eAX8=Z*21@t5OY z$K~Yk3PLVNU}&3Q}FbdHsyYr@AmPhD5Orau?Yc9-iMBcdjZya zL?LBY>ZNb&M|vSqIU-W>VvKIQ?KLyhBQ!;(S5FGv>1J3@ZMQ|=euG22?!_?zb^)Fh z48wXW0b@c04dwXGz(|qLFe51o+Iu+W`rz48&H3UbZBg0&>2N(Io zpv@GBZER0OotR4rb1n5Kmwx4vO~3}u=P-0_DYGmxkm?gX1aL>*oBArx`y>oc#F04m z8`Ma66EN?QeYF)LB7 z5Hdq9L=u56g2tD@B4ke56z)PL?E*;1;ay0us-aR+Ey!IB^rI@NwKwZYA#lRik-vYn zAh@U*ilR-tWJTTxOh8)9>qS+`vt*5au_l&sZ4sSHmoovv6^8OzaBx1*xRIif zk9c(|*Uo^2a=eEq^{9_u|(UFNmaT! zma4dIlzXt*NC1noT2UKiy!5DLR&^7}02A?i->Gv@uKIXY2A85L&m$|_W?(LqX=X5Z z?gY4%l`aR?LevI_7j4w7@P=&I6Z%C1h-kM&*?sMR4ziRB6@0c~GXhtS8N>-#cZwy> zWe9)U`5;fASHtXzjD%2RV&1xMNgwN(qsNMd^?g)Qo9a&_I9D-Md4vDfU8{~zG5av(EfRStU&-Y!K~$T) zy*>!p7w~qX)aRh|bf8p6mo>%QwHIcz7ZSLuZMJ%k8CQ0JRsz)oA z+APA5lL>v^lMawh@oJ1jkdz=0l{Cxel&@haMJQea6oM5}y=?spOqR4e6Qzvbn{A*e zbWU@;R^7J!ek{YLXNG3>(1MFc@?c4Wyi3vd-i8Tw5?%IHe8~rGX~MsD71W+Peu5}t zv?3_H?Jhh_M8>h19Hion680i57=ocX?lZYbrkQTvF;FfI{37o2b@AFkUA=; z*0)P1>PzaR+_POdsa3VrfZ7;~_09p-L+OrCuV4Xl3Qg+jA{<)N=oE;IwznUI$3-Qr zT@x{O{5i0a=BhC-WMeVsDa~D2)Vf8j?x6H~BBj6kk2$LQ1uLa~>vr8UmX}J;K zBjqbH#Bo;sC9*JNW8N!@L*;&2_Z(c$4T=MlBoo>76t=COFg^u~ePX1`9UwiB>_XI~=c&uCDj_7u4hxcvbNmKYz zl|@W~0^Ot_=`pv=kR$pP)S*k;MTyc})k(Qp&acHxo;zv4Dhtq=wr}Pgt%P}oh&Ra@RhLmp3fa!sNr_0x6qn}mne~VbMyX)Oy c-@gmMy!_D$(Cz4B!=E0tzpjNJg7_uyAHTHBdjJ3c literal 0 HcmV?d00001 diff --git a/FONT/IKONES.FON b/FONT/IKONES.FON new file mode 100644 index 0000000000000000000000000000000000000000..36a9495f0ea79027037ad40e14194c0cd83ed46a GIT binary patch literal 8909 zcmeI2J&zj9UW-2?-&APMm>|u)sSBhktOw#svcx zd|Z$a#<^#Jgb*GM)|yEC1PmN#o;M=1Dyw^LPoTX8gPiTkj5i`9A|tc%tG0^YjlYh+ z>pwmJ>-l=~)y)St->-k%eAxc>$;aKR-OIW#F+Aiz5-p zU%p#af4Tk1i|?KPYWZrp9=bCaOk=V zvfdG~3|WO$ScZzf1)Kz`+QPsk>{U3Ny{uwN&&Y?kPSh@*Gj>v1#${NHboeJR@&|&-X%U1m*mEPwk{p+|0=Sk@hx3L#BnBD;b;P z20fjXpQij)45A21qFUUT{)qo*USmV%hye{ADa?kA;i?6(jV9K{(2Ed@N+K?DnIOcG zAYMen$!NwaB$aG3qY$1Yds#r9V_x&s9g z3Z(OqKUhU%R!;ZUpqeMI*#xaKwSYrIowGE;JYdE!BF!pcgH$Tt^7dI8XO1F-ymQXH z_bfbE{+#EFK=41JAczsg@V1KKE)`<94UJ_an_uLHzLJq`71$g5D#*gNQd6Sxe= zbuRGhNX=IMy(x@<%=H1Feuk;dO~8}MtRa^Z;v%~dFuDmNkm#!{fECiyMB2y+*9D~x z`@0LxpXaHUW*r~HV=(jgTuKxzI|jq$F?522tGP%x2AB*_w18dAtC<6jcz|0|3-XXO zH%FM2bJCSsrnSQxlXPksG#j!@RhEbyzb%0#p1+?*(x}|e)&u@P+&lUhOLIzwO^&6b zOj?6-n&DbU##C@@Q5hMfHe1LZ<xmO{0Wg4FS+I?_`yj=I^PgcO zPizR&49uuncArRVzVrr|Zl8CO6A~@drYTZr86Dqb8meunm`ZX|Cj;Vx{>9krQ6b)x zm5^Mxa~eZX1dyK~dl9@p)C6hp>CR6pXjcvI5g%+Rn(Wg(;8w}Bn;(jMibRTFihj|q zssAl(su0dP_D@R|0`p7=c1h^tL83|W>Cl}i)JWOS!Y=kCtj#!$;P57u17!(Gi&QCz z6fGs}?NHg9Y3fZE-NiQ*S*q{%o3hQ|GvQUY{QUO}#!w z8jeWwS`BAg4l{F57~}BBpn)2~IpLIJobT|{%R3#sRXuPD<)vg#3!C(>)DdpWAoc*Fcgj< z3v0TtnO5gkca;;NFoM-NBDiLH1Y|-SK_YAztAD~ktSYaSA<))r)&poL3kj=PM|qGw zCUV`2P$KB(${BF1e%wL?;T1>0hlg($y>Y{Ob*)9~+ICNLo2FWN^hO1I8BnUJe5IqS z6)`xz{yn_SMA8CeX;nYNdS3yjSE!SK#zsCV(@@NrS~H{TFVYf=S~S!w(pA*ORM>H- zPq|p8_FVy=|KMc2-@k}^w1yjX%ItZ3XW|z)on1!BQckJ|Dw9((Z9?fTIwpxMIi<_k zNU~swNHnrlLDG~-_HvYZZ7DmIa@SnUTq?TB$yX~Gcp3zd1$P4by?XtTr17DqAF(ue z8E1MbceVq*sgPr|T}%^mdDmtGp9lXuJT8*uT!DC=Bm%gC@|M?j~MoP-q}pf6=ECi^S=j;vZTV)r*a7;v(8RJj+M|C#3&uf zJyjSli^u&u^4=sP`QUDOo83-nBniDm#)&^EZl_+QsJul+c4f-XI`+$Kdl~iGo{Ev* zL**k4o7q&GUz^~y2+e-XyoV=G5YZksZFH$mGD7#$@VV-DD+$#xVFEg~%VE$X+jXqDJyx=v}r$#`m!?YgwVFyW2uFRZxb`kU~xpEo~< z{z$?+P2k+ybp(!&r#XWoKLsm#l?6kY6u(`)&BMbt?NQo zgXu`wG@!>)bJp?kme*K^86G&K##?62*)k2n3gpfjlOlkU?veb*|0Kv)SwzXCiJvOv Y%vNZv*JmB~gD5aI)lE0K#XTJU1xjMV;{X5v literal 0 HcmV?d00001 diff --git a/FONT/KNIHA.FON b/FONT/KNIHA.FON new file mode 100644 index 0000000000000000000000000000000000000000..371eba44cc69f42ae326ac4d753b1d839998bf51 GIT binary patch literal 8880 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 literal 0 HcmV?d00001 diff --git a/FONT/TIMESBIT.FON b/FONT/TIMESBIT.FON new file mode 100644 index 0000000000000000000000000000000000000000..4d7f635b0e379ad2b9d013866ded6b2a1a548a01 GIT binary patch literal 31710 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 literal 0 HcmV?d00001 diff --git a/FONT/TIMESE.FON b/FONT/TIMESE.FON new file mode 100644 index 0000000000000000000000000000000000000000..460b558cbdb9f4042c2d4f6ffcfa9ea52c8a38de GIT binary patch literal 11547 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 literal 0 HcmV?d00001 diff --git a/FONT/TINY.FON b/FONT/TINY.FON new file mode 100644 index 0000000000000000000000000000000000000000..371eba44cc69f42ae326ac4d753b1d839998bf51 GIT binary patch literal 8880 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 GKm83H``u6g literal 0 HcmV?d00001 diff --git a/GAME/AUTOMAP.C b/GAME/AUTOMAP.C new file mode 100644 index 0000000..04b2bb0 --- /dev/null +++ b/GAME/AUTOMAP.C @@ -0,0 +1,954 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "engine1.h" +#include +#include "globals.h" + +#define AUTOMAP_BACK RGB555(8,4,0) +#define AUTOMAP_VODA RGB555(0,15,31) +#define AUTOMAP_LAVA RGB555(31,16,0) +#define AUTOMAP_FORE RGB555(18,17,14) +#define AUTOMAP_LINE1 RGB555(13,11,10) +#define AUTOMAP_LINE2 RGB555(31,22,6) +#define AUTOMAP_MOB RGB555(31,8,8) + +#define MEDIUM_MAP 9 +#define MEDIUM_MMAP 4 +#define MEDIUM_MAP_COLOR RGB555(21,20,19) +#define MEDIUM_MAP_LINE1 RGB555(25,20,17) +#define MEDIUM_MAP_LINE2 RGB555(31,22,6) + +word stairs_colors[]= + {AUTOMAP_LINE1, + RGB555(14,12,11), + RGB555(15,14,12), + RGB555(16,15,12), + RGB555(17,16,13)}; + +word arrow_colors[]= + { + AUTOMAP_LINE1, + AUTOMAP_FORE + }; + +char shift_map(int id,int xa,int ya,int xr,int yr); +char psani_poznamek(int id,int xa,int ya,int xr,int yr); +char map_target_select(int id,int xa,int ya,int xr,int yr); +char map_target_cancel(int id,int xa,int ya,int xr,int yr); +char map_menu(int id,int xa,int ya,int xr,int yr); +char map_menu_glob_map(int id,int xa,int ya,int xr,int yr); + +char noarrows=0; +char enable_glmap=0; + +static int map_xr,map_yr; +static int cur_depth; +TSTR_LIST texty_v_mape=NULL; + +#define BOTT 378 +#define LEFT 520 + +static char cur_disables; + +#define CLK_MAP_VIEW 5 +T_CLK_MAP clk_map_view[]= + { + {MS_GAME_WIN,0,17,639,377,psani_poznamek,2,H_MS_DEFAULT}, + {-1,54,378,497,474,start_invetory,2+8,-1}, + {-1,337,0,357,14,go_map,2,H_MS_DEFAULT}, + {-1,LEFT,BOTT,639,479,map_menu,2,H_MS_DEFAULT}, + {-1,0,0,639,479,return_game,8,-1}, + }; + +#define CLK_GLOB_MAP 4 +T_CLK_MAP clk_glob_map[]= + { + {-1,54,378,497,474,start_invetory,2+8,-1}, + {-1,337,0,357,14,go_map,2,H_MS_DEFAULT}, + {-1,LEFT,BOTT,639,479,map_menu,2,H_MS_DEFAULT}, + {-1,0,0,639,479,map_menu_glob_map,8,-1}, + }; + +#define CLK_TELEPORT_VIEW 4 +T_CLK_MAP clk_teleport_view[]= + { + {MS_GAME_WIN,0,17,639,377,map_target_select,2,H_MS_DEFAULT}, + {-1,LEFT,BOTT,639,479,map_target_cancel,2,H_MS_DEFAULT}, + {-1,0,0,639,479,map_target_cancel,8,-1}, + {-1,0,0,639,479,empty_clk,0xff,-1}, + }; + + +char testclip(int x,int y) + { + return (y>=16 && y<360+16 && x>=8 && x<630); + } + +/*void shift_map_event(EVENT_MSG *msg,int *data) + { + static int smer; + + data; + if (msg->msg==E_INIT) smer=*(int *)msg->data; + else if (msg->msg==E_TIMER) + { + switch (smer) + { + case H_SIPKY_S:send_message(E_KEYBOARD,'H'*256);break; + case H_SIPKY_J:send_message(E_KEYBOARD,'P'*256);break; + case H_SIPKY_V:send_message(E_KEYBOARD,'M'*256);break; + case H_SIPKY_Z:send_message(E_KEYBOARD,'K'*256);break; + case H_SIPKY_SZ:send_message(E_KEYBOARD,'s'*256);msg->msg=-2;break; + case H_SIPKY_SV:send_message(E_KEYBOARD,'t'*256);msg->msg=-2;break; + } + } + else if (msg->msg==E_MOUSE) + { + MS_EVENT *ms; + + ms=get_mouse(msg); + if (!ms->tl1 && !ms->tl2) + { + send_message(E_DONE,E_TIMER,shift_map_event); + msg->msg=-2; + schovej_mysku(); + other_draw(); + ukaz_mysku(); + showview(0,0,0,0); + } + } + } + */ + +void save_text_to_map(int x,int y,int depth,char *text) + { + char c[512],*d; + if (text[0]==0) return; + memset(c,1,sizeof(c)); + strcpy(c+12,text); + if (texty_v_mape==NULL) texty_v_mape=create_list(8); + d=texty_v_mape[str_add(&texty_v_mape,c)]; + x=(x-320)+map_xr; + y=(y-197)+map_yr; + memcpy(d,&x,4);memcpy(d+4,&y,4);memcpy(d+8,&depth,4); + } + +static char check_for_layer(int layer) + { + int i; + TMAP_EDIT_INFO *m=map_coord; + + for(i=0;ilayer==layer && m->flags & MC_MARKED && m->flags & MC_AUTOMAP) return 1; + return 0; + } + +void ukaz_vsechny_texty_v_mape() + { + int x,y,d,i,cn; + char *c; + + if (texty_v_mape==NULL) return; + set_font(H_FLITT5,NOSHADOW(0)); + cn=str_count(texty_v_mape); + for(i=0;i640) + { + *d=e; + d--;e=*d;*d=0; if (d==c) break; + } + position(x,y);outtext(c); + *d=e; + } + else if(x<8 && x+text_width(c)>10 && y>16 && y<376) + { + char cd[2]=" "; + while (x<10 && *c) + { + cd[0]=*c++;x+=text_width(cd); + } + position(x,y);outtext(c); + } + } + } + } + +void psani_poznamek_event(EVENT_MSG *msg,void **data) + { + static int x,y; + static char text[255],index; + static char *save; + static void *save_pic=NULL; + + data; + if (msg->msg==E_INIT) + { + int *p; + char *c; + + set_font(H_FLITT5,NOSHADOW(0)); + p=msg->data; + x=p[0]; + y=p[1]; + c=*(char **)(p+2); + strcpy(text,c); + save=(char *)getmem(strlen(text)+1); + strcpy(save,text); + index=strchr(text,0)-text; + if (save_pic==NULL) + { + schovej_mysku(); + save_pic=getmem(640*20*2+6); + get_picture(0,y,640,20,save_pic); + position(x,y);outtext(text);outtext("_"); + showview(0,0,640,480); + } + } + else + if (msg->msg==E_MOUSE) + { + MS_EVENT *ms; + + ms=get_mouse(msg); + if (ms->event_type & 0x8) send_message(E_KEYBOARD,27); + msg->msg=-1; + } + else if (msg->msg==E_KEYBOARD) + { + char c; + + c=*(char *)msg->data; + set_font(H_FLITT5,NOSHADOW(0)); + if (c) + { + switch (c) + { + case 8:if (index) index--; text[index]=0;break; + case 27:strcpy(text,save); + case 13:save_text_to_map(x,y,cur_depth,text); + send_message(E_DONE,E_MOUSE,psani_poznamek_event);msg->msg=-2;return; + default:if (c>=32) + { + text[index]=c; + text[index+1]=0; + if (text_width(text)>(640-x)) text[index]=0; else index++; + } + } + put_picture(0,y,save_pic); + position(x,y);outtext(text);outtext("_"); + showview(x,y,640,20); + } + msg->msg=-1; + } + else if (msg->msg==E_DONE) + { + if (save_pic!=NULL) + { + put_picture(0,y,save_pic); + showview(x,y,640,y+20); + free(save_pic);save_pic=NULL; + send_message(E_AUTOMAP_REDRAW); + ukaz_mysku(); + } + if (save!=NULL) + { + free(save);save=NULL; + } + } + } + +int hledej_poznamku(int x,int y,int depth) + { + int i,count; + + x=(x-320)+map_xr; + y=(y-197)+map_yr; + if (texty_v_mape==NULL) return -1; + count=str_count(texty_v_mape); + set_font(H_FLITT5,NOSHADOW(0)); + for(i=0;i=xa && y>=ya && x<=xb && y<=yb && dep==depth) + { + xas=(xa+320)-map_xr; + yas=(ya+197)-map_yr; + xbs=xas+xs; + ybs=yas+ys; + if (xas>0 && xbs<640 && yas>16 && ybs<360+16) return i; + return -2; + } + } + return -1; + } + +char psani_poznamek(int id,int xa,int ya,int xr,int yr) + { + xa;ya;xr;yr; + + if (noarrows) return 1; + if ((id=hledej_poznamku(xa,ya,cur_depth))==-1) + { + xa&=~7;xa+=2; + ya&=~7;ya-=4; + send_message(E_ADD,E_KEYBOARD,psani_poznamek_event,xa,ya,""); + send_message(E_ADD,E_MOUSE,psani_poznamek_event,xa,ya,""); + } + else if (id!=-2) + { + char *s; + + xa=*(int *)(texty_v_mape[id]); + ya=*(int *)(texty_v_mape[id]+4); + xa=(xa+320)-map_xr; + ya=(ya+197)-map_yr; + s=(char *)getmem(strlen(texty_v_mape[id]+12)+1); + strcpy(s,texty_v_mape[id]+12); + str_remove(&texty_v_mape,id); + str_delfreelines(&texty_v_mape); + send_message(E_AUTOMAP_REDRAW); + for(xr=0;xr<10;xr++) do_events(); + send_message(E_ADD,E_KEYBOARD,psani_poznamek_event,xa,ya,s); + send_message(E_ADD,E_MOUSE,psani_poznamek_event,xa,ya,s); + free(s); + } + return 0; + } + +char shift_map(int id,int xa,int ya,int xr,int yr) + { + id;xa;ya;xr;yr; + + anim_sipky(id,1); +// send_message(E_ADD,E_TIMER,shift_map_event,id); +// send_message(E_ADD,E_MOUSE,shift_map_event,id); + return 0; + } + +static void print_symbol(int x,int y,char znak) + { + char c[2]=" "; + position(x+1,y+1);c[0]=znak;outtext(c); + } + + +static void draw_amap_sector(int x,int y,int sector,int mode,int turn,int line1,int line2) + { + int j,i,k; + TSTENA *q; + TSECTOR *ss; + + q=&map_sides[sector<<2]; + ss=&map_sectors[sector]; + if (ss->sector_type==S_VODA || ss->sector_type==S_LODKA) curcolor=AUTOMAP_VODA; + else if (ss->sector_type==S_LAVA) curcolor=AUTOMAP_LAVA; + else curcolor=AUTOMAP_FORE; + if (!mode) + { + trans_bar(x,y,8,8,curcolor); + if ((k=map_coord[sector].flags & 0x600)!=0) + { + int i; + + i=map_sectors[sector].sector_type; + set_font(H_FSYMB,0);k>>=9; + switch (k) + { + case 3:break; + case 2:set_font(H_FSYMB,0); + font_color(stairs_colors); + print_symbol(x,y,'s');break; + case 1:set_font(H_FSYMB,0); + font_color(arrow_colors); + print_symbol(x,y,4+((i-S_SMER+4-turn) & 0x3));break; + + } + } + else + switch(map_sectors[sector].sector_type) + { + int i; + TSTENA *sd; + case S_SCHODY:set_font(H_FSYMB,0x3e0); + memcpy(charcolors,stairs_colors,sizeof(stairs_colors)); + print_symbol(x,y,'s');break; + case S_TELEPORT:for(i=0,sd=map_sides+sector*4;i<4 && ~sd->flags & SD_SEC_VIS;i++,sd++); + if (i!=4) {set_font(H_FSYMB,0x3e0);print_symbol(x,y,'T');}break; + case S_DIRA:set_font(H_FSYMB,NOSHADOW(0));print_symbol(x,y,'N');break; + } + } + else + for(j=0;j<4;j++) + { + i=(j+turn)&3; + if (!(q[i].flags & SD_TRANSPARENT)||(q[i].flags & SD_SECRET)) curcolor=line1; + else if (q[i].flags & SD_PLAY_IMPS) curcolor=line2; + else curcolor=AUTOMAP_FORE; + if (q[i].flags & SD_INVIS) curcolor=AUTOMAP_FORE; + if (curcolor!=AUTOMAP_FORE) + { + switch (j) + { + case 0:hor_line(x,y,x+8);break; + case 1:ver_line(x+8,y,y+8);break; + case 2:hor_line(x,y+8,x+8);break; + case 3:ver_line(x,y,y+8);break; + } + } + } + + } + +void herni_cas(char *s) + { + int mes,den,hod,min; + long cas; + + cas=game_time; + mes=cas/(360*24*30);cas%=360*24*30; + den=cas/(360*24);cas%=360*24; + hod=cas/(360);cas%=360; + min=cas/6; + + if (mes) + { + sprintf(s,texty[cislovka(mes)+149],mes); + strcat(s," "); + s=strchr(s,0); + } + if (den) + { + sprintf(s,texty[cislovka(den)+146],den); + strcat(s," "); + s=strchr(s,0); + } + sprintf(s,texty[152],hod,min); + } + +static void zobraz_herni_cas(void) + { + static char text[100]; + static long old_time=-1; + char cas[100]; + + if (old_time!=game_time) + { + herni_cas(cas); + strcpy(text,texty[145]); + strcat(text," "); + strcat(text,cas); + old_time=game_time; + } + set_font(H_FONT6,NOSHADOW(0)); + set_aligned_position(635,372,2,2,text); + outtext(text); + } + + +extern word color_butt_on[]; +extern word color_butt_off[]; + +static void displ_button(char disable,char **text) + { + int posy[]={0,18,37,55}; + int sizy[]={18,20,20,21}; + int i; + + cur_disables=disable; + set_font(H_FTINY,0); + put_picture(LEFT,BOTT,ablock(H_CHARGEN)); + for(i=0;i<4;i++) + { + if (disable & 1) + { + put_8bit_clipped(ablock(H_CHARGENB),(392+posy[i])*scr_linelen2+524+GetScreenAdr(),posy[i],96,sizy[i]); + font_color(color_butt_off); + } + else + { + font_color(color_butt_on); + } + disable>>=1; + set_aligned_position(LEFT+50,BOTT+14+13+i*19,1,2,*text); + outtext(*text); + text++; + } + } + + +void draw_automap(int xr,int yr) +{ + int i,k,x,y,xp,yp; + int depth; + TSTENA *q; + word *s; + + update_mysky(); + schovej_mysku(); + put_textured_bar(ablock(H_BACKMAP),0,17,640,360,-xr*8,-yr*8); + curcolor=AUTOMAP_BACK; + xp=map_coord[viewsector].x*8; + yp=map_coord[viewsector].y*8; + depth=cur_depth; + map_xr=xp-xr*8; + map_yr=yp-yr*8; + for(k=0;k<2;k++) + for(i=1;i=-178 && y<170 && x>=-312 && x<310) + { + + x+=320;y+=197; + draw_amap_sector(x,y,i,k,0,AUTOMAP_LINE1,AUTOMAP_LINE2); + if (map_coord[i].flags & MC_PLAYER && !noarrows) + { + int j,l=-1; + + for(j=0;jmsg==E_INIT) xr=yr=0; + if (msg->msg==E_IDLE && draw==1) + { + draw_automap(xr,yr); + draw=0; + } + else draw--; + if (msg->msg==E_AUTOMAP_REDRAW) draw=4; + if (msg->msg==E_KEYBOARD) + { + c=(*(int *)msg->data)>>8; + switch (c) + { + case 'H':yr++;draw=4;break; + case 'P':yr--;draw=4;break; + case 'M':xr--;draw=4;break; + case 'K':xr++;draw=4;break; + case 'Q': + case 's':if (check_for_layer(cur_depth-1)) cur_depth--;draw=4;break; + case 'I': + case 't':if (check_for_layer(cur_depth+1)) cur_depth++;draw=4;break; + case 15: + case 50: + case 1: + (*(int *)msg->data)=0; + unwire_proc(); + wire_proc(); + + break; + } + } + return &map_keyboard; + } + +void show_automap(char full) + { + mute_all_tracks(0); + unwire_proc(); + if (full) enable_all_map(); + hold_timer(TM_FAST_TIMER,1); + unwire_proc=unwire_automap; + schovej_mysku(); + if (cur_mode!=MD_ANOTHER_MAP) bott_draw(1),cur_mode=MD_MAP; + other_draw(); + if (!battle && full && enable_glmap) displ_button(cur_mode==MD_ANOTHER_MAP?4:6,texty+210); + else displ_button(7,texty+210); + ukaz_mysku(); + showview(0,376,640,480); + cur_depth=map_coord[viewsector].layer; + draw_automap(0,0); + send_message(E_ADD,E_KEYBOARD,map_keyboard); + send_message(E_ADD,E_AUTOMAP_REDRAW,map_keyboard); + send_message(E_ADD,E_IDLE,map_keyboard); + change_click_map(clk_map_view,CLK_MAP_VIEW); +} + +static char mob_not_invis(sector) + { + int m; + m=mob_map[sector]; + while (m) + { + m--;if (mobs[m].vlastnosti[VLS_KOUZLA] & SPL_INVIS) return 0; + m=mobs[m].next; + } + return 1; + } + +void draw_medium_map() + { + int xr, yr; + int xp, yp; + int xc,yc,x,y; + int j,i,k,layer; + //char c=" "; + + xp=MEDIUM_MMAP*8+5; + yp=MEDIUM_MMAP*8+20; + layer=map_coord[viewsector].layer; + xr=map_coord[viewsector].x; + yr=map_coord[viewsector].y; + trans_bar(0,17,MEDIUM_MAP*8+6*2,MEDIUM_MAP*8+4*2,0); + for(j=0;j<2;j++) + for(i=1;i=-MEDIUM_MMAP && yc>=-MEDIUM_MMAP && yc<=MEDIUM_MMAP && xc<=MEDIUM_MMAP) + { + draw_amap_sector(x=xc*8+xp,y=yc*8+yp,i,j,viewdir &3,MEDIUM_MAP_LINE1,MEDIUM_MAP_LINE2); + if (j) + if (mob_map[i] && mob_not_invis(i) && battle) + { + position(x+1,y+1);set_font(H_FSYMB,AUTOMAP_MOB); + outtext("N"); + } + if (map_coord[i].flags & MC_PLAYER) + { + int u=-1,z=-1; + for(k=0;k4) return 1; + id--; + if (cur_disables & (1<xa) cur_page=xa; + if (cur_page!=oldp) play_sample_at_channel(H_SND_KNIHA,1,100); + wire_kniha(); + return 1; + } + +#define CLK_KNIHA 3 +T_CLK_MAP clk_kniha[]= + { + {2,320,0,639,479,page_change,2,-1}, + {-2,0,0,319,479,page_change,2,-1}, + {-1,0,0,639,479,exit_kniha,8,-1}, + }; + + +void unwire_kniha() +{ + hold_timer(TM_FAST_TIMER,0); + GlobEvent(MAGLOB_AFTERBOOK,viewsector,viewdir); +} + + +void wire_kniha() + { + int xa; + if (!GlobEvent(MAGLOB_BEFOREBOOK,viewsector,viewdir)) + { + return; + } + xa=count_pages(); + xa=((xa-1) & ~1)+1; + if (cur_page<1) cur_page=1; + if (cur_page>xa) cur_page=xa; + mute_all_tracks(0); + unwire_proc(); + schovej_mysku(); + put_picture(0,0,ablock(H_KNIHA)); + change_click_map(clk_kniha,CLK_KNIHA); + unwire_proc=unwire_kniha; + set_font(H_FONT6,NOSHADOW(0)); + write_book(cur_page); + ukaz_mysku(); + showview(0,0,0,0); + hold_timer(TM_FAST_TIMER,1); + } + +static last_selected; + +char map_target_cancel(int id,int xa,int ya,int xr,int yr) + { + id,xa,ya,xr,yr; + return exit_wait=1; + } + +void map_teleport_keyboard(EVENT_MSG *msg,void **usr) + { + usr; + if (msg->msg==E_KEYBOARD) + switch (*(short *)msg->data>>8) + { + case 1: + case 15: + case 50: exit_wait=1; msg->msg=-1;break; + } + } + + +static char path_ok(word sector) + { + map_coord[sector].flags|=MC_MARKED; + return 1; + } + +char map_target_select(int id,int xa,int ya,int xr,int yr) + { + int x1,y1,x2,y2; + + ya,xa; + for (id=1;id=x1 && xr<=x2 && yr>=y1 && yr<=y2) + { + if (!labyrinth_find_path(viewsector,id,SD_PLAY_IMPS,path_ok,NULL)) return 0; + last_selected=id; + exit_wait=1; + return 1; + } + } + return 0; + } + + +int select_teleport_target() + { + *otevri_zavoru=1; + unwire_proc(); + disable_all_map(); + labyrinth_find_path(viewsector,65535,SD_PLAY_IMPS,path_ok,NULL); + map_coord[viewsector].flags|=MC_MARKED; + schovej_mysku(); + send_message(E_ADD,E_KEYBOARD,map_teleport_keyboard); + show_automap(0); + change_click_map(clk_teleport_view,CLK_TELEPORT_VIEW); + last_selected=0; + ukaz_mysku(); + escape(); + send_message(E_DONE,E_KEYBOARD,map_teleport_keyboard); + disable_all_map(); + return last_selected; + } diff --git a/GAME/BOLDCZ.FON b/GAME/BOLDCZ.FON new file mode 100644 index 0000000000000000000000000000000000000000..be5e16c7bc204cc269f8460b692ba38ff6f14220 GIT binary patch literal 9034 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "engine1.h" +#include +#include "globals.h" +#include "Version.h" + +#define ZIVOTY_S 60 +#define ZIVOTY_E 62 +#define KONDIC_S 64 +#define KONDIC_E 66 +#define MANA_S 68 +#define MANA_E 70 +#define BARS_S 13 +#define BARS_E 85 +#define BARS_YS (BARS_E-BARS_S) +#define PIC_X 3 +#define PIC_Y 12 +#define MANA_COLOR RGB555(15,0,31) +#define SEL_COLOR RGB555(31,31,31) + +#define ZASAHB_X 8 +#define ZASAHB_Y 20 +#define ZASAHT_X 30 +#define ZASAHT_Y 38 + + +#define SHOW {swap_buffs();showview(0,0,0,0);swap_buffs();getche();`} + +#define HUMAN_ADJUST 97 + +unsigned short barvy_skupin[POCET_POSTAV+1]= + { + RGB555(8,8,8), + RGB555(31,28,00), + RGB555(00,23,06), + RGB555(31,11,13), + RGB555(22,16,31), + RGB555(28,13,31), + RGB555(00,29,26) + }; + +char reverse_draw=0; +int viewsector=1,viewdir=1; +char norefresh=0,cancel_render=0,map_state=0; +int cur_sector; //sektor aktualni pozice +int back_color; +char global_anim_counter=0; +char one_buffer=0; +char set_halucination=0; +int hal_sector; +int hal_dir; +char see_monster=0; +char lodka=0; +int bgr_distance=0; //vzdalenost pozadi od pohledu +int bgr_handle=0; + +int spell_handle=0,spell_phase,spell_xicht; + +THE_TIMER *bott_timer=NULL; +char *bott_text=NULL; +char bott_display; +char true_seeing=0; +char obl_anim_counter=0; +char obl_max_anim=1; +char anim_mirror=0; +static char showrune=0; +static int showruneitem=0; + + + +char dirs[10]; +word minimap[VIEW3D_Z+1][VIEW3D_X*2+1]; + + + +//debug - !!!! + +int dhit=0; +int ddef=0; +int ddostal=0; +int dlives=0; +int dmzhit=0; +int dsee=0; +char show_debug=0; +char *debug_text; +char marker=0; + + +SPECTXT_ARR spectxtr; +static char spt_ptr=0; + + +void add_spectxtr(word sector,word fhandle,word count,word repeat,integer xpos) + { + SPECTXTR *sp=spectxtr+spt_ptr; + + sp->sector=sector; + sp->handle=fhandle; + sp->count=count; + sp->pos=0; + sp->repeat=repeat; + sp->xpos=xpos; + if (count) + if ((++spt_ptr)>=MAX_SPECTXTRS) spt_ptr=0; + map_coord[sector].flags |= MC_SPECTXTR; + } + +void calc_spectxtrs(void) + { + int i; + + for(i=0;ipos>=sp->count) + { + sp->pos=0;if (sp->repeat>0) sp->repeat--; + } + } + } + +static void draw_spectxtrs(word sector,int celx,int cely) + { + int i; + char a=1; + + if (!(map_coord[sector].flags & MC_SPECTXTR)) return; + for(i=0;ihandle+sp->pos),celx,cely,sp->xpos); + a=0; + } + if (a) + map_coord[sector].flags &= ~MC_SPECTXTR; + } + +void init_spectxtrs(void) + { + memset(spectxtr,0,sizeof(spectxtr)); + } + +void ukaz_kompas(char mode) + { + static int phase=0,speed=0; + int direct; + + if (mode==1) + { + direct=(3-viewdir); + direct=phase-direct*10; + if (direct<-20) direct+=40; + if (direct>=20) direct-=40; + speed=((direct>0)-(direct<0)); + } + if (mode!=255) put_image(ablock(H_KOMPAS),GetScreenAdr()+476,phase*16,102,16); + if (mode==1) + { + phase-=speed;if (phase>39) phase=0; + if(phase<0) phase=39; + } + if (mode==255) showview(476,0,102,15); + } + +void show_money() + { + char c[20]; + set_font(H_FONT7,RGB555(28,28,21)); + sprintf(c,"%d",money); + set_aligned_position(460,13,2,2,c); + outtext(c); + } + + +void anim_sipky(int h,int mode) + { + static int phase=0; + static char drw=0; + static short handle=0; + + if (mode==1) + { + handle=h; + phase=6; + return; + } + if (phase && mode!=255) + { + int i; + + if (phase>4) i=8-phase; else i=phase; + i=(i-2)*110; + if (i>=0) + put_8bit_clipped(ablock(handle),GetScreenAdr()+378*scr_linelen2+498,i,142,102); + else put_picture(498,378,ablock(H_SIPKY_END)); + drw=1; + if (mode!=-1) + { + phase--; + } + } + if (mode==255 && drw) + { + showview(498,378,142,102); + drw=0; + } + } + +void chveni(int i) + { + static int pos=0; + static int count=0; + + if (!count && !i) return; + if (i) count=i;count--; + if (!count) pos=0; + wait_retrace(); + setvesa_displaystart(8*pos,0); + pos=!pos; + } + +void objekty_mimo() + { + schovej_mysku(); + ukaz_kompas(1); + anim_sipky(0,0); + ukaz_mysku(); + ukaz_kompas(255); + anim_sipky(0,255); + chveni(0); + } + +void draw_blood(char mode,int mob_dostal,int mob_dostal_pocet) + { + static int phase=100; + static int block; + static int dostal; + char s[20]; + word *adr; + int i; + + mob_dostal_pocet; + if (mode) { + if (phase<3) dostal+=mob_dostal_pocet;else dostal=mob_dostal_pocet; + phase=0; + block=mob_dostal; + return; + } + if (phase>7) return; + adr=520+378*scr_linelen2+GetScreenAdr(); + i=105*phase; + phase++; + put_8bit_clipped(ablock(H_KREVMIN+block-1),adr,i,120,102); + set_font(H_FTINY,RGB555(31,31,31)); + itoa(dostal,s,10); + set_aligned_position(60+520,51+378,1,1,s);outtext(s); + } + +word *bott_clear(void) + { + word *bott_scr; + + bott_scr=(word *)getmem(scr_linelen2*104*2); + memset(bott_scr,0,_msize(bott_scr)); + return bott_scr; + } + +static void draw_small_icone(int num,int x,int y) + { + word *pic; + + pic=ablock(H_POSTUP); + num*=13;x+=num; + put_textured_bar(pic,x,y,13,13,num,0); + } + +static void bott_fletna_normal(void **pp,long *s) + { + word *bott_scr; + int i,x; + bott_scr=bott_clear(); + RedirectScreen(bott_scr); + put_picture(0,0,ablock(H_FLETNA_BAR)); + set_font(H_FTINY,RGB555(31,31,0)); + set_aligned_position(103,52,1,1,texty[174]);outtext(texty[174]); + for(i=0,x=156;i<12;i++,x+=22) + { + set_aligned_position(x,32,1,1,texty[180+i]);outtext(texty[180+i]); + } + *pp=GetScreenAdr(); + *s=_msize(*pp); + RestoreScreen(); + } + +static void bott_draw_normal(void **pp,long *s) + { + int i,j;int x,xs=0,y; + word *bott_scr; + THUMAN *p; + + bott_scr=bott_clear(); + RedirectScreen(bott_scr); + if (battle && cur_mode==MD_INBATTLE) put_picture(0,0,ablock(H_BATTLE_BAR)); + else put_picture(0,0,ablock(H_DESK)); + memcpy(&xs,ablock(H_OKNO),2); + x=54; + for(j=0;jused) + if (cur_mode!=MD_PRESUN || i==moving_player) + { + char c[]=" ";int z,lv,llv; + put_picture(x,0,ablock(H_OKNO));lv=p->lives;llv=p->vlastnosti[VLS_MAXHIT]; + if (lv || p->used & 0x80) + { + z=3-((lv-1)*4/llv);if (lv==llv) z=0; + z*=75; + if (p->xicht>=0)put_8bit_clipped(ablock(H_XICHTY+i),bott_scr+PIC_X+x+PIC_Y*scr_linelen2,z,54,75); + if (p->bonus) draw_small_icone(0,PIC_X+x+1,PIC_Y+1); + if (p->spell) draw_small_icone(1,PIC_X+x+1,PIC_Y+1); + if (!p->voda) draw_small_icone(2,PIC_X+x+1,PIC_Y+1); + if (!p->jidlo) draw_small_icone(3,PIC_X+x+1,PIC_Y+1); + } + else put_picture(PIC_X+x,PIC_Y,ablock(H_LEBKA)); + curcolor=0; + y=BARS_YS-p->lives*BARS_YS/p->vlastnosti[VLS_MAXHIT]; + if (y) bar(x+ZIVOTY_S,BARS_S,x+ZIVOTY_E,BARS_S+y); + y=BARS_YS-p->kondice*BARS_YS/p->vlastnosti[VLS_KONDIC]; + if (y) bar(x+KONDIC_S,BARS_S,x+KONDIC_E,BARS_S+y); + if (p->vlastnosti[VLS_MAXMANA]) y=BARS_YS-p->mana*BARS_YS/p->vlastnosti[VLS_MAXMANA];else y=BARS_YS; + if (y<0) y=0; + if (y) bar(x+MANA_S,BARS_S,x+MANA_E,BARS_S+y); + if (p->sektor!=viewsector) trans_bar25(x,0,74,102); + set_font(H_FLITT,p->groupnum==cur_group && !battle?SEL_COLOR:barvy_skupin[p->groupnum]); + set_aligned_position(x+36,92,1,0,p->jmeno);outtext(p->jmeno); + c[0]=p->groupnum+48;set_aligned_position(x+5,86,0,2,c);outtext(c); + if (cur_mode==MD_INBATTLE) + { + char s[20]; + signed char dir; + set_font(H_FBOLD,RGB555(31,31,0)); + sprintf(s,texty[40],p->actions); + set_aligned_position(x+56,86,2,2,s);outtext(s); + dir=viewdir-p->direction; + if (abs(dir)==2) c[0]=2; + else if (dir==-1 || dir==3) c[0]=1; + else if (dir==-3 || dir==1) c[0]=3; + if (dir) + { + set_font(H_FSYMB,p->groupnum==cur_group && !battle?SEL_COLOR:barvy_skupin[p->groupnum]); + c[0]+=4;set_aligned_position(x+10,86,0,2,c);outtext(c); + } + } + if (i==select_player) rectangle(x+3,12,x+3+54,12+75,SEL_COLOR); + if (p->dostal) + { + char s[20]; + put_picture(x+ZASAHB_X,ZASAHB_Y,ablock(H_PZASAH)); + set_font(H_FBOLD,RGB555(31,31,0)); + sprintf(s,"%d",p->dostal); + set_aligned_position(x+ZASAHT_X,ZASAHT_Y,1,1,s);outtext(s); + } + x+=xs; + } + if (cur_mode==MD_PRESUN || cur_mode==MD_UTEK) + { + char s[40]; + set_font(H_FBOLD,RGB555(31,31,16)); + position(150,20);outtext(texty[cur_mode==MD_PRESUN?42:44]); + sprintf(s,texty[60+cislovka(postavy[moving_player].actions)],postavy[moving_player].actions); + position(150,35);outtext(s); + position(150,50);outtext(texty[63]); + } +/* if (mob_dostal) + { + word *w; + char s[40]; + + w=ablock(H_MZASAH1+mob_dostal-1); + put_picture(580-(w[0]>>1),55-(w[1]>>1),w); + itoa(mob_dostal_pocet,s,10); + set_font(H_FLITT5,0xffff); + set_aligned_position(580,55,1,1,s); + outtext(s); + } + */ + *pp=GetScreenAdr(); + *s=_msize(*pp); + RestoreScreen(); + } + + +void bott_timer_draw(struct the_timer *q) + { + q; + bott_display=BOTT_NORMAL; + zneplatnit_block(H_BOTTBAR); + free(bott_text); + bott_text=NULL; + bott_timer=NULL; + } + +void bott_disp_text_proc(void **pp,long *ss) + { + char *p,*text; + int y=20; + int xx,yy; + + text=alloca(strlen(bott_text)+2); + set_font(H_FBOLD,NOSHADOW(0)); + zalamovani(bott_text,text,390,&xx,&yy); + RedirectScreen(bott_clear()); + if (battle && cur_mode==MD_INBATTLE) put_picture(0,0,ablock(H_BATTLE_BAR)); + else put_picture(0,0,ablock(H_DESK)); + create_frame(70,20,400,50,1); + p=text; + do + { + position(70,y); + outtext(p); + y+=text_height(p); + p=strchr(p,0)+1; + } + while (p[0]); + *pp=GetScreenAdr(); + *ss=_msize(*pp); + RestoreScreen(); + } + +void bott_disp_text(char *text) + { + if (text==0) text="Chybi popisek!!"; + zneplatnit_block(H_BOTTBAR); + if (bott_timer==NULL) + bott_timer=add_to_timer(TM_BOTT_MESSAGE,MSG_DELAY,1,bott_timer_draw); + else bott_timer->counter=MSG_DELAY; + bott_display=BOTT_TEXT; + if (bott_text!=NULL) free(bott_text); + bott_text=(char *)getmem(strlen(text)+1); + strcpy(bott_text,text); + } + +static void MaskPutPicture(int x, int y, char mask, word color, char blend, void *pic) + { + short *info=(short *)pic; + char *data=(char *)(info+3+256); + word *pos=GetScreenAdr()+x+y*scr_linelen2; + if (blend) color=color & 0xF7DE; + for (y=0;y>1; + else + pos[x]=color; + } + + +void bott_draw_rune(void **pp,long *ss) + { + int sel_zivel=showrune/10; + int sel_rune=showrune%10; + int maskrune=runes[sel_zivel]; + int i; + char buff[300]; + int spell=(sel_zivel*7+sel_rune)*3; + RedirectScreen(bott_clear()); + if (battle && cur_mode==MD_INBATTLE) put_picture(0,0,ablock(H_BATTLE_BAR)); + else put_picture(0,0,ablock(H_DESK)); + create_frame(70,20,280,50,1); + put_picture(378,0,ablock(H_RUNEBAR1+sel_zivel)); + for (i=0;i<7;i++) + if (!(maskrune & (1<counter=MSG_DELAY; + + } + +void bott_text_forever() + { + delete_from_timer(TM_BOTT_MESSAGE); + bott_timer=NULL; + } + +void bott_draw_proc(void **p,long *s) + { + switch (bott_display) + { + case BOTT_NORMAL:bott_draw_normal(p,s);break; + case BOTT_TEXT:bott_disp_text_proc(p,s);break; + case BOTT_FLETNA:bott_fletna_normal(p,s);break; + case BOTT_RUNA:bott_draw_rune(p,s);break; + } + } + +void bott_draw(char priority) + { + if (priority) + { + if (bott_display!=BOTT_NORMAL) + { + delete_from_timer(TM_BOTT_MESSAGE); + bott_timer=NULL; + bott_display=BOTT_NORMAL; + } + } + if (bott_display==BOTT_NORMAL) + zneplatnit_block(H_BOTTBAR); + } + +void bott_draw_fletna() + { + bott_display=BOTT_FLETNA; + zneplatnit_block(H_BOTTBAR); + } + +void draw_spell(int handle,int phase,int xicht) + { + int x,y,i; + word *w; + + if (bott_display!=BOTT_NORMAL) bott_draw(1); + for(i=0;i=10) + { + spell_handle=0; + spell_xicht=0; + } + } + put_picture(0,0,ablock(1)); + ukaz_kompas(0); + show_money(); + anim_sipky(0,-1); + draw_fx(); + memset(GetScreenAdr()+(SCREEN_OFFLINE-1)*scr_linelen2,0,1280); + memset(GetScreenAdr()+(SCREEN_OFFLINE+360)*scr_linelen2,0,1280); + } + +void display_spell_in_icone(int handle,int xicht) + { + spell_phase=0; + spell_handle=handle; + spell_xicht|=xicht; + } + +int fc_num(int anim_counter,int sector,char floor) + { + int mode; + TSECTOR *s; + TMAP_EDIT_INFO *m; + int basic; + + s=&map_sectors[sector]; + m=&map_coord[cur_sector]; + if (floor) + { + basic=s->floor; + mode=s->flags & 0xf; + } + else + { + basic=s->ceil; + mode=s->flags>>4; + } + + if (mode & 0x8) + return basic+(anim_counter % ((mode & 0x7)+1)); + switch (mode) + { + case 0: return basic; + case 1: return basic+((m->x+m->y+dirs[1]) & 0x1); + case 2: return basic+(dirs[1] & 0x1); + case 3: return basic+(dirs[1] & 0x1)*2+((m->x+m->y+(dirs[1]>>1)) & 0x1); + case 4: return basic+dirs[1]; + case 5: return basic+dirs[1]*2+((m->x+m->y+(dirs[1]>>1)) & 0x1); + } + return basic; + } + +int enter_tab[VIEW3D_Z+1][VIEW3D_X*2+1]= + {4,3,3,3,3,3,3,3,4, + 4,3,3,2,3,2,3,3,4, + 4,3,3,2,4,2,3,3,4, + 4,3,1,1,4,1,1,3,4, + 4,1,1,1,4,1,1,1,4}; + + + +void crt_minimap_itr(sector,smer,itrx,itry,automap) + { + static int sector_temp; + static long sideflags; + static short enter=0; + short savee; + + if (itrx==VIEW3D_X && itry==0) enter=0; + if (itrx<0 || itrx>VIEW3D_X*2 || itry>VIEW3D_Z) return; + if (minimap[itry][itrx]) return; + minimap[itry][itrx]=sector; + if (!set_halucination) map_coord[sector].flags|=automap & (itrx<=VIEW3D_X+1 && itrx>=VIEW3D_X-1) ; + if (itrx<=VIEW3D_X) + { + sector_temp=map_sectors[sector].step_next[dirs[0]]; + sideflags=map_sides[sector*4+dirs[0]].flags; + if (sector_temp && sideflags & 0x80 && enter>=0) + { + savee=enter; + enter=-enter_tab[itry][itrx]; + crt_minimap_itr(sector_temp,smer,itrx-1,itry,automap &(sideflags & 1)); + enter=savee; + } + } + if (itrx>=VIEW3D_X) + { + sector_temp=map_sectors[sector].step_next[dirs[2]]; + sideflags=map_sides[sector*4+dirs[2]].flags; + if (sector_temp && sideflags & 0x80 && enter<=0) + { + savee=enter; + enter=enter_tab[itry][itrx]; + crt_minimap_itr(sector_temp,smer,itrx+1,itry,automap &(sideflags & 1)); + enter=savee; + } + } + sector_temp=map_sectors[sector].step_next[dirs[1]]; + sideflags=map_sides[sector*4+dirs[1]].flags; + if (sector_temp && sideflags & 0x80) + { + savee=enter; + enter-=(enter>0)-(enter<0); + crt_minimap_itr(sector_temp,smer,itrx,itry+1,automap &(sideflags & 1)); + enter=savee; + } + } + + +void create_minimap(sector,smer) + { + memset(minimap,0,sizeof(minimap)); + dirs[1]=smer; + dirs[0]=(smer-1) & 3; + dirs[2]=(smer+1) & 3; + crt_minimap_itr(sector,smer,VIEW3D_X,0,1); + } + +static const float Inv2=0.5; +static const float Snapper=3<<22; + +__inline int toInt( float fval ) +{ + fval += Snapper; + return ( (*(int *)&fval)&0x007fffff ) - 0x00400000; +} + + +static void *check_autofade(void *image, char ceil, int dark) +{ + char *data=image; + if (data[5]==0x80) + { + word *xy=(word *)image; + if (mglob.map_autofadefc==1) + { + word *imgdata=xy+3; + int br=back_color>>11; + int bg=(back_color>>5) & 0x3F; + int bb=back_color & 0x1F; + int y; + + if (dark) br=bg=bb=0; + + for(y=0;y>11; + int g=(*imgdata>>5) & 0x3F; + int b=*imgdata & 0x1F; + r=toInt(r+factor*(br-r)); + g=toInt(g+factor*(bg-g)); + b=toInt(b+factor*(bb-b)); + *imgdata=(r<<11)|(g<<5)|b; + imgdata++; + } + } + } + xy[2]=xy[2] & 0xFF; + } + return image; +} + +#define draw_floor(s,celx,cely,dark) if (s->floor) draw_floor_ceil(celx,cely,0,check_autofade(ablock(num_ofsets[FLOOR_NUM]+fc_num(global_anim_counter,sector,1)),0,dark)); +#define draw_ceil(s,celx,cely,dark) if (s->ceil) draw_floor_ceil(celx,cely,1,check_autofade(ablock(num_ofsets[CEIL_NUM]+fc_num(global_anim_counter,sector,0)),1,dark)); +#define GET_OBLOUK(p) ((p->oblouk & 0xf)+(p->prim_anim>>4)) + +static int left_shiftup,right_shiftup; + +int draw_basic_floor(int celx,int cely,int sector) + { + TSECTOR *s; + int dark; + + s=&map_sectors[sector]; + dark=map_coord[sector].flags & MC_SHADING; + draw_floor(s,celx,cely,dark); + draw_ceil(s,celx,cely,dark); + return 0; + } + +static calc_item_shiftup(TITEM *it) + { + short *s; + char *c; + int y,x,xs,ys,t; + + t=0; + s=ablock(it->vzhled+face_arr[0]); + xs=s[0];ys=s[1];c=((char *)s)+PIC_FADE_PAL_SIZE; + c+=xs*ys-1;y=0; + while (yitems[i])!=0;i++) + { + TITEM *it=&glob_items[j-1]; + if (it->shiftup==0xff) it->shiftup=calc_item_shiftup(it); + draw_item2(celx,cely,v->xpos,v->ypos-it->shiftup,ablock(it->vzhled+face_arr[0]),i); + } + } + + +static int draw_basic_sector(int celx,int cely,int sector) + { + TSTENA *w,*q; + int obl; + + w=&map_sides[sector*4]; + q=&w[dirs[1]]; + obl=GET_OBLOUK(q); + if (celyflags & SD_LEFT_ARC && obl) + show_cel2(celx,cely,ablock(num_ofsets[OBL_NUM]+obl),0,0,1); + if (q->flags & SD_RIGHT_ARC && q->oblouk & 0x0f) + show_cel2(celx,cely,ablock(num_ofsets[OBL2_NUM]+obl),0,0,2); + if (q->flags & SD_PRIM_VIS && q->prim) + show_cel2(celx,cely,ablock(num_ofsets[MAIN_NUM]+q->prim+(q->prim_anim>>4)),0,0,1+(q->oblouk & SD_POSITION)); + if (q->flags & SD_SEC_VIS && q->sec) + if (q->side_tag & SD_SHIFTUP) + { + if (cely!=0) + show_cel2(celx,cely-1,ablock(num_ofsets[MAIN_NUM]+q->sec+(q->sec_anim>>4)),0,0,1); + } + else + show_cel2(celx,cely,ablock(num_ofsets[MAIN_NUM]+q->sec+(q->sec_anim>>4)),q->xsec<<1,q->ysec<<1,0); + if (q->oblouk & 0x10) + draw_vyklenek(celx,cely,sector,dirs[1]); + } + if (celx<=0) + { + q=&w[dirs[0]]; + if (left_shiftup) + show_cel(celx,cely,ablock(num_ofsets[LEFT_NUM]+left_shiftup),0,0,2),left_shiftup=0; + if (q->flags & SD_PRIM_VIS && q->prim) + show_cel(-celx,cely,ablock(num_ofsets[LEFT_NUM]+q->prim+(q->prim_anim>>4)),0,0,2+(q->oblouk & SD_POSITION)); + if (q->flags & SD_SEC_VIS && q->sec) + if (q->side_tag & SD_SHIFTUP) + if (celx!=0) left_shiftup=q->sec+(q->sec_anim>>4);else left_shiftup=0; + else if (q->flags & SD_SPEC) + show_cel(celx,cely,ablock(num_ofsets[LEFT_NUM]+q->sec+(q->sec_anim>>4)),0,0,2); + else + show_cel(celx,cely,ablock(num_ofsets[LEFT_NUM]+q->sec+(q->sec_anim>>4)),q->xsec<<1,q->ysec<<1,0); + } + if (celx>=0) + { + q=&w[dirs[2]]; + if (right_shiftup) + show_cel(celx,cely,ablock(num_ofsets[RIGHT_NUM]+right_shiftup),0,0,3),right_shiftup=0; + if (q->flags & SD_PRIM_VIS && q->prim) + show_cel(celx,cely,ablock(num_ofsets[RIGHT_NUM]+q->prim+(q->prim_anim>>4)),0,0,3+(q->oblouk & SD_POSITION)); + if (q->flags & SD_SEC_VIS && q->sec) + if (q->side_tag & SD_SHIFTUP) + if (celx!=0) right_shiftup=q->sec+(q->sec_anim>>4);else right_shiftup=0; + else if (q->flags & SD_SPEC) + show_cel(celx,cely,ablock(num_ofsets[RIGHT_NUM]+q->sec+(q->sec_anim>>4)),0,0,3); + else + show_cel(celx,cely,ablock(num_ofsets[RIGHT_NUM]+q->sec+(q->sec_anim>>4)),500-(q->xsec<<1),q->ysec<<1,1); + } + return 0; + } + +static int draw_lodku(int celx,int cely) + { + if (cely==0) return 1; + show_cel2(celx,cely-1,ablock(H_LODKA0+(global_anim_counter & 7)),250,80,0); + return 0; + } + + +int p_place_table[4][5]= + { + {0,1,4,2,3}, + {1,2,4,3,0}, + {2,3,4,0,1}, + {3,0,4,1,2} + }; +int p_positions_x[5]={-32,32,32,-32,0}; +int p_positions_y[5]={32,32,-32,-32,0}; + +void draw_players(int sector,int dir,int celx,int cely) + { + if (map_coord[sector].flags & MC_DPLAYER) + { + int i; + THUMAN *p; + char freep[5]; + int j,d,pp=0,f; + + memset(freep,0,sizeof(freep)); + for(i=0,pp=0;isektor==sector && ((!p->lives && p->groupnum==0) || p->sektor!=viewsector)) + { + pp++; + d=(p->direction-dir)&0x3; + if (p->lives) + for(j=0;j<5 && freep[p_place_table[d][j]];j++); + else + for(j=4;j>=0 && freep[p_place_table[d][j]];j--); + if (j==5 || j==-1) break; + freep[f=p_place_table[d][j]]=i+1; + } + } + if (pp==1 && freep[f] & 1) + {pp=f+1&3;freep[pp]=freep[f];freep[f]=0;} + for(i=0;i<5;i++) + if ((j=freep[d=p_place_table[0][i]])!=0) + if (postavy[j-1].lives) + { + set_font(H_FLITT5,barvy_skupin[postavy[j-1].groupnum]); + draw_player(ablock(H_POSTAVY+j-1),celx,cely,p_positions_x[d],p_positions_y[d],HUMAN_ADJUST,postavy[j-1].jmeno); + } + else + draw_player(ablock(H_KOSTRA),celx,cely,p_positions_x[d],p_positions_y[d]-32,HUMAN_ADJUST,NULL); + + + } + } + + + +int draw_sloup_sector(celx,cely,sector) + { + TSTENA *w,*q; + int obl; + + w=&map_sides[sector*4]; + q=&w[dirs[1]]; + obl=GET_OBLOUK(q); + if (q->flags & SD_LEFT_ARC && q->oblouk) + show_cel2(celx,cely,ablock(num_ofsets[OBL_NUM]+obl),0,0,1); + if (q->flags & SD_RIGHT_ARC && q->oblouk) + show_cel2(celx,cely,ablock(num_ofsets[OBL2_NUM]+obl),0,0,2); + if (q->flags & SD_PRIM_VIS && q->prim) + show_cel2(celx,cely,ablock(num_ofsets[MAIN_NUM]+q->prim+(q->prim_anim>>4)),0,0,1+(q->oblouk & SD_POSITION)); + if (celx<=0) + { + q=&w[dirs[0]]; + if (q->flags & SD_PRIM_VIS && q->prim) + show_cel(-celx,cely,ablock(num_ofsets[LEFT_NUM]+q->prim+(q->prim_anim>>4)),0,0,2+(q->oblouk & SD_POSITION)); + } + if (celx>=0) + { + q=&w[dirs[2]]; + if (q->flags & SD_PRIM_VIS && q->prim) + show_cel(celx,cely,ablock(num_ofsets[RIGHT_NUM]+q->prim+(q->prim_anim>>4)),0,0,3+(q->oblouk & SD_POSITION)); + } + q=&w[dirs[1]]; + if (q->flags & SD_SEC_VIS && q->sec && cely!=0) + if (q->flags & SD_SPEC) + show_cel2(celx,cely-1,ablock(num_ofsets[MAIN_NUM]+q->sec+(q->sec_anim>>4)),0,0,2); + else + show_cel2(celx,cely-1,ablock(num_ofsets[MAIN_NUM]+q->sec+(q->sec_anim>>4)),(q->xsec<<1)+celx*(points[0][0][cely].x-points[0][0][cely-1].x)/2,q->ysec<<1,0); + return 0; + } + + +void swap_truesee(int ss) + { + int i; + for(i=0;i<4;i++) + { + TSTENA *s=map_sides+i+ss; + + if (s->flags & SD_TRUESEE) s->flags^=SD_PRIM_VIS | SD_SEC_VIS | SD_AUTOMAP; + } + } + +void draw_sector(int celx,int cely,int s) + { + int ss; + ss=s<<2; + if (true_seeing) swap_truesee(ss); + switch (map_sectors[s].sector_type) + { + case S_SSMRT: + case S_SLOUP: + case S_TELEPORT: + draw_sloup_sector(celx,cely,s); + draw_placed_items_normal(celx,cely,s,viewdir); + break; + case S_LODKA: + draw_basic_sector(celx,cely,s); + if (cely==0) draw_placed_items_normal(celx,cely,s,viewdir); + draw_lodku(celx,cely); + break; + default: + draw_basic_sector(celx,cely,s); + draw_placed_items_normal(celx,cely,s,viewdir); + break; + } + if (true_seeing) swap_truesee(ss); + } + +void back_clear(int celx,int color) + { + int x1,y1,x2,y2,xc; + y1=points[0][0][VIEW3D_Z].y+MIDDLE_Y+SCREEN_OFFLINE; + y2=points[0][1][VIEW3D_Z].y+MIDDLE_Y+SCREEN_OFFLINE; + x2=points[0][1][VIEW3D_Z].x+MIDDLE_X; + x1=-points[0][1][VIEW3D_Z].x+MIDDLE_X; + xc=(x2-x1+2)*celx; + x1=x1+xc-1; + x2=x2+xc; + if (x1<0) x1=0; + if (x2>640) x2=640; + if (x1sektor==viewsector && !(p->vlastnosti[VLS_KOUZLA] & SPL_BLIND)) return 0; + } + return 1; + } + +extern char folow_mode; + +static void zobraz_lodku(word *lodka, word *screen, int size) + { + int x; + while (size) + { + for (x=0;x<640 && size;x++) + { + if (*lodka!=0) screen[x]=*lodka; + lodka++; + size--; + } + screen+=scr_linelen2; + } + } +/* +static __inline void zobraz_lodku(word *data,word *scr,int _size) + { + __asm + { + mov ecx,_size + mov esi,data + mov edi,scr + add esi,6 +lp1:lodsw + or ax,ax + jz skp + mov [edi],ax +skp: add edi,2h + dec ecx + jnz lp1 + } + } +*/ + +static void trace_for_bgr(int dir) + { + int s,i; + static int olddist=0; + static int olddir=0; + TSTENA *ss; + + bgr_handle=0; + bgr_distance=-1; + for(i=0,s=0;iflags & SD_PRIM_VIS && !ss->prim) + { + bgr_distance=i-1; + bgr_handle=num_ofsets[BACK_NUM]+dir; + break; + } + } + if (olddist!=bgr_distance || olddir!=dir) + { + if (bgr_distance==-1) + { + word *w=GetScreenAdr();int i=scr_linelen2*480; + do {if (*w>=NOSHADOW(0)) *w=back_color;w++;} while(--i); + } + zneplatnit_block(H_BGR_BUFF); + } + olddist=bgr_distance; + olddir=dir; + } + + +void render_scene(sector,smer) + { + int i,j,s; + + cancel_render=0;see_monster=0; + destroy_fly_map(); + build_fly_map(); + if (set_blind() && cur_mode!=MD_END_GAME && !folow_mode) + { + clear_buff(NULL,0,360); + return; + } + if (set_halucination) + { + sector=hal_sector; + smer=hal_dir; + } + cur_sector=sector; + create_minimap(sector,smer); +// trace_for_bgr(smer); + i=VIEW3D_Z-1; + s=minimap[i][VIEW3D_X]; + if (s && !map_sectors[s].ceil) clear_buff(ablock(H_BGR_BUFF),back_color,360); + else clear_buff(ablock(H_BGR_BUFF),back_color,80); + for(i=-VIEW3D_X+1;i=0;i--) + { + word *p; + + p=minimap[i]; + left_shiftup=0;right_shiftup=0; + for(j=VIEW3D_X-1;j>=0;j--) + { + int s2; + if ((s=p[VIEW3D_X+j])!=0) + { + if (map_coord[s].flags & MC_SHADING) secnd_shade=1; else secnd_shade=0; + draw_basic_floor(j,i,s); + if (map_sides[(s<<2)+smer].flags & SD_TRANSPARENT) + { + s2=map_sectors[s].step_next[smer]; + draw_mob(s2,smer,j,i,1); + } + draw_sector(j,i,s); + } + if (j && (s=p[VIEW3D_X-j])) + { + if (map_coord[s].flags & MC_SHADING) secnd_shade=1; else secnd_shade=0; + draw_basic_floor(-j,i,s); + if (map_sides[(s<<2)+smer].flags & SD_TRANSPARENT) + { + s2=map_sectors[s].step_next[smer]; + draw_mob(s2,smer,-j,i,1); + } + draw_sector(-j,i,s); + } + } + for(j=VIEW3D_X-1;j>=0;j--) + { + if ((s=p[VIEW3D_X+j])!=0) + { + if (map_coord[s].flags & MC_SHADING) secnd_shade=1; else secnd_shade=0; + draw_players(s,viewdir,j,i); + draw_mob(s,viewdir,j,i,0); + draw_fly_items(j,i,s,viewdir); + draw_spectxtrs(s,j,i); + } + if (j && (s=p[VIEW3D_X-j])) + { + if (map_coord[s].flags & MC_SHADING) secnd_shade=1; else secnd_shade=0; + draw_players(s,viewdir,-j,i); + draw_mob(s,viewdir,-j,i,0); + draw_fly_items(-j,i,s,viewdir); + draw_spectxtrs(s,-j,i); + } + } + do_events(); + if (cancel_render) return; + } + calc_spectxtrs(); + if (lodka) zobraz_lodku(ablock(H_LODKA),LODKA_POS,LODKA_SIZ); + } + +void debug_print() + { + char s[256]; + static char indx=50; + static int counter=0; + + sprintf(s,"battle: %d waiting: %d lhit: %3d ldef: %3d dostal: %3d magic: %3d lives: %3d wpn: %d", + battle, neco_v_pohybu, dhit, ddef, ddostal, dmzhit, dlives, vybrana_zbran ); + trans_bar(0,17,640,15,0); + position(0,17);set_font(H_FBOLD,0x3ff); + if (debug_text!=NULL) + { + outtext(debug_text); + counter++; + if (counter==100) + { + counter=0; + debug_text=NULL; + } + } + else outtext(s); + if (dsee) indx--; + if (!indx) + { + dsee=0; + indx=10; + } + + } + +void redraw_scene() + { + if (norefresh) return; + if (one_buffer) RedirectScreenBufferSecond(); + render_scene(viewsector,viewdir); + if (cancel_render) return; + if (running_anm) klicovani_anm(GetBuffer2nd()+SCREEN_OFFSET,anim_render_buffer,anim_mirror); + update_mysky(); + schovej_mysku(); + if (one_buffer) RestoreScreen(); + OutBuffer2nd(); + if (battle || (game_extras & EX_ALWAYS_MINIMAP)) draw_medium_map(); + if (show_debug) debug_print(); + other_draw(); + ukaz_mysku(); + global_anim_counter++; + send_message(E_KOUZLO_ANM); + } + +void refresh_scene() + { + redraw_scene(); + if (!cancel_render && !norefresh) + { + showview(0,0,0,0); + calc_game(); + if (autoopenaction==1) {go_book(0,0,0,0,0);autoopenaction=0;} + } + } + +typedef struct fx_play + { + int x,y,phase; + struct fx_play *next; + }FX_PLAY; + +static FX_PLAY *fx_data=NULL; + +void draw_fx() + { + word *c; + FX_PLAY *fx; + FX_PLAY **last; + + if (fx_data==NULL) return; + fx=fx_data;last=&fx_data; + c=ablock(H_FX); + while (fx!=NULL) + { + put_8bit_clipped(c,GetScreenAdr()+fx->x+fx->y*scr_linelen2,fx->phase*16,c[0],16); + if (++fx->phase>14) + { + *last=NULL; + free(fx); + return; + } + last=&(fx->next); + fx=*last; + } + } + + +void play_fx(int x,int y) + { + FX_PLAY *fx; + + fx=New(FX_PLAY); + fx->next=fx_data; + fx->x=x; + fx->y=y; + fx->phase=0; + fx_data=fx; + } + +void play_fx_at(int where) + { + static word polex[]={313,290,362}; + static word poley[]={1,1,1}; + + play_fx(polex[where],poley[where]); + } + +void display_ver(int x,int y,int ax,int ay) + { + char *ver="Brny Skeldalu version "VERSION" (C)1998"; + set_font(H_FTINY,RGB555(31,31,31));set_aligned_position(x,y,ax,ay,ver); + outtext(ver);showview(0,0,0,0); + } diff --git a/GAME/CHARGEN.C b/GAME/CHARGEN.C new file mode 100644 index 0000000..cecfb0f --- /dev/null +++ b/GAME/CHARGEN.C @@ -0,0 +1,908 @@ +//CHARACTER GENERATOR +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "engine1.h" +#include +#include "globals.h" +#include + +//there is defined procedures from source "INV.C" + +void display_items_wearing(THUMAN *h); +void inv_display_vlastnosti();; +extern void (*inv_redraw)(); +void write_human_big_name(char *c); + +#define MSG_COLOR1 RGB555(30,30,23) + + +#define MAX_XICHTS 8 +#define MAX_CHARS 6 + +#define XICHT_STEP 40 + +#define INV_DESK 266 +#define INV_DESK_Y (SCREEN_OFFLINE) +#define INV_DESC_X 285 +#define INV_DESC_Y (SCREEN_OFFLINE+20) +#define HUMAN_X 40 +#define HUMAN_Y 328 + + +#define X_SKIP_X 64 +#define X_SKIP_Y 85 + +typedef struct staty + { + int zivl; + int zivh; + int manl; + int manh; + int konl; + int konh; + int akc; + }T_STATY; + +static T_STATY cur_stats; + +word color_butt_on[]={0,RGB555(31,27,4),RGB555(30,26,4),RGB555(29,25,4)}; +word color_butt_off[]={0,RGB555(10,10,10),RGB555(10,10,10),RGB555(10,10,10)}; + + +typedef struct vlasts + { + int sill; + int silh; + int smgl; + int smgh; + int pohl; + int pohh; + int obrl; + int obrh; + int hpreg; + int mpreg; + int vpreg; + }T_VLASTS; + +static T_VLASTS cur_vls; +static T_VLASTS rohy[9]= + { + {17,22, 5,10,17,22, 9,14, 3, 2, 3}, + {13,18,10,15,20,25, 5,10, 3, 3, 2}, + { 9,14,15,20,17,22, 9,14, 3, 3, 2}, + { 5,10,20,25,13,18,13,18, 2, 4, 2}, + { 9,14,15,20, 9,14,17,22, 2, 3, 2}, + {13,18,10,15, 5,10,20,25, 2, 2, 4}, + {17,22, 5,10, 9,14,17,22, 3, 1, 2}, + {20,25, 0, 5,13,18,13,18, 4, 1, 2}, + {12,17,12,17,12,17,12,17, 2, 2, 2}, + }; + +#define CALC_DIFF(x,y,angl) ((x)+(((((y)-(x))<<4)*((angl)<<4)/720+8)>>4)) +#define CALC_DIFF2(x,y,pol) ((x)+(((((y)-(x))<<4)*((pol)<<4)/(PERLA_MAXPOLOMER<<4)+8)>>4)) +#define DIFF_RAND(x,y) ((x)+rnd((y)-(x)+1)) + +#define MAX_RACES 5 +static char women[MAX_XICHTS]={0,0,0,0,1,1,1,1}; +static char poradi[MAX_XICHTS]={0,2,3,4,1,5,6,7}; +static char disable[MAX_XICHTS]; +static int cur_edited=0; +static int cur_angle=90; +static int cur_polomer=0; +static int cur_xicht=-1; +static char shut_downing_text=0; +static int save_values[POCET_POSTAV][2]; +static char del_mode=0; +static char was_enter=0; + + +#define PERLA_STRED_X (INV_DESK+189) +#define PERLA_STRED_Y (INV_DESK_Y+217) + + +#define PERLA_POLOMER cur_polomer +#define PERLA_MAXPOLOMER 75 +short *pod_perlou=NULL; +short pod_perlou_x=0; +short pod_perlou_y=0; +char *error_text=NULL; + + + +char select_xicht(int id,int xa,int ya,int xr,int yr); +char vol_vlastnosti(int id,int xa,int ya,int xr,int yr); +char go_next_page(int id,int xa,int ya,int xr,int yr); +char vls_click(int id,int xa,int ya,int xr,int yr); +char view_another_click2(int id,int xa,int ya,int xr,int yr); +//char edit_another_click(int id,int xa,int ya,int xr,int yr); +char edit_another_click2(int id,int xa,int ya,int xr,int yr); +char gen_exit_editor(int id,int xa,int ya,int xr,int yr); + +void zobraz_staty(T_VLASTS *st); + +#define CLK_PAGE1 6 + + +static T_CLK_MAP clk_page1[]= + { + {0,28+INV_DESK,18+INV_DESK_Y,334+INV_DESK,55+INV_DESK_Y,select_xicht,2,-1}, + {0,78+INV_DESK,97+INV_DESK_Y,314+INV_DESK,340+INV_DESK_Y,vol_vlastnosti,2+1,-1}, + {-1,520,378,639,479,go_next_page,2,-1}, + //{-1,54,378,497,479,edit_another_click,2+8,-1}, + {2,0,0,639,479,gen_exit_editor,8,-1}, + {0,0,0,639,479,empty_clk,0xff,-1}, + }; + +#define CLK_PAGE2 5 + +static T_CLK_MAP clk_page2[]= + { + {-1,INV_DESK,INV_DESK_Y,639,378,vls_click,2,-1}, + {-1,520,378,639,479,go_next_page,2,-1}, + {-1,54,378,497,479,view_another_click2,2,-1}, + {1,0,0,639,479,gen_exit_editor,8,-1}, + {0,0,0,639,479,empty_clk,0xff,-1}, + }; +#define CLK_PAGE3 4 + +/*static T_CLK_MAP clk_page3[]= + { + {-1,520,378,639,479,go_next_page,2,-1}, + {-1,54,378,497,479,view_another_click2,2+8,-1}, + {0,0,0,639,479,edit_another_click2,8,-1}, + {0,0,0,639,479,empty_clk,0xff,-1}, + }; +*/ + + +#define H_GENERACE (H_MENUS_FREE+100) +#define H_GEN_PERLA (H_MENUS_FREE+101) +#define H_GEN_TOPBAR (H_MENUS_FREE+102) +#define H_GEN_OKBUTT (H_MENUS_FREE+103) +#define H_GEN_CHARGEN (H_MENUS_FREE+104) +#define H_GEN_CHARGENB (H_MENUS_FREE+105) +#define H_GEN_CHARGENM (H_MENUS_FREE+106) +#define H_GEN_XICHTY (H_MENUS_FREE+107) +#define H_GEN_POSTAVY (H_GEN_XICHTY+MAX_XICHTS) + +TDREGISTERS char_gen_reg[]= + { + {H_GENERACE,"postavy.pcx",pcx_15bit_decomp,SR_BGRAFIKA}, + {H_GEN_PERLA,"perla.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_GEN_TOPBAR,"topbar_p.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_GEN_CHARGEN,"chargen.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_GEN_CHARGENB,"chargenb.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_GEN_CHARGENM,"chargenm.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + }; + +#define BOTT 378 +#define LEFT 520 + +char *b_texty[4]; +char b_disables; + +void displ_button(char disable,char **text) + { + int posy[]={0,18,37,55}; + int sizy[]={18,20,20,21}; + int i; + + set_font(H_FTINY,0); + put_picture(LEFT,BOTT,ablock(H_GEN_CHARGEN)); + for(i=0;i<4;i++) + { + if (disable & 1) + { + put_8bit_clipped(ablock(H_GEN_CHARGENB),(392+posy[i])*scr_linelen2+524+GetScreenAdr(),posy[i],96,sizy[i]); + font_color(color_butt_off); + } + else + { + font_color(color_butt_on); + } + disable>>=1; + set_aligned_position(LEFT+50,BOTT+14+13+i*19,1,2,*text); + outtext(*text); + text++; + } + } +static void draw_other_bar() + { + int i; + word *bbar=ablock(H_BOTTBAR); + word *screen=GetScreenAdr()+(480-102)*scr_linelen2; + for (i=0;i<102;i++,screen+=scr_linelen2,bbar+=scr_linelen2) memcpy(screen,bbar,scr_linelen); + //put_8bit_clipped(ablock(H_GEN_OKBUTT),378*640+520+screen,0,120,102); + displ_button(b_disables,b_texty); + put_picture(0,0,ablock(H_GEN_TOPBAR)); + zobraz_staty(&cur_vls); + } + + +static void display_character(THUMAN *p,char i) + { + word *w; + put_picture(4,SCREEN_OFFLINE,ablock(H_IOBLOUK)); + if (p->used) + { + w=ablock(H_GEN_POSTAVY+(p->xicht)); + put_picture(HUMAN_X+30,HUMAN_Y-w[1],w); + } + if (i) draw_other_bar(); + } +static void zobraz_error_text() + { + if (error_text!=NULL) + { + trans_bar(0,362,640,16,0); + set_font(H_FONT6,RGB555(31,31,0)); + position(10,364);outtext(error_text); + } + } + + + + +static void vypocet_perly(int angle,int xp,int yp,int *x,int *y) + { + float xr,yr; + float rad; + + rad=angle*3.14159265f/180; + xr=(float)cos(rad)*PERLA_POLOMER; + yr=(float)sin(rad)*PERLA_POLOMER; + *x=(int)xr+PERLA_STRED_X; + *y=PERLA_STRED_Y-(int)yr; + x[0]-=xp>>1; + y[0]-=yp>>1; + } + +static void zobraz_perlu(void) + { + word *perla; + int x,y; + word *scr,*sss; + char *p; + word *b; + int xs,ys,xxs; + + alock(H_GEN_PERLA); + perla=ablock(H_GEN_PERLA); + if (pod_perlou==NULL) + { + pod_perlou=getmem(perla[0]*perla[1]*2+6); + } + vypocet_perly(cur_angle,perla[0],perla[1],&x,&y); + xs=perla[0];ys=perla[1]; + get_picture(x,y,xs,ys,pod_perlou); + sss=x+scr_linelen2*y+GetScreenAdr(); + p=(char *)(perla+256+3); + b=perla+3; + for(;ys>0;ys--) + { + scr=sss; + for(xxs=0;xxs>1; + scr++;p++; + } + sss+=scr_linelen2; + } + //put_picture(x,y,perla); + pod_perlou_x=x; + pod_perlou_y=y; + aunlock(H_GEN_PERLA); + } + +static void schovej_perlu(void) + { + put_picture(pod_perlou_x,pod_perlou_y,pod_perlou); + } + +static void vypocet_vlastnosti(int angle,T_VLASTS *vls) + { + T_VLASTS *low,*hi; + div_t rm; + int p,test; + + rm=div(angle,45); + p=rm.quot; + low=rohy+p;p++;if (p>=8) p=0; + hi=rohy+p; + test=CALC_DIFF(8,12,44); + vls->sill=CALC_DIFF(low->sill,hi->sill,rm.rem); + vls->silh=CALC_DIFF(low->silh,hi->silh,rm.rem); + vls->smgl=CALC_DIFF(low->smgl,hi->smgl,rm.rem); + vls->smgh=CALC_DIFF(low->smgh,hi->smgh,rm.rem); + vls->obrl=CALC_DIFF(low->obrl,hi->obrl,rm.rem); + vls->obrh=CALC_DIFF(low->obrh,hi->obrh,rm.rem); + vls->pohl=CALC_DIFF(low->pohl,hi->pohl,rm.rem); + vls->pohh=CALC_DIFF(low->pohh,hi->pohh,rm.rem); + vls->hpreg=CALC_DIFF(low->hpreg,hi->hpreg,rm.rem); + vls->mpreg=CALC_DIFF(low->mpreg,hi->mpreg,rm.rem); + vls->vpreg=CALC_DIFF(low->vpreg,hi->vpreg,rm.rem); + low=&rohy[8];hi=vls;rm.rem=PERLA_POLOMER; + vls->sill=CALC_DIFF2(low->sill,hi->sill,rm.rem); + vls->silh=CALC_DIFF2(low->silh,hi->silh,rm.rem); + vls->smgl=CALC_DIFF2(low->smgl,hi->smgl,rm.rem); + vls->smgh=CALC_DIFF2(low->smgh,hi->smgh,rm.rem); + vls->obrl=CALC_DIFF2(low->obrl,hi->obrl,rm.rem); + vls->obrh=CALC_DIFF2(low->obrh,hi->obrh,rm.rem); + vls->pohl=CALC_DIFF2(low->pohl,hi->pohl,rm.rem); + vls->pohh=CALC_DIFF2(low->pohh,hi->pohh,rm.rem); + vls->hpreg=CALC_DIFF2(low->hpreg,hi->hpreg,rm.rem); + vls->mpreg=CALC_DIFF2(low->mpreg,hi->mpreg,rm.rem); + vls->vpreg=CALC_DIFF2(low->vpreg,hi->vpreg,rm.rem); + } + +/*static void vypocet_statu(T_VLASTS *vls,T_STATY *sts) + { + sts->zivl=vls->sill*3/2; + sts->zivh=vls->silh*3/2; + sts->manl=vls->smgl*2; + sts->manh=vls->smgh*2; + sts->konl=vls->obrl*2; + sts->konh=vls->obrh*2; + sts->akc=(((vls->pohl+vls->pohh)/2)+14)/15; + } +*/ + +static void zobraz_staty(T_VLASTS *st) + { + char s[100]; + + set_font(H_FTINY,0);font_color(color_topbar); + sprintf(s,texty[2],st->sill,st->silh); + position(230,2);outtext(s); + sprintf(s,texty[3],st->smgl,st->smgh); + position(330,2);outtext(s); + sprintf(s,texty[4],st->pohl,st->pohh); + position(430,2);outtext(s); + sprintf(s,texty[5],st->obrl,st->obrh); + position(530,2);outtext(s); + } + + +void redraw_generator(char show) + { + T_STATY z; + int i; + memset(&z,20,sizeof(z)); + schovej_mysku(); + put_picture(INV_DESK,SCREEN_OFFLINE,ablock(H_GENERACE)); + if (cur_xicht==-1) + { + put_picture(4,SCREEN_OFFLINE,ablock(H_IOBLOUK)); + bott_draw(1); + draw_other_bar(); + } + else display_character(postavy+cur_edited,1); + zobraz_error_text(); + zobraz_perlu(); + for(i=0;iused=1; + h->xicht=xicht; + h->vlastnosti[VLS_MAXHIT]=1; + h->vlastnosti[VLS_KONDIC]=1; + h->lives=1; + h->kondice=0; + h->mana=0; + h->sektor=viewsector; + h->groupnum=1; + h->jidlo=1; + h->voda=1; + h->bonus=0; + h->spell=0; + } + +static char select_xicht(int id,int xa,int ya,int xr,int yr) + { + int i,j,k; + char s[20]; + + i=xr/XICHT_STEP; + j=xr%XICHT_STEP; + if (j>27) return 0; + k=poradi[i]; + if (disable[k]) return 1; + memset(disable,0,sizeof(disable)); + set_xicht(cur_edited,cur_xicht=k); + postavy[cur_edited].female=women[i]; + b_disables=0x6; + if (was_enter) send_message(E_KEYBOARD,13); + else + { + strcpy(postavy[cur_edited].jmeno,texty[160+i]); + send_message(E_KEYBOARD,27); + was_enter=0; + } + sprintf(s,XICHT_NAME,k); + def_handle(H_XICHTY+cur_edited,s,pcx_8bit_decomp,SR_BGRAFIKA); + sprintf(s,CHAR_NAME,k); + def_handle(H_POSTAVY+cur_edited,s,pcx_8bit_decomp,SR_BGRAFIKA); + for(j=0;jpod_perlou_x+pod_perlou[0] || ya>pod_perlou_y+pod_perlou[1] ) + { + cancel=1; + return 0; + } + else cancel=0; + if (cancel) return 0; + xr=xa-PERLA_STRED_X; + yr=-(ya-PERLA_STRED_Y); + a=(int)(atan2((double)yr,(double)xr)*180/3.14159265); + cur_polomer=(int)sqrt(xr*xr+yr*yr); + if (cur_polomer>PERLA_MAXPOLOMER) cur_polomer=PERLA_MAXPOLOMER; + xa=pod_perlou_x; + ya=pod_perlou_y; + schovej_mysku(); + schovej_perlu(); + if (a<0) a+=360; + vypocet_vlastnosti(a,&cur_vls); + cur_angle=a; + zobraz_perlu(); + ukaz_mysku(); + update_mysky(); + showview(pod_perlou_x,pod_perlou_y,pod_perlou[0],pod_perlou[1]); + showview(xa,ya,pod_perlou[0],pod_perlou[1]); + put_picture(0,0,ablock(H_GEN_TOPBAR)); + zobraz_staty(&cur_vls); + showview(250,0,640,17); + return 1; + } + +static int edit_task=-1; + +static void edit_name() + { + if (shut_downing_text) return; + curcolor=0;bar(120,2,120+104,16); + edit_task=add_task(16384,type_text_v2,postavy[cur_edited].jmeno,120,2,104, + sizeof(postavy[cur_edited].jmeno)-1,H_FONT6,RGB555(31,31,0),edit_name); + } + +static void stop_edit_name() + { + shut_downing_text=1;send_message(E_KEYBOARD,13); + task_sleep(NULL); + if (edit_task>0 && is_running(edit_task)) + shut_down_task(edit_task); + shut_downing_text=0; + } + +/*static char edit_another_click(int id,int xa,int ya,int xr,int yr) + { + short *w; + + id,xa,ya,xr,yr; + w=ablock(H_OKNO); + id=xr/w[0]; + if (!postavy[id].used) return 0; + shut_downing_text=1; + send_message(E_KEYBOARD,13); + shut_downing_text=0; + save_values[cur_edited][0]=cur_angle; + save_values[cur_edited][1]=cur_polomer; + select_player=cur_edited=id; + cur_angle=save_values[cur_edited][0]; + cur_polomer=save_values[cur_edited][1]; + vypocet_vlastnosti(cur_angle,&cur_vls); + cur_xicht=postavy[cur_edited].xicht; + edit_name(); + bott_draw(1); + redraw_generator(); + return 1; + } +*/ + + +static void def_entries() + { + int i; + int s; + TDREGISTERS *p; + + s=sizeof(char_gen_reg)/sizeof(TDREGISTERS); + p=char_gen_reg; + for(i=0;ih_num,p->name,p->proc,p->path); + for(i=0;iused=1; + h->groupnum=1; + v=h->stare_vls; + v[VLS_SILA]=DIFF_RAND(cur_vls.sill,cur_vls.silh); + v[VLS_SMAGIE]=DIFF_RAND(cur_vls.smgl,cur_vls.smgh); + v[VLS_POHYB]=DIFF_RAND(cur_vls.pohl,cur_vls.pohh); + v[VLS_OBRAT]=DIFF_RAND(cur_vls.obrl,cur_vls.obrh); + v[VLS_HPREG]=cur_vls.hpreg; + v[VLS_MPREG]=cur_vls.mpreg; + v[VLS_VPREG]=cur_vls.vpreg; +// v[VLS_THIEF]=cur_vls.vpreg; + h->lives=v[VLS_MAXHIT]=(v[VLS_SILA]*3+v[VLS_POHYB])/2; + h->mana=v[VLS_MAXMANA]=v[VLS_SMAGIE]*2; + h->kondice=v[VLS_KONDIC]=v[VLS_OBRAT]*2; + v[VLS_OBRAN_L]=1; + v[VLS_OBRAN_H]=2; + v[VLS_UTOK_L]=1; + v[VLS_UTOK_H]=2; + prepocitat_postavu(h); + h->inv_size=6; + h->level=1; + h->exp=0; + h->bonus=5; + h->jidlo=MAX_HLAD(h); + h->voda=MAX_ZIZEN(h); + h->mana_battery=32767; + //postava je vygenerovana + } + +static void redraw_page3() + { + update_mysky(); + schovej_mysku(); + curcolor=0; + inv_display_vlastnosti(); + display_character(postavy+cur_edited,1); + write_human_big_name(postavy[cur_edited].jmeno); + draw_other_bar(); + displ_button(b_disables,b_texty); + ukaz_mysku(); + showview(0,0,0,0); + inv_redraw=redraw_page3; + } + + +static void redraw_svitek() + { + if (postavy[cur_edited].bonus==0) + { + char mode; + mode=7; + if (postavy[charmin-1].used) mode&=~2; + if (!postavy[charmax-1].used) mode&=~1; + if (!del_mode) mode&=~4; + b_disables=mode; + redraw_page3(); + return; + } + update_mysky(); + schovej_mysku(); + curcolor=0; + bar(0,16,30,16+360); + bar(620,16,640,16+360); + inv_display_vlastnosti(); + display_character(postavy+cur_edited,0); +// display_items_wearing(human_selected); +// write_pocet_sipu(); +// display_rings(); + zobraz_error_text(); + displ_button(b_disables,b_texty); + ukaz_mysku(); + showview(0,0,0,0); + inv_redraw=redraw_svitek; + } + + +static char validate_character(THUMAN *h) + { + if (h->jmeno[0]==0) error_text=texty[111]; + else error_text=NULL; + return error_text==NULL; + } + +/*static char edit_another_click2(int id,int xa,int ya,int xr,int yr) + { + id,xa,ya,xr,yr; + cur_edited=select_player; + schovej_mysku(); + edit_name(); + draw_other_bar(); + send_message(E_CLOSE_GEN,0); + ukaz_mysku(); + update_mysky(); + return 1; + } + */ +static void empty_proc() + { + } + +char potvrzeno(char *text,void (*redraw)()) + { + int i; + unwire_proc=empty_proc; + stop_edit_name(); + i=message(2,0,1,texty[118],text,texty[114],texty[115])==0; + redraw(); + edit_name(); + return i; + } + +static char view_another_click2(int id,int xa,int ya,int xr,int yr) + { + short *w; + + id,xa,ya,xr,yr; + w=ablock(H_OKNO); + id=xr/w[0]; + if (!(~b_disables & 0x3)) return 1; + if (!postavy[id].used) return 0; + shut_downing_text=1;send_message(E_KEYBOARD,13); + shut_downing_text=0; + select_player=id; + bott_draw(1); + human_selected=postavy+id; + cur_edited=id; + edit_name(); + redraw_page3(); + if (del_mode) + if (potvrzeno(texty[117],redraw_page3)) + { + del_mode=0; + postavy[cur_edited].used=0; + disable[postavy[cur_edited].xicht]=0; + send_message(E_CLOSE_GEN,0); + } + return 0; + } + +void effect_show(va_list args) + { + int i; + schovej_mysku(); + for(i=0;i<12;i++) + { + showview(0,240-i*20-20,640,20); + showview(0,240+(i*20),640,20); + task_wait_event(E_TIMER); + } + ukaz_mysku(); + } + + +static void enter_reaction(EVENT_MSG *msg,void **unused) + { + unused; + if (msg->msg==E_KEYBOARD) + { + if (*(char *)msg->data==13 && !shut_downing_text) + { + send_message(E_KEYBOARD,13); + bott_draw(1); + redraw_generator(1); + msg->msg=-1; + } + was_enter=1; + } + } + +static void enter_reaction2(EVENT_MSG *msg,void **unused) + { + unused; + if (msg->msg==E_KEYBOARD && *(char *)msg->data==13 && !shut_downing_text && ~b_disables & 0x3) + { + send_message(E_KEYBOARD,13); + bott_draw(1); + redraw_page3(); + msg->msg=-1; + } + } + + +char gen_exit_editor(int id,int xa,int ya,int xr,int yr) + { + xa,ya,xr,yr,id; + + if (del_mode==1) + { + del_mode=0; + mouse_set_default(H_MS_DEFAULT); + b_disables&=~0x4; + redraw_svitek(); + return 1; + } + unwire_proc=empty_proc; + shut_downing_text=1;send_message(E_KEYBOARD,13);shut_downing_text=0; + if (message(2,0,1,texty[118],texty[113],texty[114],texty[115])==0) + { + send_message(E_CLOSE_GEN,255); + } + else + { + if (id==2)redraw_generator(1); + else redraw_svitek(); + edit_name(); + } + return 1; + } + +char enter_generator() + { + int i; + char rep=0; + + znova: + del_mode=0; + stop_edit_name(); + b_texty[0]=texty[170]; + b_texty[1]=texty[171]; + b_texty[2]=texty[172]; + b_texty[3]=texty[173]; + def_entries(); + curcolor=0;bar(0,0,639,479); + cur_angle=315; + cur_edited=0; + memset(postavy,0,sizeof(postavy)); + memset(disable,0,sizeof(disable)); + memset(save_values,0,sizeof(save_values)); + do + { + mouse_set_default(H_MS_DEFAULT); + cur_angle=save_values[cur_edited][0]; + cur_polomer=save_values[cur_edited][1]; + set_xicht(cur_edited,cur_xicht=-1); + select_player=-1; + memset(&cur_stats,0,sizeof(cur_stats)); + vypocet_vlastnosti(cur_angle,&cur_vls); + b_disables=0x7; + redraw_generator(rep);if (!rep)effect_show(NULL);rep=1; + edit_name(); + change_click_map(clk_page1,CLK_PAGE1); + was_enter=0; + do + { + send_message(E_ADD,E_KEYBOARD,enter_reaction); + i=*(char *)task_wait_event(E_CLOSE_GEN); + send_message(E_DONE,E_KEYBOARD,enter_reaction); + if (i==3 && potvrzeno(texty[116],redraw_generator)) goto znova; + if (i==255) return 1; + } + while (cur_xicht==-1 || i==3); + send_message(E_KEYBOARD,13); + save_values[cur_edited][0]=cur_angle; + save_values[cur_edited][1]=cur_polomer; + cur_xicht=0; + error_text=NULL; + generuj_postavu(postavy+cur_edited); + human_selected=postavy+cur_edited; + b_disables=0x7; + do + { + redraw_svitek(); + change_click_map(clk_page2,CLK_PAGE2); + do + { + send_message(E_ADD,E_KEYBOARD,enter_reaction2); + i=*(char *)task_wait_event(E_CLOSE_GEN); + send_message(E_DONE,E_KEYBOARD,enter_reaction2); + if (i==3 && potvrzeno(texty[116],redraw_svitek)) goto znova; + if (i==2) + { + del_mode=1; + mouse_set_default(H_MS_WHO); + b_disables|=0x4; + redraw_svitek(); + i=3; + } + } + while (i==3); + mouse_set_default(H_MS_DEFAULT); + del_mode=0; + send_message(E_KEYBOARD,13); + if (i==255) return 1; + if (validate_character(postavy+cur_edited)) + for(cur_edited=0;postavy[cur_edited].used;cur_edited++); + } + while (error_text!=NULL); + stop_edit_name(); + } + while (i!=1); + disable_click_map(); + schovej_mysku(); + curcolor=0; + bar(0,0,639,479); + showview(0,0,0,0); + ukaz_mysku(); + for(i=0;i<3;i++) + { + if (postavy[i].vlastnosti[VLS_SILA]>20) postavy[i].stare_vls[VLS_UTOK_H]++; + if (postavy[i].vlastnosti[VLS_OBRAT]>20) postavy[i].stare_vls[VLS_OBRAN_H]++; + } + return 0; + } + + + + + + + + + diff --git a/GAME/CHARGEN2.C b/GAME/CHARGEN2.C new file mode 100644 index 0000000..0139e85 --- /dev/null +++ b/GAME/CHARGEN2.C @@ -0,0 +1,344 @@ +//CHARACTER GENERATOR + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "engine1.h" +#include +#include "globals.h" +#include + +//there is defined procedures from source "INV.C" + +void display_items_wearing(THUMAN *h); + + +#define MAX_XICHTS 8 +#define MAX_CHARS 3 + +#define INV_DESK 266 +#define INV_DESC_X 285 +#define INV_DESC_Y (SCREEN_OFFLINE+20) +#define HUMAN_X 40 +#define HUMAN_Y 328 + + +#define X_SKIP_X 64 +#define X_SKIP_Y 85 + +typedef struct staty + { + char zivl; + char zivh; + char manl; + char manh; + char konl; + char konh; + char akc; + }T_STATY; + +#define MAX_RACES 5 +static char women[MAX_XICHTS]={0,1,0,0,0,1,0,0};//,0,0}; +static int cur_edited=0; +static int cur_xicht=-1; +static int cur_page=1; +static int loc_select=-1; + +#define CLK_PAGE1 3 + + + +static T_CLK_MAP clk_page1[]= + { + + }; + +static void display_character(THUMAN *p) + { + word *w; + put_picture(4,SCREEN_OFFLINE,ablock(H_IOBLOUK)); + if (p->used) + { + w=ablock(hl_ptr+MAX_XICHTS+(p->xicht)); + put_picture(HUMAN_X+30,HUMAN_Y-w[1],w); + } + } +/* +static void display_all_xichts() + { + int i,a,x,y; + + a=0; + x=INV_DESC_X;y=INV_DESC_Y; + for(i=0;i4) + { + a=0; + x=INV_DESC_X; + y+=X_SKIP_Y; + } + } + } +*/ +/* +static void display_race_line(int line,char pushed) + { + int x,y; + char *c; + + set_font(H_FBOLD,pushed?0x3e0:0x7fff); + x=INV_DESK+137;y=INV_DESC_Y+170+22*line; + put_textured_bar(ablock(H_BUTBIG),x,y,100,20,0,20*pushed); + x+=49+pushed;y+=9+pushed; + if (cur_xicht==-1 || !women[cur_xicht]) c=texty[line+110];else c=texty[line+115]; + set_aligned_position(x,y,1,1,c);outtext(c); + } +*/ + +static void tlac2(int x,int y,char *text,int pushed) + { + set_font(H_FBOLD,pushed?0x3e0:0x7fff); + put_textured_bar(ablock(H_BUTSMALL),x,y,56,20,0,20*pushed); + x+=27+pushed;y+=9+pushed; + set_aligned_position(x,y,1,1,text);outtext(text); + } + +static tlac2_press(int x,int y,char *text) + { + schovej_mysku(); + tlac2(x,y,text,1); + ukaz_mysku(); + showview(x,y,56,20); + } + +/* +static void display_page2() + { + int i,x,y; + char s[10]; + + set_font(H_FBOLD,0x7fff); + position(INV_DESC_X,INV_DESC_Y);outtext(texty[122]); + x=INV_DESC_X+10;y=INV_DESC_Y+100; + for(i=0;i<4;i++) + { + position(x,y);outtext(texty[i+10]); + sprintf(s,"%d",postavy[cur_edited].stare_vls[i+VLS_SILA]); + set_aligned_position(x+140,y,2,0,s);outtext(s); + tlac2(x+150,y-5,"-",0); + tlac2(x+210,y-5,"+",0); + y+=30; + } + position(x,y);outtext(texty[19]); + sprintf(s,"%d",postavy[cur_edited].bonus); + set_aligned_position(x+140,y,2,0,s);outtext(s); + } +*/ +static void zobraz_staty(T_STATY *st) + { + char s[100]; + + set_font(H_FONT6,(28*1024+16*32+2)); + sprintf(s,texty[2],st->zivl,st->zivh); + position(250,3);outtext(s); + sprintf(s,texty[3],st->manl,st->manh); + position(350,3);outtext(s); + sprintf(s,texty[4],st->konl,st->konh); + position(450,3);outtext(s); + sprintf(s,texty[5],st->akc); + position(550,3);outtext(s); + } + +void redraw_generator() + { + T_STATY z; + memset(&z,20,sizeof(z)); + schovej_mysku(); + put_picture(INV_DESK,SCREEN_OFFLINE,ablock(H_GENERACE)); + put_picture(0,SCREEN_OFFLINE,ablock(H_IOBLOUK)); + bott_draw(1); + memcpy(screen+(480-102)*640,ablock(H_BOTTBAR),640*102*2); + put_picture(0,0,ablock(H_GEN_TOPBAR)); + zobraz_staty(&z); + ukaz_mysku(); + showview(0,0,0,0); + } + +static char page1_xicht(int id,int xa,int ya,int xr,int yr) + { + THUMAN *p; + char s[15]; + xa,ya,id; + if (xr%X_SKIP_X>54 || yr%X_SKIP_Y>75) return 0; + xr/=X_SKIP_X; + yr/=X_SKIP_Y; + cur_xicht=yr*5+xr; + sprintf(s,CHAR_NAME,cur_xicht); + def_handle(H_CHARS+cur_edited,s,pcx_fade_decomp,SR_BGRAFIKA); + sprintf(s,XICHT_NAME,cur_xicht); + def_handle(H_XICHTY+cur_edited,s,pcx_8bit_decomp,SR_BGRAFIKA); + p=postavy+cur_edited; + p->used=1; + p->lives=1; + p->xicht=cur_xicht; + p->sektor=viewsector; + prepocitat_postavu(p); + redraw_generator(); + return 1; + } + +static char page1_tlac1(int id,int xa,int ya,int xr,int yr) + { + yr/=22;yr,xa,ya,id,xr; + if (yrvlastnosti; + //common definiton + p->used=1; + p->groupnum=1; + p->sipy=0; + p->inv_size=6; + p->level=1; + p->exp=rnd(200); + p->female=women[p->xicht]; + switch(povolani) + { + case 0:w[VLS_SILA]=5+rnd(5); + w[VLS_SMAGIE]=0; + w[VLS_POHYB]=rnd(7)+2; + w[VLS_OBRAT]=rnd(5)+1; + w[VLS_MAXHIT]=10+rnd(10); + w[VLS_MAXMANA]=0; + w[VLS_KONDIC]=rnd(10)+10; + w[VLS_HPREG]=2; + w[VLS_MPREG]=1; + w[VLS_VPREG]=1; + p->bonus_zbrani[TPW_MEC]=1; + p->bonus_zbrani[TPW_SEKERA]=1; + break; + case 1:w[VLS_SILA]=rnd(5)+3; + w[VLS_SMAGIE]=rnd(5); + w[VLS_POHYB]=rnd(7)+2; + w[VLS_OBRAT]=rnd(7)+1; + w[VLS_MAXHIT]=10+rnd(10); + w[VLS_MAXMANA]=rnd(10); + w[VLS_KONDIC]=rnd(10)+10; + w[VLS_HPREG]=1; + w[VLS_MPREG]=1; + w[VLS_VPREG]=2; + p->bonus_zbrani[TPW_MEC]=1; + p->bonus_zbrani[TPW_DYKA]=1; + break; + case 2:w[VLS_SILA]=rnd(4)+1; + w[VLS_SMAGIE]=rnd(5)+5; + w[VLS_POHYB]=rnd(4)+1; + w[VLS_OBRAT]=rnd(4)+1; + w[VLS_MAXHIT]=5+rnd(5); + w[VLS_MAXMANA]=5+rnd(10); + w[VLS_KONDIC]=rnd(5)+10; + w[VLS_HPREG]=1; + w[VLS_MPREG]=2; + w[VLS_VPREG]=1; + p->bonus_zbrani[TPW_HUL]=1; + p->bonus_zbrani[TPW_DYKA]=1; + break; + case 3:w[VLS_SILA]=rnd(4)+1; + w[VLS_SMAGIE]=0; + w[VLS_POHYB]=rnd(5)+4; + w[VLS_OBRAT]=rnd(5)+5; + w[VLS_MAXHIT]=10+rnd(5); + w[VLS_MAXMANA]=0; + w[VLS_KONDIC]=rnd(5)+10; + w[VLS_HPREG]=1; + w[VLS_MPREG]=1; + w[VLS_VPREG]=1; + p->bonus_zbrani[TPW_STRELNA]=3; + break; + case 4:w[VLS_SILA]=rnd(4)+1; + w[VLS_SMAGIE]=0; + w[VLS_POHYB]=rnd(7)+2; + w[VLS_OBRAT]=rnd(4)+6; + w[VLS_MAXHIT]=5+rnd(5); + w[VLS_MAXMANA]=5+rnd(10); + w[VLS_KONDIC]=rnd(5)+10; + w[VLS_HPREG]=1; + w[VLS_MPREG]=1; + w[VLS_VPREG]=1; + p->bonus_zbrani[TPW_DYKA]=3; + break; + } + p->lives=w[VLS_MAXHIT]; + p->mana=w[VLS_MAXMANA]; + p->kondice=w[VLS_KONDIC]; + p->jidlo=MAX_HLAD(p); + p->voda=MAX_ZIZEN(p); + memcpy(p->stare_vls,p->vlastnosti,sizeof(p->vlastnosti)); + } + +static char page1_tlac2(int id,int xa,int ya,int xr,int yr) + { + id,xa,ya,xr,yr; + tlac2_press(INV_DESK+290,340,texty[120]); + timered_redraw(); + if (cur_xicht==-1 || loc_select==-1) return 1; + cur_page=2; + generate_vlastnosti(postavy+cur_edited,loc_select); + return 1; + } + + +void enter_generator() + { + int i; + + curcolor=0;bar(0,0,639,479); + for(i=0;i +#include +#include +#include +#include +#include +#include +#include +#include "globals.h" +#include "engine1.h" + +#define get_shift_state() ((GetKeyState(VK_SHIFT) & 0x80)!=0) +int default_ms_cursor=0; + +char spell_cast=0; + +char clk_step(int id,int xa,int ya,int xr,int yr) + { + xa;ya;xr;yr; + spell_cast=0; + pick_set_cursor(); + switch (id) + { + case H_SIPKY_S:step_zoom(0);break; + case H_SIPKY_J:step_zoom(2);break; + case H_SIPKY_SV:turn_zoom(1);break; + case H_SIPKY_SZ:turn_zoom(-1);break; + case H_SIPKY_Z:step_zoom(3);break; + case H_SIPKY_V:step_zoom(1);break; + default:return 0; + } + return 1; + } + +char clk_touch_vyk(int sector,int side,int xr,int yr) + { + int i; + TVYKLENEK *v; + int x1,y1,x2,y2; + + if (picked_item!=NULL && picked_item[1]!=0) return 0; + for(i=0;v=map_vyk+i,isector==sector && v->dir==side) break; + if (i==vyk_max) return 0; + x1=v->xpos-v->xs/2; + x2=v->xpos+v->xs/2; + y1=320-(v->ypos+v->ys); + y2=320-(v->ypos); + x1+=MIDDLE_X-points[0][1][1].x; + x2+=MIDDLE_X-points[0][1][1].x; + y1+=MIDDLE_Y+points[0][1][1].y; + y2+=MIDDLE_Y+points[0][1][1].y; + if (x1<=xr && xr<=x2 && y1<=yr && yr<=y2) + { + if (picked_item==NULL) + { + for(i=0;v->items[i];i++);if (!i) return 0; + i--; + picked_item=NewArr(short,2); + picked_item[0]=v->items[i];picked_item[1]=0; + v->items[i]=0; + do_items_specs(); + pick_set_cursor(); + call_macro(viewsector*4+viewdir,MC_VYKEVENT); + return 1; + } + else + { + int fc; + word *w; + for(i=0;v->items[i];i++);if (i==8) + { + bott_disp_text(texty[36]); + return 1; + } + fc=picked_item[0];fc=glob_items[fc-1].vzhled+face_arr[0]; + w=ablock(fc); + if (v->xsysitems[i]=picked_item[0]; + v->items[i+1]=0; + call_macro(viewsector*4+viewdir,MC_VYKEVENT); + free(picked_item);picked_item=NULL; + pick_set_cursor(); + return 1; + } + } + return 0; + } + +char clk_touch(int id,int xa,int ya,int xr,int yr) + { + int x1,y1,x2,y2; + word *p; + int ext=0; + + xa;ya;id; + spell_cast=0; + pick_set_cursor(); + id=viewsector*4+viewdir; + if (map_sides[id].oblouk & 0x10) if (clk_touch_vyk(viewsector,viewdir,xr,yr))return 1; + if (map_sides[id].flags & SD_SEC_VIS && map_sides[id].sec!=0) + { + xa=map_sides[id].xsec<<1; + ya=320-(map_sides[id].ysec<<1); + p=(word *)ablock(map_sides[id].sec+num_ofsets[MAIN_NUM]); + x1=*p++;y1=*p++; + x2=xa+x1/2;y2=ya+y1/2;y1=y2-y1;x1=x2-x1; + x1+=MIDDLE_X-points[0][1][1].x; + x2+=MIDDLE_X-points[0][1][1].x; + y1+=MIDDLE_Y+points[0][1][1].y; + y2+=MIDDLE_Y+points[0][1][1].y; + ext=1; + } + else if (map_sides[id].sec==0) + { + x1=MIDDLE_X-points[0][0][1].x; + y1=MIDDLE_Y+points[0][1][1].y; + x2=640-x1; + y2=MIDDLE_Y+points[0][0][1].y; + ext=((map_sides[id].flags & SD_THING_IMPS) && !(map_sides[id].oblouk & SD_ITPUSH)); + } + if (x1<=xr && xr<=x2 && y1<=yr && yr<=y2) + { + a_touch(viewsector,viewdir); + return ext; + } + return 0; + } + +char clk_fly_cursor(int id,int xa,int ya,int xr,int yr) + { + id; + + if (spell_cast) + { + spell_cast=0; + pick_set_cursor(); + return 1; + } + if (yr>180) + if(xr>480) clk_step(H_SIPKY_V,xa,ya,xr,yr); + else if(xr<160) clk_step(H_SIPKY_Z,xa,ya,xr,yr); + else clk_step(H_SIPKY_J,xa,ya,xr,yr); + else + if(xr>480) clk_step(H_SIPKY_SV,xa,ya,xr,yr); + else if(xr<160) clk_step(H_SIPKY_SZ,xa,ya,xr,yr); + else clk_step(H_SIPKY_S,xa,ya,xr,yr); + return 1; + } + +char clk_throw(int id,int xa,int ya,int xr,int yr) + { + id,xa,ya; + if (picked_item!=NULL) + { + throw_fly(xr,yr,0); + return 1; + } + return 0; + } + +char go_map(int id,int xa,int ya,int xr,int yr) + { + int i=15*256; + id;xa;ya;xr;yr; + + if (cur_mode==MD_ANOTHER_MAP) + {unwire_proc();wire_proc();return 1;} + spell_cast=0; + pick_set_cursor(); + send_message(E_KEYBOARD,i); + return 1; + } + +char go_book(int id,int xa,int ya,int xr,int yr) + { + id;xa;ya;xr;yr; + + if (cur_mode==MD_ANOTHER_MAP) unwire_proc(),wire_proc(); + spell_cast=0; + pick_set_cursor(); + wire_kniha(); + return 1; + } + + +char konec(int id,int xa,int ya,int xr,int yr) + { + id;xa;ya;xr;yr; + unwire_proc(); + if (!message(2,0,1,texty[118],texty[76],texty[77],texty[78])) + { + if (cur_mode==MD_ANOTHER_MAP) unwire_proc(),wire_proc(); + send_message(E_CLOSE_MAP); + } + else wire_proc(); + return 1; + } + +char spell_casting(int id,int xa,int ya,int xr,int yr) + { + id;xa;ya;xr;yr; + if (picked_item!=NULL) return 1; + spell_cast=1; + mouse_set_default(H_MS_WHO); + return 1; + } + + +char clk_sleep(int id,int xa,int ya,int xr,int yr) + { + id;xa;ya;xr;yr; + if (cur_mode==MD_ANOTHER_MAP) unwire_proc(),wire_proc(); + if (mglob.map_effector==ME_MESTO) + { + bott_disp_text(texty[120]); + return 1; + } + if (!battle) add_task(8100,sleep_players); + return 1; + } + + +char start_invetory(int id,int xa,int ya,int xr,int yr) + { + THUMAN *p; + int i; + word *xs; + + id;xa;ya;yr; + if (cur_mode==MD_ANOTHER_MAP) unwire_proc(),wire_proc(); + if (bott_display!=BOTT_NORMAL) + { + schovej_mysku(); + bott_draw(1); + other_draw(); + ukaz_mysku(); + showview(0,376,640,104); + return 1; + } + xs=ablock(H_OKNO); + i=xr/xs[0]; + if (iused) + { + if (ms_last_event.event_type & 0x2) + { + if (GetKeyState(VK_CONTROL) & 0x80) + { + if (p->sektor==viewsector) + { + add_to_group(i); + zmen_skupinu(p); + return 1; + } + return 1; + } + if (select_player!=i && select_player!=-1 && picked_item==NULL && !(cur_mode==MD_INV && battle_mode==MD_PREZBROJIT)) + { + select_player=i; + zmen_skupinu(p); + bott_draw(1); + if (cur_mode==MD_INBATTLE) return 1; + } + if (p->groupnum!=cur_group || spell_cast) + { + if (picked_item!=NULL && p->sektor!=viewsector) return 0; + if (spell_cast && p->sektor==viewsector) + { + wire_fly_casting(i); + spell_cast=0; + mouse_set_default(H_MS_DEFAULT); + return 1; + } + zmen_skupinu(p); + if (cur_mode==MD_GAME && p->groupnum) return 1; + } + if (!p->groupnum && p->sektor!=viewsector) return 1; + unwire_proc(); + wire_inv_mode(p); + return 0; + } + else + { + if (picked_item==NULL) return 0; + if (p->sektor==viewsector) + if (put_item_to_inv(p,picked_item)) + { + free(picked_item); + picked_item=NULL; + } + pick_set_cursor(); + if (cur_mode==MD_INV) + { + unwire_proc(); + wire_inv_mode(human_selected); + } + return 1; + } + } + } + return 0; + } + +char clk_group_all(int id,int xa,int ya,int xr,int yr) + { + id,xa,ya,xr,yr; + unwire_proc(); + wire_proc(); + group_all(); + return 1; + } + +char clk_saveload(int id,int xa,int ya,int xr,int yr) + { + xa;ya;xr;yr; + if (id && battle) + { + bott_disp_text(texty[81]);other_draw();showview(0,0,0,0); + return 1; + } + if (id && !GlobEvent(MAGLOB_CLICKSAVE,viewsector,viewdir)) + return 1; + if (cur_mode==MD_ANOTHER_MAP) unwire_proc(),wire_proc(); + unwire_proc(); + cancel_render=1; + wire_save_load(id); + return 1; + } + +char return_game(int id,int xa,int ya,int xr,int yr) + { + id;xa;ya;xr;yr; + if (ms_last_event.event_type & 0x8) + { + unwire_proc(); + wire_proc(); + } + return 0; + } + +char clk_mob_alter(int id,int xa,int ya,int xr,int yr) + { + id;xa;ya;xr;yr; + + xa=viewsector; + id=mob_map[xa]; + while (id==0 || mobs[id-1].dialog==-1) + { + if (id) id=mobs[id-1].next; + if (id==0 && xa==viewsector) + if (~map_sides[(xa<<2)+viewdir].flags & SD_PLAY_IMPS) + { + xa=map_sectors[xa].step_next[viewdir]; + id=mob_map[xa]; + } + else return 0; + else return 0; + } + id--; + start_dialog(mobs[id].dialog,id); + return 1; + } + +char empty_clk(int id,int xa,int ya,int xr,int yr) //tato udalost slouzi ke zruseni nekterych mist v globalni mape + { + id,xa,ya,xr,yr; + return 1; + } + +static char sing_song_clk(int id,int xa,int ya,int xr,int yr) + { + char *xadr; + word *xs; + static char playing=0; + char standardflute=map_sectors[viewsector].sector_type>=S_FLT_SMER && + map_sectors[viewsector].sector_type12 || (ms_last_event.event_type & 0x4)) + { + if (playing) + { + THE_TIMER *t; + stop_play_flute(); + playing=0; + if (standardflute) + { + if (fletna_get_buffer_pos()) + { + THE_TIMER *t; + if (standardflute) + { + t=add_to_timer(TM_FLETNA,100,1,check_fletna); + t->userdata[0]=viewsector; + t->userdata[1]=viewdir; + } + } + } + else + { + t=add_to_timer(TM_FLETNA,100,1,check_global_fletna); + t->userdata[0]=viewsector; + t->userdata[1]=viewdir; + } + + } + return id<12; + } + if (~ms_last_event.event_type & 0x2) return 1; + start_play_flute(id); + playing=1; + if (standardflute) + { + fletna_pridej_notu(id); + delete_from_timer(TM_FLETNA); + } + else + { + fletna_glob_add_note(id); + delete_from_timer(TM_FLETNA); + } + return 1; + } + + +T_CLK_MAP clk_main_view[]= + { + {H_SIPKY_S,561,378,598,407,clk_step,2,H_MS_DEFAULT}, + {H_SIPKY_SZ,530,387,560,418,clk_step,2,H_MS_DEFAULT}, + {H_SIPKY_Z,529,419,555,453,clk_step,2,H_MS_DEFAULT}, + {H_SIPKY_J,560,446,598,474,clk_step,2,H_MS_DEFAULT}, + {H_SIPKY_SV,599,387,628,418,clk_step,2,H_MS_DEFAULT}, + {H_SIPKY_V,605,420,632,454,clk_step,2,H_MS_DEFAULT}, + {MS_GAME_WIN,0,17,639,377,clk_fly_cursor,8,-1}, + {1,320,303,639,376,pick_item_,2,-1},//344 + {0,0,303,320,376,pick_item_,2,-1},//344 + {3,0,200,320,340,pick_item_,2,-1},//303 + {2,320,200,639,340,pick_item_,2,-1},//303 + {MS_GAME_WIN,0,17,639,377,clk_touch,2,-1}, + {MS_GAME_WIN,0,17,639,377,clk_throw,2,-1}, + {MS_GAME_WIN,0,17,639,250,clk_mob_alter,2,-1}, + {-1,0,378,639,479,sing_song_clk,0xff,-1}, + {-1,54,378,497,479,start_invetory,2+8,-1}, + {-1,315,0,335,14,spell_casting,2,-1}, + }; + +#define GAME_CLK_MAP 8 +T_CLK_MAP game_clk_map[]= + { + {-1,499,379,518,390,clk_group_all,2,-1}, + {-1,337,0,357,14,go_map,2,H_MS_DEFAULT}, + {-1,291,0,313,14,go_book,2,H_MS_DEFAULT}, + {-1,87,0,142,14,game_setup,2,H_MS_DEFAULT}, + {-1,30,0,85,14,konec,2,H_MS_DEFAULT}, + {1,147,0,205,14,clk_saveload,2,H_MS_DEFAULT}, + {0,207,0,265,14,clk_saveload,2,H_MS_DEFAULT}, + {-1,267,0,289,15,clk_sleep,2,H_MS_DEFAULT}, + }; + + +T_CLK_MAP *click_map=NULL; +int click_map_size=0; +T_CLK_MAP *global_click_map=NULL; +int global_click_map_size=0; + +int find_in_click_map(MS_EVENT *ms,T_CLK_MAP *pt,int pocet,int *evtype) + { + int mscur=-1; + while (pocet--) + { + if (ms->x>=pt->xlu && ms->x<=pt->xrb && ms->y>=pt->ylu && ms->y<=pt->yrb) + { + if (mscur==-1) mscur=pt->cursor; + if ((*evtype) & pt->mask) + if (pt->proc!=NULL) + if (pt->proc(pt->id,ms->x,ms->y,ms->x-pt->xlu,ms->y-pt->ylu)) + { + evtype[0]&=~pt->mask; + if (!evtype[0]) break; + } + } + pt++; + } + return mscur; + } + + +void ms_clicker(EVENT_MSG *msg,void **usr) + { + MS_EVENT *ms; + + usr; + if (pass_zavora) return; + switch (msg->msg) + { + case E_INIT:return; + case E_DONE:return; + case E_MOUSE: + { + int mscur; + int msc=-1; + int evtype; + ms=get_mouse(msg); + mscur=-1; + evtype=ms->event_type; + mscur=find_in_click_map(ms,click_map,click_map_size,&evtype); + if (evtype) msc=find_in_click_map(ms,global_click_map,global_click_map_size,&evtype); + if (mscur==-1) mscur=msc; + if (mscur!=-1) mouse_set_cursor(mscur); + else mouse_set_cursor(default_ms_cursor); + } + break; + } + return; + } + +void change_click_map(T_CLK_MAP *map,int mapsize) + { + click_map=map; + click_map_size=mapsize; + } + +void save_click_map(void **map,int *mapsize) + { + *map=click_map; + *mapsize=click_map_size; + } + +void restore_click_map(void *map,int mapsize) + { + click_map=(T_CLK_MAP *)map; + click_map_size=mapsize; + } + + + +void change_global_click_map(T_CLK_MAP *map,int mapsize) + { + global_click_map=map; + global_click_map_size=mapsize; + } + +void set_game_click_map(void) + { + change_global_click_map(game_clk_map,GAME_CLK_MAP); + } + + +T_CLK_MAP map_disabled= + {-1,0,0,639,479,empty_clk,0xff,-1}; + +void disable_click_map(void) + { + change_click_map(&map_disabled,1); + } diff --git a/GAME/CRC.C b/GAME/CRC.C new file mode 100644 index 0000000..7cc267e --- /dev/null +++ b/GAME/CRC.C @@ -0,0 +1,31 @@ +#include +#include + +unsigned long l; + +#define ZAKLAD_CRC 0xC005 + +char data[100000]; +long delka; +FILE *f; + + +main() + { + int i; + f=fopen("CRC.C","rb"); + memset(data,0,sizeof(data)); + delka=fread(data,1,sizeof(data),f); + fclose(f); + memcpy(&l,data,2);i=0; + l%=ZAKLAD_CRC; + while(i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "engine1.h" +#include +#include "globals.h" + +typedef struct t_paragraph + { + unsigned num:15; + unsigned alt:15; + unsigned visited:1; + unsigned first:1; + long position; + }T_PARAGRAPH; + +#define STR_BUFF_SIZ 4096 +#define SAVE_POSTS 20 +#define P_STRING 1 +#define P_SHORT 2 +#define P_VAR 3 + +#define MAX_VOLEB 10 + +#define VOLBY_X 85 +#define VOLBY_Y 398 +#define VOLBY_XS 450 +#define VOLBY_YS 10 + +#define TEXT_X 17 +#define TEXT_Y 270 +#define TEXT_XS 606 +#define TEXT_YS 94 +#define TEXT_STEP 11 + +#define OPER_EQ 32 +#define OPER_BIG 35 +#define OPER_LOW 33 +#define OPER_BIGEQ 36 +#define OPER_LOWEQ 34 +#define OPER_NOEQ 37 + +#define PIC_X 17 +#define PIC_Y (17+SCREEN_OFFLINE) + +#define DESC_COLOR1 (RGB555(28,28,21)) + +static short varibles[20]; + +static char sn_nums[SAVE_POSTS]; +static char sn_nams[SAVE_POSTS][32]; +static char sn_rods[SAVE_POSTS]; + +static word *back_pic; +static char back_pic_enable=0; + +static char showed=0; +static char *pc; +static char *descript=NULL; +static char *string_buffer=NULL; +static char iff; + +static char _flag_map[32]; + +static int local_pgf=0; + +static char story_on=0; + +static char pocet_voleb=0; +static char vyb_volba=0; +static short vol_n[MAX_VOLEB]; +//static char *vol_s[MAX_VOLEB]; +static short save_jump; + +static TSTR_LIST history=NULL; +static int his_line=0; +static int end_text_line=0; +static int last_his_line=0; + +static int starting_shop=-1; + +static char halt_flag=0; + +static int dialog_mob=0; + +static char code_page=1; + +static char case_click(int id,int xa,int ya,int xr,int yr); +static char ask_who_proc(int id,int xa,int ya,int xr,int yr); + + +#define CLK_DIALOG 3 +static T_CLK_MAP clk_dialog[CLK_DIALOG]= + { + {0,TEXT_X,TEXT_Y,TEXT_X+TEXT_XS,TEXT_Y+TEXT_YS,case_click,3,H_MS_DEFAULT}, + {-1,30,0,85,14,konec,2,H_MS_DEFAULT}, + {0,0,0,639,479,empty_clk,0xff,H_MS_DEFAULT}, + }; + +#define CLK_DLG_WHO 3 +static T_CLK_MAP clk_dlg_who[CLK_DLG_WHO]= + { + {1,54,378,497,479,ask_who_proc,2,-1}, + {2,0,0,639,479,ask_who_proc,8,-1}, + {-1,0,0,639,479,empty_clk,0xff,-1}, + }; + + +static int glob_y; + +static int last_pgf; + +static word *paleta; +static long loc_anim_render_buffer; +static short task_num=-1; + +void small_anm_buff(void *target,void *buff,void *paleta); +//#pragma aux small_anm_buff parm[edi][esi][ebx] modify [eax ecx] +void small_anm_delta(void *target,void *buff,void *paleta); +//#pragma aux small_anm_delta parm[edi][esi][ebx] modify [eax ecx] + +static void animace_kouzla(int act,void *data,int csize) + { + word *p=GetScreenAdr()+loc_anim_render_buffer; + switch (act) + { + case MGIF_LZW: + case MGIF_COPY:small_anm_buff(p,data,paleta);break; + case MGIF_DELTA:small_anm_delta(p,data,paleta);break; + case MGIF_PAL:paleta=data;break; + } + } + + +static void dialog_anim(va_list args) +//#pragma aux dialog_anim parm [] + { + char *block=va_arg(args,char *); + int speed=va_arg(args,int); + int rep=va_arg(args,int); + + void *anm; + void *aptr; + char *ch; + char hid; + int spdc=0,cntr=rep,tm,tm2; + + loc_anim_render_buffer=PIC_Y*scr_linelen2+PIC_X; + mgif_install_proc(animace_kouzla); + concat(ch,pathtable[SR_DIALOGS],block); + free(block); + aptr=load_file(ch); + do + { + anm=open_mgif(aptr); + while (anm!=NULL && task_quitmsg()) + { + task_sleep(NULL); + if (!spdc) + { + if (ms_last_event.x<=PIC_X+320 && ms_last_event.y<=PIC_Y+180) + { + hid=1;schovej_mysku(); + } + else hid=0; + anm=mgif_play(anm); + spdc=speed; + if (hid) ukaz_mysku(); + showview(PIC_X,PIC_Y,320,180); + } + tm2=get_timer_value(); + if (tm!=tm2) + { + spdc--;tm=tm2; + } + } + rep--; + close_mgif(); + } + while (!cntr && rep && !task_quitmsg()); + free(aptr); + } + +static void stop_anim() + { + if (task_num!=-1) term_task(task_num); + } + +static void run_anim(char *name,int speed,int rep) + { + char *bl; + stop_anim(); + bl=getmem(strlen(name)+1);strcpy(bl,name); + task_num=add_task(8196,dialog_anim,bl,speed,rep); + } + +static void error(char *text) + { + char buff[256]; + sprintf(buff,"%s v odstavci %d\r\nLocal_pgf=%d / DIALOG : %d / SENTENCE : %d\r\n",text,last_pgf+local_pgf,local_pgf,local_pgf/128,last_pgf); + MessageBox(NULL,buff,NULL,MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL); + SEND_LOG("(DIALOGS) Dialog error detected at %d:%d",local_pgf/128,last_pgf); + SEND_LOG("(DIALOGS) Error description: %s",text,0); + } + +static void show_dialog_picture() + { + if (!showed) + { + put_picture(0,SCREEN_OFFLINE,ablock(H_DIALOG)); + showed=1; + glob_y=250; + } + } + +static T_PARAGRAPH *find_paragraph(int num) + { + int *pp; + int pocet,i; + T_PARAGRAPH *z; + + num+=local_pgf; + pp=(int *)ablock(H_DIALOGY_DAT); + pocet=*pp;pp+=2; + z=(T_PARAGRAPH *)pp; + for(i=0;inum==(unsigned)num) return z; + { + char s[80]; + + sprintf(s,"Odstavec %d neexistuje! Odkaz byl vyvoln",num); + error(s); + return (T_PARAGRAPH *)pp; + } + } + +static int find_pgnum(char *pc) + { + T_PARAGRAPH *z; + int *pp; + int lastnum=-1; + int pocet; + int pcc,i; + + pp=(int *)ablock(H_DIALOGY_DAT); + pocet=*pp;pp+=2; + pcc=pc-(char *)pp-8-sizeof(T_PARAGRAPH)*pocet; + z=(T_PARAGRAPH *)pp; + for(i=0;iposition>pcc) break;else lastnum=z->num; + return lastnum-local_pgf; + } + +static void goto_paragraph(int prgf) + { + T_PARAGRAPH *z; + + + do + { + z=find_paragraph(prgf); + if (z->visited) z->first=1; + if (z->alt==z->num || !z->visited) + { + pc=((char *)ablock(H_DIALOGY_DAT))+*((int *)ablock(H_DIALOGY_DAT))*sizeof(T_PARAGRAPH)+8+z->position; + last_pgf=prgf; + z->visited=1; + return; + } + prgf=z->alt-local_pgf; + do_events(); + } + while (1); + } + +static char *transfer_text(char *source,char *target) + { + char *orgn=source,*ot=target; + int num; + while (*source) + { + if (*source=='%') + { + source++; + switch(*source) + { + case '[':*target++='[';break; + case ']':*target++=']';break; + case 'a':*target++='\'';break; + case 'p': + case '%':*target++='%';break; + case 'n':strcpy(target,sn_nams[0]);target+=strlen(sn_nams[0]);break; + default: num=0;while (isdigit(*source)) num=10*num+*source++-'0'; + if (*source=='l') + { + sn_nums[0]=sn_nums[num]; + strcpy(sn_nams[0],sn_nams[num]); + sn_rods[0]=sn_rods[num]; + } + break; + } + source++; + } + else if (*source=='[') + { + source++; + num=sn_rods[0]; + while(num>0) + { + source=strchr(source,','); + num--; + if (source==NULL) + { + char buff[256]; + closemode(); + sprintf(buff,"%s\r\nChybny rod nebo maly pocet tvaru od jednoho slova",orgn); + error(buff); + exit(-1); + } + source++; + } + while (*source!=',' && *source!=']' && *source!=0) *target++=*source++; + if (*source!=']') + { + source=strchr(source,']'); + if (source==NULL) + { + char buff[256]; + closemode(); + sprintf(buff,"%s\r\nOcekava se ]",orgn); + error(buff); + exit(-1); + } + } + source++; + } + else *target++=*source++; + } + *target=0; + if (code_page==2) + prekodovat(ot); + return target; + } + +static char *conv_text(char *source) + { + if (string_buffer==NULL) string_buffer=getmem(STR_BUFF_SIZ); + return transfer_text(source,string_buffer); + } + +static char zjisti_typ() + { + return *pc; + } + +static char *Get_string() + { + char *c,i; + if (*pc==P_STRING) + { + pc++; + c=conv_text(pc); + do + { + pc+=strlen(pc)+1; + if ((i=zjisti_typ())==P_STRING) + { + pc++; + c=transfer_text(pc,c); + } + } + while(i==P_STRING); + return string_buffer; + } + if (zjisti_typ()==P_SHORT) + { + short i; + pc++; + i=*(short *)pc;pc+=2; + if (i<=0) c=conv_text(texty[abs(i)]);else c=conv_text(level_texts[i]); + return string_buffer; + } + error("Oekv se etzec nebo index do tabulky etzc"); + exit(0); + return NULL; + } + +static short Get_short() + { + short p; + if (*pc==P_SHORT) + { + pc++; + p=*(short *)pc; + pc+=2; + return p; + } + if (*pc==P_VAR) + { + pc++; + p=*(short *)pc; + pc+=2; + return varibles[p]; + } + error("Oekv se slo"); + exit(0); + return 0; + } + +static void show_desc() + { + char *c=descript; + int y; + + showed=0; + show_dialog_picture(); + if (c==NULL) return; + y=34; + set_font(H_FBOLD,DESC_COLOR1); + while (*c) + { + position(382,y); + outtext(c);y+=text_height(c); + c=strchr(c,0)+1; + } + } + +static void add_desc(char *c) + { + int xs,ys; + if (story_on) write_story_text(c); + if (descript!=NULL) free(descript); + descript=(char *)getmem(strlen(c)+2); + set_font(H_FBOLD,RGB555(31,31,31)); + zalamovani(c,descript,225,&xs,&ys); + } + +static void show_emote(char *c) + { + int xs,ys; + char *a; + + if (story_on) write_story_text(c); + a=alloca(strlen(c)+2); + set_font(H_FBOLD,RGB555(31,31,31)); + zalamovani(c,a,TEXT_XS,&xs,&ys); + while (*a) + { + char z[100]="M"; + strcat(z,a); + end_text_line=str_add(&history,z)+1; + a=strchr(a,0)+1; + } + } + + +static void echo(char *c) + { + int xs,ys; + char *a; + + if (story_on) write_story_text(c); + a=alloca(strlen(c)+2); + set_font(H_FBOLD,RGB555(0,30,0)); + zalamovani(c,a,TEXT_XS,&xs,&ys); + while (*a) + { + char z[100]="E"; + strcat(z,a); + end_text_line=str_add(&history,z)+1; + a=strchr(a,0)+1; + } + } + +#define TEXT_UNSELECT *((word *)ablock(H_DIALOG)+3+254) +#define TEXT_SELECT *((word *)ablock(H_DIALOG)+3+255) + +static void redraw_text() + { + int y=TEXT_Y; + int ys=TEXT_YS; + int ls_cn,i; + + + put_textured_bar(ablock(H_DIALOG),TEXT_X,TEXT_Y,TEXT_XS,TEXT_YS,TEXT_X,TEXT_Y-SCREEN_OFFLINE); + //create_frame(TEXT_X,TEXT_Y,TEXT_XS,TEXT_YS,1); + ls_cn=str_count(history); + if (ls_cn<=his_line) return; + + for (i=his_line;i=omz && chk[i]==0) + { + if (l>=0) chk[l]|=4; + l=-2;iff=0; + } + else if (l!=-2 && chk[i]==0 && postavy[i].vlastnosti[vls]>=m) + { + if (l>=0) chk[l]|=4; + l=i;iff=1; + m=postavy[i].vlastnosti[vls]; + } + else chk[i]|=4; + m=0; + for(i=0;i0;i++) if (!chk[i]) l--; + i--; + sn_nums[0]=i; + strcpy(sn_nams[0],postavy[i].jmeno); + sn_rods[0]=postavy[i].female; + } + +static void pc_xicht(int xichtid) +{ + int i; + for (i=0;ivisited; + } + +static void set_nvisited(int prgf) + { + T_PARAGRAPH *z; + + z=find_paragraph(prgf); + z->visited=0; + z->first=0; + } + + +void q_flag(int flag) + { + iff=_flag_map[flag>>3] & (1<<(flag & 0x7)); + } + +static void set_flag(int flag) + { + q_flag(flag); + _flag_map[flag>>3]|=(1<<(flag & 0x7)); + } + +static void reset_flag(int flag) + { + q_flag(flag); + _flag_map[flag>>3]&=~(1<<(flag & 0x7)); + } + +void change_flag(int flag,char mode) + { + if (mode==0) reset_flag(flag); + else if (mode==1) set_flag(flag); + else _flag_map[flag>>3]^=(1<<(flag & 0x7)); + } + +char test_flag(int flag) + { + return (_flag_map[flag>>3] & (1<<(flag & 0x7)))!=0; + } + +static void first_visited(int prgf) + { + T_PARAGRAPH *z; + + z=find_paragraph(prgf); + iff=!z->first; + } + + + +void do_dialog(); +static void remove_all_cases(); + +static void dialog_cont() + { + save_jump=vol_n[vyb_volba]; + remove_all_cases(); + echo(" "); + his_line=get_last_his_line(); + if (halt_flag) goto_paragraph(save_jump); + schovej_mysku(); + do_dialog(); + } + + +static void key_check(EVENT_MSG *msg,void **unused) + { + char c,d; + + unused; + if (msg->msg==E_KEYBOARD) + { + c=*(char *)msg->data; + d=*(int *)msg->data>>8; + if (c==0) + { + switch(d) + { + case 'H':if (vyb_volba==0) his_line-=(his_line>0);else vyb_volba--;break; + case 'P':if (his_linemsg=-1; + } + else if (c==27) konec(0,0,0,0,0); + } + } + +void wire_dialog(); +void wire_dialog_drw() + { + schovej_mysku(); + wire_dialog(); + draw_all(); + ukaz_mysku(); + showview(0,0,0,0); + } +void unwire_dialog() + { + send_message(E_DONE,E_KEYBOARD,key_check); + disable_click_map(); +// wire_proc=wire_dialog_drw; + } + +void wire_dialog() + { + cancel_render=1; + send_message(E_ADD,E_KEYBOARD,key_check); + change_click_map(clk_dialog,CLK_DIALOG); + unwire_proc=unwire_dialog; + showview(0,0,0,0); + last_his_line=his_line; + } + + +short *q_item_one(int i,int itnum) + { + int j; + THUMAN *p=&postavy[i]; + for(j=0;jinv_size;j++) + if (p->inv[j]==itnum) return &p->inv[j]; + for(j=0;jwearing[j]==itnum) return &p->wearing[j]; + for(j=0;jprsteny[j]==itnum) return &p->wearing[j]; + return NULL; + } + +short *q_item(int itnum,int sector) + { + int i; + short *p; + + itnum++; + for(i=0;iMAX_VOLEB) {error("POZOR! Je priliz mnoho voleb");pocet_voleb=MAX_VOLEB;} + a=alloca(strlen(text)+2); + set_font(H_FBOLD,RGB555(0,30,0)); + zalamovani(text,a,TEXT_XS,&xs,&ys); + while (*a) + { + char z[100]; + z[0]=pocet_voleb+48; + z[1]=0; + strcat(z,a); + str_add(&history,z); + a=strchr(a,0)+1; + } + pocet_voleb++; + } + +static void remove_all_cases() + { + int cf,i; + pocet_voleb=0; + cf=str_count(history); + for(i=end_text_line;i1) + { + id=yr/TEXT_STEP; + cf=str_count(history); + id+=his_line; + if (id>=cf) return 0; + if (history[id]==NULL) return 0; + id=history[id][0]; + if (id=='E' || id=='M') return 0; + id-=48; + if (id!=vyb_volba) + { + vyb_volba=id; + schovej_mysku(); + redraw_text(); + ukaz_mysku(); + showview(TEXT_X,TEXT_Y,TEXT_XS,TEXT_YS); + } + if (ms_last_event.event_type & 0x2) + { + dialog_cont(); + } + } + else + if (ms_last_event.event_type & 0x2) + { + dialog_cont(); + } + return 1; + } + +void dialog_select(char halt) + { + showed=0; + unwire_proc(); + draw_all(); + ukaz_mysku(); + wire_dialog(); + halt_flag=halt && (pocet_voleb>0); + } + +void dialog_select_jump() + { + goto_paragraph(save_jump); + } + +static void exit_dialog() + { + _flag_map[0]|=0x1; + stop_anim(); + if (dialog_mob>-1) + { + mobs[dialog_mob].dialog_flags=_flag_map[0]; + mobs[dialog_mob].stay_strategy=_flag_map[1]; + } + unwire_proc(); + aunlock(H_DIALOGY_DAT); + ukaz_mysku(); + free(descript);descript=NULL; + free(string_buffer);string_buffer=NULL; + remove_all_cases(); + release_list(history); + history=0; + free(back_pic); + undef_handle(H_DIALOG_PIC); + if (starting_shop!=-1 && !battle) + { + enter_shop(starting_shop); + ukaz_mysku(); + update_mysky(); + cancel_pass=0; + } + else + { + wire_proc(); + norefresh=0; + } + starting_shop=-1; + SEND_LOG("(DIALOGS) Exiting dialog...",0,0); + } + + +static void picture(char *c) + { + undef_handle(H_DIALOG_PIC); + if (strcmp(c,"SCREEN")) def_handle(H_DIALOG_PIC,c,hi_8bit_correct,SR_DIALOGS),back_pic_enable=0; + else back_pic_enable=1; + } + + + +static void dlg_start_battle() + { + if (dialog_mob!=-1) + { + mobs[dialog_mob].vlajky|=MOB_IN_BATTLE; + } + battle=1; + } + +static void teleport_group(short sector,short dir) + { + int i; + THUMAN *h=postavy; + + destroy_player_map(); + for(h=postavy,i=0;iused && h->groupnum==cur_group) + { + recheck_button(h->sektor,1); + recheck_button(sector,1); + h->sektor=sector; + h->direction=dir; + } + viewsector=sector; + viewdir=dir; + build_player_map(); + } + +extern THUMAN postavy_2[]; + +char join_character(int i) + { + THUMAN *h; + THUMAN *s=postavy_2+i; + int j; + + SEND_LOG("(DIALOGS) Joining character '%s'",s->jmeno,0); + for(j=0,h=postavy;jused) + { + memcpy(h,s,sizeof(THUMAN)); + h->sektor=viewsector; + h->direction=viewdir; + h->groupnum=cur_group; + reg_grafiku_postav(); + bott_draw(1); + return 0; + } + SEND_LOG("(DIALOGS) Join failed - no room for new character",0,0); + return 1; + } + + +static int selected_player; + +char drop_character() +{ + int selected_player=sn_nums[0]; + if (selected_player<0 || selected_player>=POCET_POSTAV) return 1; + memcpy(postavy+selected_player,postavy+selected_player+1,sizeof(*postavy)*(POCET_POSTAV-selected_player)); + postavy[POCET_POSTAV-1].used=0; + reg_grafiku_postav(); + bott_draw(1); + return 0; +} + + +static char dead_players=0; + +static char ask_who_proc(int id,int xa,int ya,int xr,int yr) + { + { + THUMAN *p; + int i; + word *xs; + + if (id==2) + { + selected_player=-1; + exit_wait=1; + return 1; + } + xs=ablock(H_OKNO); + i=xr/xs[0];yr;xa;ya;id; + if (iused && ((p->lives!=0) ^ (dead_players))) + if (p->sektor==viewsector) + { + selected_player=i; + exit_wait=1; + } + } + return 1; + } + + } + + +static dlg_ask_who() + { + draw_all(); + mouse_set_default(H_MS_WHO); + ukaz_mysku(); + showview(0,0,0,0); + *otevri_zavoru=1; + change_click_map(clk_dlg_who,CLK_DLG_WHO); + escape(); + dead_players=0; + schovej_mysku(); + mouse_set_default(H_MS_DEFAULT); + if (selected_player==-1) return 1; + strcpy(sn_nams[0],postavy[selected_player].jmeno); + sn_rods[0]=postavy[selected_player].female; + sn_nums[0]=selected_player; + change_click_map(NULL,0); + return 0; + } + +extern word weapon_skill[]; + +static void pract(h,vls,how,max) + { + iff=0; + if (vls>=100) + { + vls-=100; + if (postavy[h].bonus_zbrani[vls]>=max) iff=1; + else + { + postavy[h].bonus_zbrani[vls]+=how; + if (postavy[h].bonus_zbrani[vls]>max) postavy[h].bonus_zbrani[vls]=max,iff=1; + postavy[h].weapon_expy[vls]=weapon_skill[postavy[h].bonus_zbrani[vls]]; + } + } + else + { + if (postavy[h].vlastnosti[vls]>=max) iff=1; + else + { + postavy[h].stare_vls[vls]+=how; + prepocitat_postavu(postavy+h); + if (postavy[h].vlastnosti[vls]>max) + { + postavy[h].stare_vls[vls]-=postavy[h].vlastnosti[vls]-max; + postavy[h].vlastnosti[vls]=max; + iff=1; + } + } + } + } + +static void pract_to(h,vls,how) + { + iff=0; + if (vls>=100) + { + vls-=100; + if (postavy[h].bonus_zbrani[vls]val2; + case OPER_LOW:return val1=val2; + case OPER_LOWEQ:return val1<=val2; + case OPER_NOEQ:return val1!=val2; + default:error("Chybn operator porovnvn"); + } + return 0; + } + +static char test_vls(h,vls,oper,num) + { + int val; + if (vls>=100) + { + vls-=100; + val=postavy[h].bonus_zbrani[vls]; + } + else + val=postavy[h].stare_vls[vls]; + return oper_balance(val,num,oper); + } + +static char atsector(int oper,int sector) + { + return oper_balance(viewsector,sector,oper); + } + + +static void dark_screen(int time,int gtime) + { + int z,i; + THUMAN *h; + i=get_timer_value()+time*50; + curcolor=0; + bar(0,17,639,377); + showview(0,0,0,0); + while (get_timer_value()used && h->lives) + { + z=h->vlastnosti[VLS_HPREG]*gtime;z+=h->lives; + if (z>h->vlastnosti[VLS_MAXHIT]) z=h->vlastnosti[VLS_MAXHIT];h->lives=z; + z=h->vlastnosti[VLS_MPREG]*gtime;z+=h->mana; + if (z>h->vlastnosti[VLS_MAXMANA]) z=h->vlastnosti[VLS_MAXMANA];h->mana=z; + z=h->vlastnosti[VLS_VPREG]*gtime;z+=h->kondice; + if (z>h->vlastnosti[VLS_KONDIC]) z=h->vlastnosti[VLS_KONDIC];h->kondice=z; + } + bott_draw(0); + } + +static char najist_postavy(int cena) + { + int i,s=0; + THUMAN *h=postavy; + + for(i=0;iused && h->sektor==viewsector && h->lives) s=s+cena; + if (s>money) return 1; + money-=s; + for(i=0,h=postavy;iused && h->sektor==viewsector && h->lives) + { + h->jidlo=MAX_HLAD(h); + h->voda=MAX_ZIZEN(h); + } + return 0; + } + +static char isall() + { + THUMAN *h=postavy; + int i; + + for(i=0,h=postavy;isektor!=viewsector && h->used && h->lives) return 0; + return 1; + } + +static void spat(int hodin) + { + sleep_ticks=hodin*HODINA;add_task(16384,sleep_players); + insleep=1; + while (insleep) do_events(); + } + +static char test_volby_select(int balance,int value) + { + return oper_balance(pocet_voleb,value,balance); + } + +static void cast_spell(int spell) + { + int cil=1+sn_nums[0]; + + add_spell(spell,cil,cil,1); + } + + +void do_dialog() + { + int i,p1,p2,p3; + char *c; + + do + { + i=Get_short();p3=0; + switch(i) + { + case 128:add_desc(Get_string());break; + case 129:show_emote(Get_string());break; + case 130:save_name(Get_short());break; + case 131:iff=!iff; + case 132:load_name(Get_short());break; + case 133:nahodne(0,0,Get_short());break; + case 134:p1=Get_short();p2=Get_short();nahodne(VLS_SMAGIE,p1,p2);break; + case 135:p1=Get_short();p2=Get_short();nahodne(VLS_SILA,p1,p2);break; + case 136:p1=Get_short();p2=Get_short();nahodne(VLS_OBRAT,p1,p2);break; + case 137:c=Get_string();p1=Get_short();strncpy(sn_nams[0],c,32);sn_rods[0]=p1;break; + case 138:iff=Get_short();break; + case 139:goto_paragraph(Get_short());break; + case 140:p1=Get_short();if (iff) goto_paragraph(p1);break; + case 141:p1=Get_short();if (!iff) goto_paragraph(p1);break; + case 142:p1=Get_short();add_case(p1,Get_string());break; + case 143:p1=Get_short();p2=Get_short();c=Get_string();if (iff==p1) add_case(p2,c);break; + case 144:dialog_select(1);return; + case 145:iff=visited(Get_short());break; + case 146:p1=Get_short();c=Get_string();iff=visited(p1);if (iff==0) add_case(p1,c);break; + case 147:picture(Get_string());break; + case 148:echo(Get_string());break; + case 149:cur_page=count_pages(); + cur_page&=~0x1; + cur_page++; + add_to_book(Get_short()); + play_fx_at(FX_BOOK); + if (game_extras & EX_AUTOOPENBOOK) autoopenaction=1; + break; + case 150:set_nvisited(Get_short());break; + case 151:iff=rnd(100)<=Get_short();break; + case 152:iff=q_item(Get_short(),viewsector)!=NULL;break; + case 153:create_item(Get_short());break; + case 154:destroy_item(Get_short());break; + case 155:money+=Get_short();break; + case 156:p1=Get_short();if (p1>money) iff=1;else money-=p1;break; + case 157:dlg_start_battle();break; + case 158:p1=Get_short();p2=Get_short();delay_action(0,p1,p2,0,0,0);break; + case 160:p1=Get_short();p2=Get_short();teleport_group(p1,p2);break; + case 161:c=Get_string();p1=Get_short();p2=Get_short();run_anim(c,p1,p2);break; + case 162:lecho(Get_string());break; + case 163:q_flag(Get_short());break; + case 164:dialog_select(0);return; + case 165:dialog_select_jump();break; + case 166:first_visited(Get_short());break; + case 167:local_pgf=Get_short();break; + case 168:starting_shop=Get_short();break; + case 169:p1=Get_short();if (!iff) pc+=p1;break; + case 170:p1=Get_short();if (iff) pc+=p1;break; + case 171:p1=Get_short();pc+=p1;break; + case 172:code_page=Get_short();break; + case 173:break; //ALT_SENTENCE + case 174:iff=join_character(Get_short());break; + case 189:dead_players=1; + case 175:echo(Get_string()); p1=Get_short(); + if (dlg_ask_who()) if (p1) goto_paragraph(p1); + else iff=1; + else iff=0; + break; + case 176:p1=Get_short();p2=Get_short();pract_to(sn_nums[0],p1,p2);break; + case 177:p1=Get_short();p2=Get_short();p3=Get_short();iff=test_vls(sn_nums[0],p1,p2,p3);break; + case 178:p1=Get_short();runes[p1/10]|=1<<(p1%10);break; + case 179:p1=Get_short();iff=((runes[p1/10] & (1<<(p1%10)))!=0);break; + case 180:p1=Get_short();iff=(money>=p1);break; + case 181:p1=Get_short();p2=Get_short();p3=Get_short();pract(sn_nums[0],p1,p2,p3);break; + case 182:p1=Get_short();p2=Get_short();dark_screen(p1,p2);break; + case 183:spat(Get_short());break; + case 184:p1=Get_short();iff=najist_postavy(p1);break; + case 185:iff=isall();break; + case 186:enable_glmap=Get_short();break; + case 187:p1=Get_short();p2=Get_short();iff=atsector(p1,p2);break; + case 188:p1=Get_short();cast_spell(p1);break; + case 190:spell_sound(Get_string());break; + case 191:p1=Get_short();p2=Get_short();iff=test_volby_select(p1,p2);break; + case 192:p1=Get_short();p2=Get_short();varibles[p1]=p2;break; + case 193:p1=Get_short();p2=Get_short();varibles[p1]+=p2;break; + case 194:p1=Get_short();p2=Get_short();p3=Get_short();iff=oper_balance(varibles[p1],p3,p2);break; + case 195:p2=find_pgnum(pc);p1=Get_short();varibles[p1]=p2;break; + case 196:p1=Get_short();varibles[p1]=iff;break; + case 197:p1=Get_short();add_case(varibles[p1],Get_string());break; + case 198:p1=Get_short();p2=Get_short();c=Get_string();if (iff==p1) add_case(varibles[p2],c);break; + case 199:goto_paragraph(varibles[Get_short()]);break; + case 200:iff=drop_character();break; + case 201:pc_xicht(Get_short());break; + case 518:set_flag(Get_short());break; + case 519:reset_flag(Get_short());break; + case 255:exit_dialog();return; + default: + { + char s[80]; + sprintf(s,"Neznm instrukce: %d",i); + error(s); + } + break; + } + } + while(1); + } + +static void create_back_pic() + { + int skpx=4,skpy=5,xp,yp; + word *p,*s=GetScreenAdr()+SCREEN_OFFSET,*s2; + + schovej_mysku(); + p=back_pic=NewArr(word,3+340*200); + *p++=340; + *p++=200; + *p++=A_16BIT; + for(yp=0;yp<200;yp++) + { + s2=s; + for(xp=0;xp<340;xp++) + { + *p++=*s2++; + if (!skpx) skpx=8;else s2++,skpx--; + } + s+=scr_linelen2; + if (!skpy) skpy=4;else s+=scr_linelen2,skpy--; + } + ukaz_mysku(); + } + +void call_dialog(int entr,int mob) + { + int i; + void (*old_wire_proc)()=wire_proc; + curcolor=0; + create_back_pic(); + bar(0,SCREEN_OFFLINE,639,SCREEN_OFFLINE+359); + SEND_LOG("(DIALOGS) Starting dialog...",0,0); + for(i=0;i-1) + { + _flag_map[0]=mobs[mob].dialog_flags; + _flag_map[1]=mobs[mob].stay_strategy; + } + local_pgf=0; + poloz_vsechny_predmety(); + cancel_render=1; + norefresh=1; + history=create_list(256); + his_line=0; + memset(sn_nums,0xff,sizeof(sn_nums)); + goto_paragraph(entr); + schovej_mysku(); + alock(H_DIALOGY_DAT); + aswap(H_DIALOGY_DAT); + selected_player=-1; + do_dialog(); + } + +char save_dialog_info(FILE *f) + { + int pgf_pocet; + int *p,i; + size_t siz; + char *c,res=0; + T_PARAGRAPH *q; + + SEND_LOG("(DIALOGS)(SAVELOAD) Saving dialogs info...",0,0); + p=ablock(H_DIALOGY_DAT); + pgf_pocet=*p; + fwrite(&pgf_pocet,1,4,f); + siz=(pgf_pocet+3)/4; + if (siz) + { + c=getmem(siz); + memset(c,0,siz); + p=ablock(H_DIALOGY_DAT); + q=(T_PARAGRAPH *)(p+2); + for(i=0;i>2]|=(q[i].visited<>2]>>j); + q[i].first=(c[i>>2]>>(j+1)); + } + free(c); + } + res|=(fread(_flag_map,1,sizeof(_flag_map),f)!=sizeof(_flag_map)); + SEND_LOG("(DIALOGS)(SAVELOAD) Done...",0,0); + return res; + } diff --git a/GAME/DLGLIB.C b/GAME/DLGLIB.C new file mode 100644 index 0000000..9630019 --- /dev/null +++ b/GAME/DLGLIB.C @@ -0,0 +1,271 @@ +/* + + definice formatu- + + :num - odstavec + #text + + # asterix = muze obsahovat tyto znaky + . = normal text (vypisuje se) + _ = popis (zapisuje se do LOGu) + " = dialog (vypisuje se do LOGu a tiskne se) + ? = vyber.. Nasleduje . nebo _ nebo ' + * = prikaz + ; = komentar + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +FILE *dlg; +long *odstavce=NULL; +int pocet; + +int selptr=0; + +char get_article() + { + int c; + + while ((c=fgetc(dlg))==32); + return (char)c; + } + +#define new_line() while (fgetc(dlg)!='\n'); + + +int count_pargh() + { + char c; + int i=0; + + fseek(dlg,0,SEEK_SET); + c=get_article(); + while (c!=0xff) + { + if (c==':') i++; + if (c!='\n') new_line(); + c=get_article(); + } + return i; + } + +void read_pargh() + { + int s,i; + long *d; + char c; + if (odstavce!=NULL) free(odstavce); + odstavce=NULL; + s=(pocet=i=count_pargh())*sizeof(long)*2; + if (s==0) return; + odstavce=getmem(s); + d=odstavce; + fseek(dlg,0,SEEK_SET); + c=get_article(); + while (c!=0xff && i) + { + if (c==':') + { + fscanf(dlg,"%d",&s); + *d++=s; + *d++=ftell(dlg); + i--; + } + if (c!='\n') new_line(); + c=get_article(); + } + } + +void dlg_error(char *chyba) + { + closemode(); + printf("Error in dialoge: %s\n",chyba); + exit(1); + } + +long *najdi_odstavec(int odstavec) + { + long *d; + int i; + + + d=odstavce; + for(i=0;i>24; + fseek(dlg,m,SEEK_SET); + return c; + } + +void set_flags(int n,long maskand,long maskor) + { + long *l; + l=najdi_odstavec(n); + l[1]&=(maskand<<24)+0xffffff; + l[1]|=maskor<<24; + } + +int param(char *c) + { + int i; + sscanf(c,"%d",&i); + return i; + } + +int nparam(int n,char *c) + { + char *d; + + if (n) + { + d=c; + while (n--) d=(char *)strchr(d+1,','); + } + else d=c-1; + if (d==NULL) return -1;else return param(d+1); + } + +void proved_goto(int num) + { + char c; + long l; + l=ftell(dlg); + c=jdi_na_odstavec(num); + while (c & 1) + { + int i,j; + + j=fscanf(dlg,"%d",&i); + if (j) c=jdi_na_odstavec(i); else + { + c=0; + fseek(dlg,l,SEEK_SET); + } + } + } +void proved_d(char *code,char *text) + { + static int mode=0; + static char *save_text; + + do + { + if (mode==0) + { + *code=get_article(); + switch (*code) + { + case ';': + case ':':*code=0xff;new_line();break; + case '.':*code=1;break; + case '_':*code=2;break; + case '"':*code=3;break; + case '?':*code=4;selptr++;break; + case '*':*code=0;break; + default :*code=0xff;break; + } + if (*code!=0xff)fscanf(dlg,"%[^\n]",text); + if (*code==0) + { + strupr(text); + if (!strncmp(text,"GOTO",4)) + { + int n; + sscanf(text+4,"%d",&n); + proved_goto(n); + } + if (!strncmp(text,"JUMP",4)) + { + int n; + sscanf(text+4,"%d",&n); + jdi_na_odstavec(n); + } + else if (!strncmp(text,"DISABLE",7)) set_flags(param(text+7),0xff,1); + else if (!strncmp(text,"ENABLE",6)) set_flags(param(text+7),0xfe,0); + else if (!strncmp(text,"CHOICE",6)) + { + *text=selptr; + selptr=0; + *code=5; + mode=1; + save_text=getmem(strlen(text)-6+1); + strcpy(save_text,text+6); + } + else if (!strncmp(text,"STOP",4)) *code=7; + else if (!strncmp(text,"MENU",4)) selptr=param(text+4); + } + else if (*code==4) + { + long *l=najdi_odstavec(param(text)); + char c,*d; + + c=l[1]>>24; + if (c & 1) *code=6; + d=text;while (*d>='0' && *d<='9') d++; + strcpy(text,d); + } + } + else if (mode==1) + { + int i=text[1],j; + + *code=5; + j=nparam(i,save_text); + if (j==-1) return; + free(save_text); + proved_goto(j); + set_flags(j,0xff,0x1); + mode=0; + *code=0; + } + } + while (*code==0); + } + +main() + { + char code,text[300]; + dlg=fopen("test.txt","r"); + read_pargh(); + proved_goto(1); + proved_d(&code,text); + while (code!=7) + { + switch (code) + { + case 1:printf("%s\n",text);break; + case 2: + case 3:printf("%s\n",text);break; + case 4:printf(" %c.%s\n",selptr+64,text);break; + case 5:text[1]=toupper(getche())-65;putchar('\n');break; + } + proved_d(&code,text); + } + } + + diff --git a/GAME/DUMP.C b/GAME/DUMP.C new file mode 100644 index 0000000..d9837d4 --- /dev/null +++ b/GAME/DUMP.C @@ -0,0 +1,81 @@ +#include +#include +#include +#include +#include +#include + +static int latest_version(char *wild,int numpos) + { + WIN32_FIND_DATA ff; + HANDLE rc; + int i=0,j=-1; + char *p; + + rc=FindFirstFile(wild,&ff); + if (rc!=INVALID_HANDLE_VALUE) + do + { + p=ff.cFileName+numpos; + sscanf(p,"%d",&i); + if (i>j) j=i; + } + while (FindNextFile(rc,&ff)); + FindClose(rc); + return j; + } + +void save_dump() + { + static dump_counter=-1; + FILE *f; + int i,r,g,b,x,y; + word *a; + char c[20]; + + if (dump_counter==-1) + { + dump_counter=latest_version("DUMP*.BMP",4); + SEND_LOG("(DUMP) Dump counter sets to %d",dump_counter,0); + } + sprintf(c,"DUMP%04d.BMP",++dump_counter); + SEND_LOG("(DUMP) Saving screen shot named '%s'",c,0); + f=fopen(c,"wb"); + fputc('B',f);fputc('M',f); + i=DxGetResX()*DxGetResY()*3+0x36; + fwrite(&i,1,4,f);i=0; + fwrite(&i,1,4,f); + i=0x36; + fwrite(&i,1,4,f); + i=0x28; + fwrite(&i,1,4,f); + i=DxGetResX(); + fwrite(&i,1,4,f); + i=DxGetResY(); + fwrite(&i,1,4,f); + i=1; + fwrite(&i,1,2,f); + i=24; + fwrite(&i,1,2,f); + i=0; + fwrite(&i,1,4,f); + i=DxGetResX()*DxGetResY()*3; + fwrite(&i,1,4,f); + for(i=4,r=0;i>0;i--) fwrite(&r,1,4,f); + for(y=DxGetResY();y>0;y--) + { + word *scr=GetScreenAdr(); + a=scr+(y-1)*scr_linelen2; + for(x=0;x>3; + r=i>>8; + i=((r*256)+g)*256+b; + fwrite(&i,1,3,f); + } + } + fclose(f); + } + diff --git a/GAME/ENCRYPT.C b/GAME/ENCRYPT.C new file mode 100644 index 0000000..dbc040a --- /dev/null +++ b/GAME/ENCRYPT.C @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include + +FILE *source,*target; + +void encrypt_file(FILE *sr,FILE *tg) + { + int i,j,last=0; + + i=getc(sr); + while (i!=EOF) + { + j=i-last; + last=i; + putc(j,tg); + i=getc(sr); + } + } + +void open_files(char *src,char *tgr) + { + if (tgr==NULL) + { + char *c,*d; + tgr=alloca(strlen(src)+5); + strcpy(tgr,src); + c=strrchr(tgr,'\\'); + d=strrchr(tgr,'.'); + if (c>d) d=strchr(tgr,0); + strcpy(d,".ENC"); + } + source=fopen(src,"rb"); + target=fopen(tgr,"wb"); + } + +void close_files() + { + fclose(source); + fclose(target); + } + + +char main(int argc,char **argv) + { + if (argc<2) + { + puts("Pouziti: ENCRYPT zdroj.ext [cil.ext] \n" + "\n" + "Pokud nezadas cil, doplni se zdroj s koncovkou .enc\n" + "Nikdy nezadavej pouze cestu jako cil. Vzdycky uved jmeno!"); + return 0; + } + if (argc==2) open_files(argv[1],NULL); + else open_files(argv[1],argv[2]); + if (source==NULL) + {puts("Nemuzu najit zdrojovy soubor\n");return 1;}; + if (target==NULL) + {puts("Nemuzu otevrit cil pro zapis\n");return 1;}; + encrypt_file(source,target); + close_files(); + puts("Ok."); + return 0; + } diff --git a/GAME/ENEMY.C b/GAME/ENEMY.C new file mode 100644 index 0000000..fa617e3 --- /dev/null +++ b/GAME/ENEMY.C @@ -0,0 +1,2140 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "engine1.h" +#include "globals.h" +#include "specproc.h" + +#define MOB_ZNAKY "FLBLCH" +#define MOB_START 1 + + +#define MOB_DIST 24 +#define MBS_WALK 0 +#define MBS_ATTACK 1 +#define MBS_HIT 2 + + +#define MBA_ATTACK 3 //potvora utoci +#define MBA_SPELL 1 //potvora caruje +#define MBA_FLEE 2 //potvora utika +#define MBA_NONE 0 + +#define PK_QUERY 0 //dotaz zda je v mrtvole predmet +#define PK_PICK 1 //prvni predmet v mrtvole + +#define mob_walk_sound(p) if (p->locx!=p->headx || p->locy!=p->heady) mob_sound_event(p,MBS_WALK) + +TMOB mobs[MAX_MOBS]; +char *mob_map; +char hex_chars[]="0123456789ABCDEF"; +int mob_dostal=0; +int mob_dostal_pocet; + +char folow_mode=0; +char folow_mob; + +char mob_go_x[]={128,255,128,0}; +char mob_go_y[]={0,128,255,128}; +char mob_batt_x[]={128,128+MOB_DIST,128,128-MOB_DIST}; +char mob_batt_y[]={128-MOB_DIST,128,128+MOB_DIST,128}; +short konv_x[]={1,1,-1,-1}; +short konv_y[]={-1,1,1,-1}; +char going[]={0,0,1,0,1,1}; + +static word *mob_paths[MAX_MOBS]; +static word *mob_path_ptr[MAX_MOBS]; +static int monster_block; + +void *sound_template=NULL; + +short att_sect; +char battle=0; +char neco_v_pohybu=1; +char nohassle=0; + +typedef struct tmobsavedata +{ + short anim_counter; //citac animaci + char anim_phase; //cinnost kterou mob dela + char dir; +}TMOBSAVEDATA; + +static TMOBSAVEDATA **mobsavedata=0; + +static void register_mob_path(int mob,word *path) //registruje cestu pro potvoru + { + mob_paths[mob]=path; + mob_path_ptr[mob]=path; + } + +static void free_path(int mob) //vymaze cestu potvore + { + free(mob_paths[mob]); + mob_paths[mob]=NULL; + mob_path_ptr[mob]=NULL; + } + +void send_mob_to(int m,word *path) + { + if (mob_paths[m]!=NULL) + { + free_path(m); + } + register_mob_path(m,path); + mobs[m].stay_strategy |= MOB_WALK; + } + +void smeruj_moba(TMOB *m,int smer) + { + int val=128+MOB_DIST*smer; + + switch (m->dir) + { + case 0:m->headx=val;break; + case 1:m->heady=val;break; + case 2:m->headx=-val;break; + case 3:m->heady=-val;break; + } + } + +void save_enemy_paths(FILE *f) + { + int i,s; + word *w; + + for(i=0;ihome_pos].flags & MC_PLAYER || + mob_map[m->home_pos]) return; + m->vlajky|=MOB_LIVE; + m->vlajky&=~MOB_IN_BATTLE; + m->lives=m->vlastnosti[VLS_MAXHIT]; + m->sector=m->home_pos; + m->locx=m->headx=m->locy=m->heady=128; + memset(m->inv,0,sizeof(m->inv)); + play_sample_at_sector(H_SND_TELEPOUT,viewsector,m->home_pos,0,0); + add_spectxtr(m->home_pos,H_TELEP_PCX,14,1,0); + refresh_mob_map(); + debug_text="New monster arrived to the dungeon !"; + SEND_LOG("(RELOAD) Mob reloaded: '%s' at sector %d",m->name,m->home_pos); + free_path(m-mobs); + } + } + } + + +void init_mobs() + { + memset(mobs,0,sizeof(mobs)); + mob_map=getmem(mapsize); + memset(mob_map,0,mapsize); + memset(mob_paths,0,sizeof(mob_paths)); + memset(mob_path_ptr,0,sizeof(mob_path_ptr)); + send_message(E_DONE,E_KOUZLO_KOLO,mob_reload); + send_message(E_ADD,E_KOUZLO_KOLO,mob_reload); + } + +static void register_mob_graphics(int num,char *name_part,char *anims,char *seq) + { + char fulname[14]; + char znaky[]=MOB_ZNAKY; + int i,j,a; + + strcpy(fulname,name_part); + strcat(fulname,"??.PCX"); + a=num; + for(i=0;i<6;i++) + { + for(j=0;j<16;j++) + { + if (anims[i]) + { + fulname[6]=znaky[i]; + if (j<=anims[i]) + { + fulname[7]=*seq++; + def_handle(a,fulname,pcx_8bit_nopal,SR_ENEMIES); + } + a++; + } + else + { + fulname[6]=znaky[0]; + if (j<=anims[0]) + { + fulname[7]=*seq++; + def_handle(a,fulname,pcx_8bit_nopal,SR_ENEMIES); + } + a++; + } + if (*seq=='\r') + { + char buff[256]; + closemode(); + sprintf(buff,"Soubor sekvence %s obsahuje chybne udaje nebo je sekvence je moc kratka\n"); + MessageBox(NULL,buff,NULL,MB_OK|MB_ICONSTOP); + exit(0); + } + } + seq=strchr(seq,'\n')+1; + } + } + + + + +static void register_mob_sounds(int hlptr,word *sounds) + { + int i,z; + + for(i=0;i<4;i++) + { + z=sounds[i]; + if (z) + { + def_handle(hlptr,sound_table[z-1],wav_load,SR_ZVUKY); + } + hlptr++; + } + } + +static char miri_middle(TMOB *p) //procedura zjisti zda li potvora miri do dveri + { + int ss; + + ss=(p->sector<<2)+p->dir; + return (map_sides[ss].lclip!=0); + } + + +static char pick_item_corpse(TMOB *m,char query) + { + short *p=NULL; + int sector=m->sector; //sektor kde se bude mrtvola prohledavat + if (map_coord[sector].flags & MC_DEAD_PLR) //lezi tam vubec nejaka mrtvola? + { + int i; + THUMAN *h; //najdi mezi hraci mrtvolu ktera tam lezi + for(i=0,h=postavy;ilives && h->used && h->sektor==sector) + { + int i; //podivej se ji do inventare.... + for(i=0;iprsteny[i]) p=&h->prsteny[i]; + //nejprve ber prsteny + for(i=0;iwearing[i]) p=&h->wearing[i]; + //pak seber zbrane a brneni + for(i=0;iinv_size && p==NULL;i++) if (h->inv[i]) p=&h->inv[i]; + //teprve potom se podivej co ma v inv. + } + } + if (p!=NULL) //nasel jsi neco? + if (query==PK_QUERY) return 1; //pokud se jednalo o dotaz, tak pouze vrat 1 + else + { + int i; + for(i=0;iinv[i]==0) break; //zjisti jestli mas misto + if (i==MOBS_INV) return 0; //nemas, mas smulu.... + m->inv[i]=*p; //prenes predmet od postavy do sveho inventare. + *p=0; //ale na puvodnim miste tento predmet znic. + } + else return 0; + return 1; + } + +static char seber_predmet(TMOB *m) + { + short *p=NULL,*q; + int i,j,c,z; + + for(j=0,c=0;jinv[j]==0)); + i=0; + do + { + for(;i<4 && p==NULL;i+=(p==NULL)) pop_item(m->sector,i,0,&p); + if (i==4) return 1; + z=count_items_total(p); + if (z>c) + { + push_item(m->sector,i,p); + free(p); + p=NULL; + } + i++; + } + while (z>c); + if (z<=c) for(q=p,j=0;jinv[j]==0) m->inv[j]=(abs(*q++)); + free(p); + return 0; + } + +static void mob_sound_event(TMOB *m,int event) + { + if (m->sounds[event] && m->vlajky & MOB_LIVE && ~m->vlastnosti[VLS_KOUZLA] & SPL_STONED) + if (event==MBS_WALK) + play_sample_at_sector(m->cislo_vzoru+16*6+event+monster_block,viewsector,m->sector,m-mobs+256,(m->vlajky & MOB_SAMPLE_LOOP)!=0); + else + play_sample_at_sector(m->cislo_vzoru+16*6+event+monster_block,viewsector,m->sector,0,0); + } + +void load_enemies(short *data,int size,int *grptr,TMOB *template,long tsize) + { + int i; + short cisla[256]; + + monster_block=*grptr; + memset(cisla,0xff,sizeof(cisla)); + size>>=2; + for(i=0;iMAX_MOBS-MOB_START) size=MAX_MOBS-MOB_START; + for(i=0;i=0)mobs[i].palette=rnd(mobs[i].palette);else mobs[i].palette=abs(mobs[i].palette); + mobs[i].sector=data[0]; + mobs[i].dir=(data[1]>>14)&0x3; + mobs[i].home_pos=data[0]; + mobs[i].vlajky|=MOB_LIVE; + if (mobs[i].speed<1) + { + char buff[256]; + closemode(); + sprintf(buff,"Nestvura cislo #%d (%s) je spatne definovana (rychlost)",i,mobs[i].name); + MessageBox(NULL,buff,NULL,MB_OK|MB_ICONEXCLAMATION); + exit(1); + } + cisla[i]=mobs[i].cislo_vzoru; + for(j=0;j0 && cnt<5;cnt++,dir=(dir+1)&3) + if (!(i=mob_check_next_sector(sector,dir,alone,mobile))) + { + r--; + if (!r) break; + } + if (cnt==5) dir=-1; + return dir; + } + +char je_mozne_videt(int sector1,int sector2,int flag) + { + int x1,y1; + int x2,y2; + int xs,ys; + int x,y,ly,s; + + if (map_coord[sector1].layer!=map_coord[sector2].layer) return 0; + x1=map_coord[sector1].x;x2=map_coord[sector2].x; + y1=map_coord[sector1].y;y2=map_coord[sector2].y; + xs=x1-x2; + ys=y1-y2; + if (xs==0 && ys==0) return 1; + s=sector1; + ly=0; + if (xs>=0) + { + for(x=0;x<=xs;x++) + { + y=(x+1)*ys/(xs+1); + while (y>ly) + if ((map_sides[(s<<2)].flags & flag)!=(unsigned)flag) + { + s=map_sectors[s].step_next[0]; + ly++; + } + else return 0; + while (y=xs;x--) + { + y=(x-1)*ys/(xs-1); + while (y>ly) + if ((map_sides[(s<<2)].flags & flag)!=(unsigned)flag) + { + s=map_sectors[s].step_next[0]; + ly++; + } + else return 0; + while (yvlastnosti[VLS_KOUZLA] & SPL_BLIND) return -1; + if (p->vlastnosti[VLS_KOUZLA] & SPL_FEAR) return -1; + if (p->flee_num==100 && !insleep) return -1; + for(i=0;idohled && (!(ps->vlastnosti[VLS_KOUZLA] & SPL_INVIS)||p->vlajky & MOB_SENSE) && ps->used && ps->lives) + switch(dir) + { + case 0:ok=ys>=0;break; + case 1:ok=xs<=0;break; + case 2:ok=ys<=0;break; + case 3:ok=xs>=0;break; + } + if (ok) + if (je_mozne_videt(sector,postavy[i].sektor,SD_MONST_IMPS | SD_PLAY_IMPS)) + { + int alt; + if (ys>=abs(xs)) {nd=0;alt=xs>0?3:1;} + else if (xs>=abs(ys)) {nd=3;alt=ys>0?0:2;} + else if (ys<=(-abs(xs))) {nd=2;alt=xs>0?1:3;} + else if (xs<=(-abs(ys))) {nd=1;alt=ys>0?2:0;} + if (mob_check_next_sector(p->sector,nd,p->stay_strategy & MOB_BIG,p->vlajky & MOB_PASSABLE)==1) + { + nd=alt; + if (mob_check_next_sector(p->sector,nd,p->stay_strategy & MOB_BIG,p->vlajky & MOB_PASSABLE)==1) + { + nd=(alt+2)&3; + if (mob_check_next_sector(p->sector,nd,p->stay_strategy & MOB_BIG,p->vlajky & MOB_PASSABLE)==1) + { + nd=(alt+3)&3; + } + } + } + } + else d=255; + else d=255; + if (d!=255) + { + d*=2; + if (xs!=0 && ys!=0) d+=3;//dej prednost tem co jsou na tve souradnici. + if (dheadx!=255 && p->headx!=0 && p->headx!=128) return 128-p->headx; + if (p->heady!=255 && p->heady!=0 && p->heady!=128) return 128-p->heady; + } + if (p->headx!=255 && p->headx!=0) p->headx=128+kolik; + if (p->heady!=255 && p->heady!=0) p->heady=128+kolik; + return -kolik; + } + + +void stop_mob(TMOB *p) + { + int num1; + TMOB *q; + + p->mode=MBA_NONE; + num1=mob_map[p->sector]; + if (num1) q=&mobs[num1-MOB_START];else q=p; + if (p==q) + if (p->next) + q=mobs+p->next-MOB_START; + else + q=NULL; + if (p->stay_strategy & MOB_BIG) + { + p->headx=128; + p->heady=128; + goto end; + } + if (q!=NULL && p->dir!=q->dir) + { + p->headx=mob_batt_x[p->dir]; + p->heady=mob_batt_y[p->dir]; + q->headx=mob_batt_x[q->dir]; + q->heady=mob_batt_y[q->dir]; + mob_walk_sound(p); + mob_walk_sound(q); + return; + } + if (q!=NULL && p->dir==q->dir) + { + if (miri_middle(q)) + { + p->dir=p->dir+1 & 3; + stop_mob(q); + } + } + else + { + if (p->dir & 1) + { + p->headx=mob_batt_x[p->dir]; + if (p->heady==255 || p->heady==0) p->heady=128; + } + else + { + p->heady=mob_batt_y[p->dir]; + if (p->headx==255 || p->headx==0) p->headx=128; + } + goto end; + } + { + switch (p->dir) + { + case 0: + case 2:if (q->headx==128) + if (p->headx<128) q->headx=128+MOB_DIST;else q->headx=128-MOB_DIST; + p->headx=-q->headx; + p->heady=mob_batt_y[p->dir]; + break; + case 1: + case 3:if (q->heady==128) + if (p->heady<128) q->heady=128+MOB_DIST;else q->heady=128-MOB_DIST; + p->heady=-q->heady; + p->headx=mob_batt_x[p->dir];break; + } + } + end: + mob_walk_sound(p); + } + +void stop_all_mobs() + { + int i; + for(i=0;inext; + } + } + +char mob_test_na_bitvu(TMOB *p) + { + int x,d; + char c=0; + char pt; + + if (nohassle) return 0; + if (p->stay_strategy & MOB_WATCH) + if ((d=q_vidis_postavu(p->sector,p->dir,p,&x,0))>-1) + { + p->stay_strategy|=MOB_WALK; + if (mob_check_next_sector(p->sector,x,p->stay_strategy & MOB_BIG,p->vlajky & MOB_PASSABLE)!=1) + { + pt=(p->headx==p->locx && p->heady==p->locy); + if (p->dir!=x || pt) + { + p->dir=x; + if (!(p->stay_strategy & MOB_BIG) || pt) + { + p->headx=mob_go_x[x]; + p->heady=mob_go_y[x]; + } + else + { + p->headx=128; + p->heady=128; + } + } + if (q_zacit_souboj(p,d,att_sect)) + { + stop_mob(p); + p->vlajky|=MOB_IN_BATTLE; + if (!battle) zacni_souboj(p,d,att_sect); + } + c=1; + } + if (c) mob_sound_event(p,MBS_WALK); + return c; + } + return 0; + } + +char return_home(TMOB *p,int *smer) + { + word *path; + int i; + + i=p->dir; + if (!mob_check_next_sector(p->sector,i+1&3,p->stay_strategy & MOB_BIG,0) || !mob_check_next_sector(p->sector,i+3&3,p->stay_strategy & MOB_BIG,0)) return 1; + if (p->sector==p->home_pos) return 1; + najdi_cestu(p->sector,p->home_pos,SD_MONST_IMPS,&path,(p->stay_strategy & MOB_BIG)?1:2); + if (path==NULL) + { + return 1; + } + for(i=0;i<4 && map_sectors[p->sector].step_next[i]!=path[0];i++); + free(path); + if (i==4) return 1; + if (mob_check_next_sector(p->sector,i,p->stay_strategy & MOB_BIG,0)) return 1; + *smer=i; + return 0; + } + +static int jdi_po_ceste(int old,TMOB *p) + { + int i,s; + word *c; + + if (p->mode==MBA_FLEE && !p->actions--) //v pride uteku pocitej kroky + { + p->mode=0; + p->vlajky&=~MOB_IN_BATTLE; + return old; + } + c=mob_path_ptr[p-mobs]; //vem cestu + if (c==NULL) return old; //neni -> konec + if (*c==0) //na konci -> dealokace a konec + { + free_path(p-mobs); + p->mode=0; + p->vlajky&=~MOB_IN_BATTLE; + return old; + } + s=p->sector; + for(i=0;i<4;i++) if (map_sectors[s].step_next[i]==*c) break; + if (i==4) return old; + old=i; + c++; + mob_path_ptr[p-mobs]=c; //uloz_ukazatel + return old; + } + +void rozhodni_o_smeru(TMOB *p) + { + int sect,dir,r,v,lv,c,alone,oldwalk,passable; + int vdir=-1; + + alone=p->stay_strategy & MOB_BIG; + passable=p->vlajky & MOB_PASSABLE; + sect=p->sector; + dir=p->dir; + lv=p->walk_data; + if (mob_paths[p-mobs]!=NULL) c=jdi_po_ceste(-1,p);else c=-1; + if (c!=-1) + if (!mob_check_next_sector(sect,c,alone,passable)) + { + p->headx=mob_go_x[c]; + p->heady=mob_go_y[c]; + p->dir=c; + goto end1; + } + else + { + if (mob_path_ptr[p-mobs]-mob_paths[p-mobs]>1) mob_path_ptr[p-mobs]-=2; + } + if (p->vlajky & MOB_IN_BATTLE) + { + stop_mob(p); + goto end1; + } + if (call_mob_event(p->specproc,SMPR_WALK,p)) goto end1; + oldwalk=p->walk_data; + if (mob_test_na_bitvu(p)) return; + p->vlajky&=~MOB_IN_BATTLE; + c=map_sectors[sect].sector_type; + c-=S_SMER; + if (c>=0 && c<4 && !mob_check_next_sector(sect,c,alone,passable)) + { + if (p->headx==p->locx && p->heady==p->locy) dir=c+4;else dir=c; + } + else + { + v=mob_pocet_vychodu(sect,dir); + if (v==p->walk_data && !mob_check_next_sector(sect,dir,alone,passable)) + if (p->headx==p->locx && p->heady==p->locy) dir=p->dir+4;else dir=p->dir; + else + { + r=1; + if (v==0) v=1; + p->walk_data=v; + if (v==1 && p->stay_strategy & MOB_GUARD) r=return_home(p,&dir); + if (r) + { + if (v<2) r=1;else r=rand()*v/(RAND_MAX+1)+1; + vdir=dir=mob_vyber_vychod(r,sect,dir,alone,passable); + //if ( p->stay_strategy & MOB_WATCH && rnd(100)<20 && lv<128 && dir!=p->dir) dir=-1; + } + } + } + if (dir==-1) + { + dir=p->dir;p->dir=p->dir+2&3; + stop_mob(p); + p->walk_data=rnd(32)+223; + if (vdir!=-1)p->dir=vdir; + } + else + if (p->dir!=dir || miri_middle(p)) + { + if (p->stay_strategy & MOB_BIG && (p->locx!=p->headx || p->locy!=p->heady)) + { + stop_mob(p); + p->walk_data=oldwalk; + } + else if ((p->dir-dir &0x3)==2 && (p->headx!=p->locx || p->heady!=p->locy)) + { + stop_mob(p); + p->walk_data=0; + } + else + { + dir&=3; + p->headx=mob_go_x[dir]; + p->heady=mob_go_y[dir]; + p->dir=dir; + } + } + end1: + if (p->headx!=p->locx || p->heady!=p->locy) mob_sound_event(p,MBS_WALK); + } + +void krok_moba(TMOB *p) + { + if (!mob_check_next_sector(p->sector,p->dir,p->stay_strategy,p->vlajky)) + { + p->headx=mob_go_x[p->dir]; + p->heady=mob_go_y[p->dir]; + } + } + +static char get_view_mirror=0; + +int get_view(TMOB *p,int dirmob,int action,int curdir) + { + int view;int pos; + int xs,ys; + + get_view_mirror=0; + if (action==MOB_ATTACK) pos=4; + else if (action==MOB_TO_HIT) pos=5; + else if (action==MOB_DEATH) + { + return 1; + } + else + { + xs=p->headx-p->locx; + ys=p->heady-p->locy; + if (!(game_extras & EX_WALKDIAGONAL) || p->stay_strategy & MOB_BIG) + if (ys!=0 && xs!=0) + if (p->dir==1 || p->dir==3) xs=0;else ys=0; + if (xs) dirmob=(xs<0)?3:1; + if (ys) dirmob=(ys<0)?0:2; + pos=(2+dirmob-curdir)&0x3; + if (game_extras & EX_WALKDIAGONAL && !( p->stay_strategy & MOB_BIG)) + { + switch (curdir & 0x3) + { + case 0: if (p->locx>p->headx) pos=1;else if (p->locxheadx) pos=3;break; + case 1: if (p->locy>p->heady) pos=1;else if (p->locyheady) pos=3;break; + case 2: if (p->locx>p->headx) pos=3;else if (p->locxheadx) pos=1;break; + case 3: if (p->locy>p->heady) pos=3;else if (p->locyheady) pos=1;break; + } + } + } + if (pos==3) get_view_mirror=pos=1; + if (p->anim_counter==-1) view=pos*16; + else view=pos*16+(p->anim_counter % p->anim_counts[pos])+1; + return view; + } + +void get_pos(int x,int y,int *xpos,int *ypos,int dir) + { + switch(dir) + { + case 0:*xpos=x;*ypos=-y;break; + case 1:*xpos=y;*ypos=x;break; + case 2:*xpos=-x;*ypos=y;break; + case 3:*xpos=-y;*ypos=-x;break; + } + } + +/* +void draw_blood(int zasah,int celx,int cely,int posx,int posy) + { + draw_placed_texture(ablock(H_MZASAH1+zasah-1),celx,cely,posx+64,posy+64,75,0); + } +*/ +static void *mob_select_palette(TMOB *p) + { + char *palet; + + palet=ablock(p->cislo_vzoru+6*16+4+monster_block); + return palet+(p->palette)*PIC_FADE_PAL_SIZE; + } + +static void CheckMobStoned(int num) +{ + if (mobs[num].vlastnosti[VLS_KOUZLA] & SPL_STONED) + { + TMOB *p=mobs+num; + TMOBSAVEDATA *save; + if (!mobsavedata) + { + mobsavedata=(TMOBSAVEDATA **)getmem(sizeof(TMOBSAVEDATA *)*MAX_MOBS); + memset(mobsavedata,0,sizeof(TMOBSAVEDATA)*MAX_MOBS); + } + save=mobsavedata[num]; + if (save==NULL) + { + save=mobsavedata[num]=(TMOBSAVEDATA *)getmem(sizeof(TMOBSAVEDATA)); + save->anim_counter=p->anim_counter; + save->anim_phase=p->anim_phase; + save->dir=p->dir; + } + else + { + p->anim_counter=save->anim_counter; + p->anim_phase=save->anim_phase; + p->dir=save->dir; + p->headx=p->locx; + p->heady=p->locy; + } + } + else + { + if (mobsavedata && mobsavedata[num]) + { + free(mobsavedata[num]); + mobsavedata[num]=0; + } + } + + +} + +void draw_mob_call(int num,int curdir,int celx,int cely,char shiftup) + { + TMOB *p,*q; + int view,vw; + int view2,vw2; + DRW_ENEMY drw1,drw2; + + set_font(H_FLITT5,RGB555(31,31,0)); + CheckMobStoned(num-MOB_START); + p=&mobs[num-MOB_START]; + shiftup|=(p->stay_strategy & MOB_BIG); + + get_pos(p->locx-128,p->locy-128,&drw1.posx,&drw1.posy,curdir); + view=get_view(p,p->dir,p->anim_phase,curdir); + vw=p->cislo_vzoru+view+monster_block; + if (p->vlastnosti[VLS_KOUZLA] & SPL_INVIS) {drw1.txtr=NULL;vw=0;}else drw1.txtr=ablock(vw); + drw1.celx=celx; + drw1.cely=cely; + drw1.mirror=get_view_mirror; + drw1.adjust=p->adjusting[view]; + drw1.shiftup=shiftup; + drw1.num=p->lives; + drw1.palette=mob_select_palette(p); + drw1.stoned= (p->vlastnosti[VLS_KOUZLA] & SPL_STONED)!=0; + see_monster|=(~p->vlajky & MOB_PASSABLE); + if (p->next) + { + CheckMobStoned(p->next-MOB_START); + q=&mobs[p->next-MOB_START]; + get_pos(q->locx-128,q->locy-128,&drw2.posx,&drw2.posy,curdir); + view2=get_view(q,q->dir,q->anim_phase,curdir); + vw2=view2+q->cislo_vzoru+monster_block; + drw2.shiftup=shiftup; + drw2.celx=celx; + drw2.cely=cely; + alock(vw); + alock(vw+6*16+5); + if (q->vlastnosti[VLS_KOUZLA] & SPL_INVIS) {drw2.txtr=NULL;vw2=0;}else drw2.txtr=ablock(vw2); + drw2.mirror=get_view_mirror; + alock(vw2); + alock(vw2+6*16+5); + drw2.adjust=q->adjusting[view2]; + drw2.num=q->lives; + drw2.palette=mob_select_palette(q); + drw2.stoned=(q->vlastnosti[VLS_KOUZLA] & SPL_STONED)!=0; + see_monster|=(~q->vlajky & MOB_PASSABLE); + } + else + { + view2=-1; + draw_enemy(&drw1); + return; + } + if (drw1.posy>drw2.posy) + { + draw_enemy(&drw1); + draw_enemy(&drw2); + } + else + { + draw_enemy(&drw2); + draw_enemy(&drw1); + } + aunlock(vw); + aunlock(vw2); + aunlock(vw+6*16+5); + aunlock(vw2+6*16+5); + } + +void draw_mob(int num,int curdir,int celx,int cely,char shiftup) + { + int ss=(num<<2); + num=mob_map[num]; + if (!num) return; + set_lclip_rclip(celx,cely,map_sides[ss+((curdir+3)&3)].lclip,map_sides[ss+((curdir+1)&3)].lclip); + draw_mob_call(num,curdir,celx,cely,shiftup); + } + + +void otoc_moba(TMOB *p) + { + p->walk_data=255; + rozhodni_o_smeru(p); + } + + +static mob_check_teleport(int sect,int num) + { + int i; + if (!ISTELEPORTSECT(sect)) return sect; + play_sample_at_sector(H_SND_TELEPOUT,viewsector,sect,0,0); + add_spectxtr(sect,H_TELEP_PCX,14,1,0); + sect=map_sectors[sect].sector_tag; + play_sample_at_sector(H_SND_TELEPOUT,viewsector,sect,0,0); + add_spectxtr(sect,H_TELEP_PCX,14,1,0); + if (map_coord[sect].flags & MC_PLAYER) + { + THUMAN *h=postavy; + for(i=0;isektor==sect) player_hit(h,h->lives,0); + } + mobs[num].locx=128; + mobs[num].locy=128; + return sect; + } + +void mob_step_next(int num,int sect,int dir,char *change) + { + int c,numm,d; + TMOB *p; + + *change+=128; + numm=num+MOB_START; + if (~mobs[num].vlajky & MOB_MOBILE) + { + c=mob_map[sect]; + if (c!=numm) + mobs[c-MOB_START].next=0; + else mob_map[sect]=mobs[num].next; + mobs[num].next=0; + recheck_button(sect,1); + } + sect=map_sectors[sect].step_next[dir]; + if (~mobs[num].vlajky & MOB_MOBILE) + { + sect=mob_check_teleport(sect,num); + c=mob_map[sect]; + if (c) + { + mobs[num].next=c; + d=uhni_mobe(1,num,0); + if (d) d=uhni_mobe(1,c-MOB_START,d); + else d=uhni_mobe(1,c-MOB_START,-MOB_DIST); + } + mob_map[sect]=numm; + recheck_button(sect,1); + } + mobs[num].sector=sect; + p=&mobs[num]; + p->dir=dir; + rozhodni_o_smeru(p); + if (p->next) + uhni_mobe(0,num,d); + if (p->stay_strategy & MOB_PICKING) + { + for(c=0;c<4;c++) if (map_items[(p->sector<<2)+c]!=NULL) break; + if (c==4 && pick_item_corpse(p,PK_QUERY)) c=0; + if (c!=4) + { + stop_mob(p); + p->stay_strategy|=MOB_PICK; + } + } + } + +void mob_check(int num,TMOB *p) + { + int sect,q,z; + + sect=p->sector; + q=p->stay_strategy & MOB_BIG; + z=p->vlajky & MOB_PASSABLE; + if (p->locy<64) + if (mob_check_next_sector(sect,0,q,z)) otoc_moba(p); + else mob_step_next(num,sect,0,&p->locy); + else if (p->locx>191) + if (mob_check_next_sector(sect,1,q,z)) otoc_moba(p); + else mob_step_next(num,sect,1,&p->locx); + else if (p->locy>191) + if (mob_check_next_sector(sect,2,q,z)) otoc_moba(p); + else mob_step_next(num,sect,2,&p->locy); + else if (p->locx<64) + if (mob_check_next_sector(sect,3,q,z)) otoc_moba(p); + else mob_step_next(num,sect,3,&p->locx); + if (battle && p->mode!=MBA_FLEE) + { + mob_sound_event(p,MBS_WALK); + stop_mob(p); + } + } + +/*void mobs_attack(TMOB *p) + { + int sect,dir,asect; + + if (p->actions<=0) return; + neco_v_pohybu=1; + sect=p->sector; + dir=p->dir; + asect=map_sectors[sect].step_next[dir]; + if (!asect || map_sides[sect*4+dir].flags & SD_MONST_IMPS) + { + rozhodni_o_smeru(p); + p->headx=mob_go_x[p->dir]; + p->heady=mob_go_y[p->dir]; + p->anim_phase=0; + return; + } + if (!(map_coord[asect].flags & MC_PLAYER)) + { + rozhodni_o_smeru(p); + p->headx=mob_go_x[p->dir]; + p->heady=mob_go_y[p->dir]; + p->anim_phase=0; + return; + } + p->anim_phase=MOB_ATTACK; + p->csektor=asect; + viewsector=asect; + viewdir=(dir+2)&3; + }*/ + +void vymaz_zasahy(THE_TIMER *q) + { + if (q->userdata[1]!=postavy[q->userdata[0]].dostal) return; + postavy[q->userdata[0]].dostal=0; + bott_draw(0); + } + +static drop_inventory(TMOB *p) + { + int i,x,y,pl; + short c[]={0,0}; + + for(i=-1;iinv[i] || (i<0 && p->money)) + { + if (p->locx>128) x=1;else if (p->locx<128) x=-1;else x=rnd(2)*2-1; + if (p->locy>128) y=1;else if (p->locy<128) y=-1;else y=rnd(2)*2-1; + pl=0;if (x>0) pl++; + if (y>0) pl=3-pl; + if (i<0) + { + int z=(int)p->money+(int)(rnd(40)-20)*(int)p->money/(int)100; + c[0]=create_item_money(z); + } + else + { + c[0]=p->inv[i]; + p->inv[i]=0; + } + push_item(p->sector,pl,c); + } + } + + +void mob_check_death(int num,TMOB *p) + { + int sect; + + mob_dostal=0; + bott_draw(0); + if (p->lives>0) return; + SEND_LOG("(GAME) Monster killed ... '%s'",p->name,0); + sect=p->sector; + p->vlajky&=~MOB_IN_BATTLE & ~MOB_LIVE; + free_path(num); + drop_inventory(p); + if (mob_map[sect]==num+MOB_START) mob_map[sect]=p->next; + else + { + p=&mobs[mob_map[sect]-MOB_START]; + p->next=0; + } + pozdrz_akci(); + } +extern char att_player; + +void mob_hit(TMOB *mm,int dostal) + { + int ch; + int mob_dostal,mob_dostal_pocet; + + if (mm->vlajky & MOB_PASSABLE) return; + if (dostal>mm->vlastnosti[VLS_MAXHIT]) dostal=mm->vlastnosti[VLS_MAXHIT]; + mm->headx=mm->locx; + mm->heady=mm->locy; + mm->lives-=dostal; + mob_dostal_pocet=dostal; + mm->dostal+=dostal; + if (dostal>0) mm->vlajky|=MOB_IN_BATTLE; + //mm->stay_strategy|=MOB_WALK | MOB_WATCH; + mm->dialog_flags|=0x2; + if (mm->lives>mm->vlastnosti[VLS_MAXHIT]) mm->lives=mm->vlastnosti[VLS_MAXHIT]; + dlives=mm->lives; + if (dostal>0) + { + ddostal=dostal; + send_experience(mm,dostal); + att_player=select_player; + if (dostallives) ch=dostal*3/mm->lives;else ch=2; + mob_dostal=ch+1; + bott_draw(0); + if (mm->lives<1) + { + int xpos; + switch (viewdir) + { + case 0:xpos=-(mm->locx-128);break; + case 1:xpos=-(mm->locy-128);break; + case 2:xpos=(mm->locx-128);break; + case 3:xpos=(mm->locy-128);break; + } + add_spectxtr(mm->sector,H_KILL,10,1,xpos*23/10); + mm->anim_phase=MOB_DEATH; + } + else mm->anim_phase=MOB_TO_HIT; + mm->anim_counter=0; + mm->mode=MBA_NONE; + mob_sound_event(mm,MBS_HIT); + battle|=dostal>0; + if (vybrana_zbran>-1) //utok zbrani? + { + int druh; + if (vybrana_zbran!=0) //neni to utok holyma rukama + { + TITEM *it; + it=&glob_items[vybrana_zbran-1]; + druh=it->typ_zbrane; + } + else druh=TPW_OST; + send_weapon_skill(druh); + vybrana_zbran=-1; + } + } + if (mob_dostal_pocet>0)draw_blood(1,mob_dostal,mob_dostal_pocet); + } + + +void mob_strelba(TMOB *p) + { + int i; + TITEM *t; + + for(i=0;izmeny[VLS_MGSIL_H]=p->vlastnosti[VLS_MGSIL_H]; //adjust zmen v magickem utoku + t->zmeny[VLS_MGSIL_L]=p->vlastnosti[VLS_MGSIL_L]; + t->zmeny[VLS_MGZIVEL]=p->vlastnosti[VLS_MGZIVEL]; + spell_throw(-((p-mobs)+1),i); + letici_veci->flags &=~FLY_DESTROY; + letici_veci->hit_bonus=p->vlastnosti[VLS_UTOK_L]+rnd(p->vlastnosti[VLS_UTOK_H]-p->vlastnosti[VLS_UTOK_L]+1); + letici_veci->damage=p->vlastnosti[VLS_DAMAGE]; + p->dostal=0; + } + +static void knock_player_back(THUMAN *p,int dir) + { + int sect,sid,nsect; + + sect=p->sektor;sid=sect*4+dir; + nsect=map_sectors[sect].step_next[dir]; + if (mob_map[nsect]) return; + destroy_player_map(); + call_macro(sid,MC_EXIT); + if (map_sides[sid].flags & SD_PLAY_IMPS) + { + call_macro(sid,MC_PASSFAIL); + build_player_map(); + return; + } + else call_macro(sid,MC_PASSSUC); + p->sektor=nsect; + viewsector=nsect; + check_postavy_teleport(); + build_player_map(); + recheck_button(nsect,1); + recheck_button(sect,1); + redraw_scene(); + hold_timer(TM_BACK_MUSIC,1); + zooming_backward(ablock(H_BGR_BUFF)); + hold_timer(TM_BACK_MUSIC,0); + showview(0,0,0,0); + } + +void PodporaStitu(THUMAN *h, short *vlastnosti) + { + int pos[]={PO_RUKA_L,PO_RUKA_R}; + int i; + int factor=h->kondice*100/h->vlastnosti[VLS_KONDIC]; + for (i=0;i<2;i++) + { + if (h->wearing[pos[i]]!=0) + { + TITEM *it=glob_items+h->wearing[pos[i]]-1; + if (it->zmeny[VLS_OBRAN_L] || it->zmeny[VLS_OBRAN_H]) + { + vlastnosti[VLS_OBRAN_L]-=it->zmeny[VLS_OBRAN_L]; + vlastnosti[VLS_OBRAN_H]-=it->zmeny[VLS_OBRAN_H]; + vlastnosti[VLS_OBRAN_L]+=(2*it->zmeny[VLS_OBRAN_L])*factor/100; + vlastnosti[VLS_OBRAN_H]+=(2*it->zmeny[VLS_OBRAN_H])*factor/100; + } + } + } + if (factor<20) + { + vlastnosti[VLS_OBRAT]=vlastnosti[VLS_OBRAT]*factor/20; + } + if (h->kondice) h->kondice--; + } + +void mobs_hit(TMOB *p) + { + int asect; + int obet; + int i,pocet; + THE_TIMER *tt; + int spec;char rr=1;char dead; + THUMAN *h; + short vlastnosti[VLS_MAX]; + + if (p->mode==MBA_SPELL) + { + mob_cast(p->casting,p,p-mobs); + p->dostal=0; + } + else + if (p->stay_strategy & MOB_ROGUE) mob_strelba(p); + else + { + asect=p->csektor; + if (!(map_coord[asect].flags & MC_PLAYER)) return; + pocet=0; + for(i=0;iused && p->sektor==asect && p->lives) pocet++; + } + if (!pocet) abort(); + obet=1+rnd(pocet); + for(i=0;obet>0;) + { + THUMAN *p; + i++; + if (i>=POCET_POSTAV) i=0; + p=&postavy[i]; + if (p->used && p->sektor==asect && p->lives) obet--; + } + h=&postavy[i]; + if (h->utek) + { + pocet=10; + h->utek--; + } + memcpy(vlastnosti,h->vlastnosti,sizeof(vlastnosti)); + spec=vlastnosti[VLS_KOUZLA]; + if (game_extras & EX_SHIELD_BLOCKING) PodporaStitu(h,vlastnosti); + else uprav_podle_kondice(h,&pocet); + h->dostal=vypocet_zasahu(p->vlastnosti,vlastnosti,pocet,0,0); //vypocet zasahu + if (h->dostal) p->dostal=0; + if (spec & SPL_OKO) //oko za oko pro hrace + { + vybrana_zbran=-1; + mob_hit(p,h->dostal); + mob_check_death(p-mobs,p); + } + if (h->dostal && p->vlastnosti[VLS_KOUZLA] & SPL_KNOCK) knock_player_back(h,p->dir); + if (p->vlastnosti[VLS_KOUZLA] & SPL_DRAIN) //energy drain pro potvoru + { + p->lives+=h->dostal; + if (p->lives>p->vlastnosti[VLS_MAXHIT])p->lives=p->vlastnosti[VLS_MAXHIT]; + } + dead=player_hit(h,h->dostal,1); + if (h->lives>h->vlastnosti[VLS_MAXHIT]) h->lives=h->vlastnosti[VLS_MAXHIT]; + if ((spec & SPL_TVAR) && (spec & SPL_OKO)) //nedovolena kombinace + { + char s[200]; + h->lives=0; + sprintf(s,texty[73+(postavy[i].female==1)],postavy[i].jmeno); + bott_disp_text(s); + rr=0; + dead=player_check_death(&postavy[i],0); + } + tt=add_to_timer(TM_CLEAR_ZASAHY,100,1,vymaz_zasahy);tt->userdata[0]=i;tt->userdata[1]=postavy[i].dostal; + if (dead && hlubina_level>0) + { + select_player=i; + vybrana_zbran=-1; + mob_hit(p,p->lives); //hlubina (potvora je mrtva); + } + bott_draw(rr); + } + } + + +void mobs_live(int num) + { + TMOB *p; + int xs,ys; + + p=&mobs[num]; + if (p->vlastnosti[VLS_KOUZLA] & SPL_STONED && p->lives>0) + { + p->vlajky &= ~MOB_IN_BATTLE; + return; + } + if (p->sector>=mapsize) + { + char buff[256]; + closemode(); + sprintf(buff,"Potvora v neexistujicim sektoru (%d, %d) ",num,p->sector); + MessageBox(NULL,buff,NULL,MB_OK|MB_ICONEXCLAMATION); + exit(1); + } + if (p->headx==p->locx && p->heady==p->locy && !p->anim_phase) + { + //zde se bude rozhodovat co dal; + p->anim_counter=-1; + stop_track_free(num+256); + if (battle) + { + if (p->mode!=MBA_NONE && p->mode!=MBA_FLEE) + { + neco_v_pohybu=1; + p->anim_phase=MOB_ATTACK; + p->anim_counter=0; + mob_sound_event(p,MBS_ATTACK); + mobs_live(num); + return; + } + if (p->mode==MBA_NONE) return; + rozhodni_o_smeru(p); + return; + } + if (p->stay_strategy & MOB_PICK) + { + if (!seber_predmet(p)) return; + if (pick_item_corpse(p,PK_PICK)) return; + p->stay_strategy&=~MOB_PICK; + } + if (p->stay_strategy & MOB_WALK) + { + if (p->walk_data>=224) + if (++p->walk_data<255) + { + p->anim_counter=-1; + return; + } + p->anim_counter=0; + rozhodni_o_smeru(p); + } + else + if (mob_map[p->sector]==num+MOB_START && (!p->next) ) + { + p->headx=128;p->heady=128; + } + } + else + { + if (p->anim_phasemode==MBA_FLEE) + { + int xr=abs(map_coord[p->sector].x-map_coord[viewsector].x); + int yr=abs(map_coord[p->sector].y-map_coord[viewsector].y); + if (xr>3 || yr>3) spd=100;else spd=2*p->speed; + } + else spd=p->speed; + xs=p->headx-p->locx; + ys=p->heady-p->locy; + if (!(game_extras & EX_WALKDIAGONAL) || p->stay_strategy & MOB_BIG) + { + if (ys!=0 && xs!=0) + if (p->dir==1 || p->dir==3) xs=0;else ys=0; + } + if (xs>spd) xs=spd; + else if (xs<-spd) xs=-spd; + if (ys>spd) ys=spd; + else if (ys<-spd) ys=-spd; + p->locx+=xs; + p->locy+=ys; + if (xs!=0 || ys!=0) neco_v_pohybu=1; + if (p->locx>192 || p->locx<64 || p->locy>192 || p->locy<64) mob_check(num,p); + } + p->anim_counter++; + if (p->anim_phase==MOB_ATTACK) + { + neco_v_pohybu=1; + if (p->anim_counter==p->hit_pos) mobs_hit(p); + if (p->anim_counter>=p->anim_counts[4]) + { + if (p->lives<1) p->anim_phase=MOB_TO_HIT;else p->anim_phase=0; + p->anim_counter=-1; + p->mode=MBA_NONE; + } + } + else + if (p->anim_phase==MOB_TO_HIT && p->anim_counter>=p->anim_counts[5]) + { + neco_v_pohybu=1; + p->anim_phase=0; + p->anim_counter=-1; + mob_check_death(num,p); + } + else + if (p->anim_phase==MOB_DEATH) + { + neco_v_pohybu=1; + if (p->anim_counter==2) mob_check_death(num,p); + else if (p->anim_counter>12) + { + p->anim_phase=0; + p->anim_counter=-1; + } + } + } + } + +void calc_mobs() + { + int i; + + neco_v_pohybu=0; + for(i=0;ivlajky & MOB_LIVE) + { + mob_test_na_bitvu(p); + if (p->vlajky & MOB_IN_BATTLE) b=1; + } + } + battle=b; + } + +void check_all_mobs_battle() //kontroluje zda je nekdo v battle + { + int i; + TMOB *p; + char b=0; + + for(i=0;ivlajky & MOB_LIVE) + if (p->vlajky & MOB_IN_BATTLE) + b=1; + } + battle=b; + } + + +#define Hi(x) ((x)>>16) +#define Lo(x) ((x)& 0xffff) + +int q_kolik_je_potvor(int sector) + { + if (mob_map[sector]) + if (mobs[mob_map[sector]-MOB_START].next) return 2; + else if (mobs[mob_map[sector]-MOB_START].stay_strategy & MOB_BIG) return 2; + else return 1; + return 0; + } + +void najdi_cestu(word start,word konec,int flag,word **cesta, int iamcnt) + { + longint *stack; + longint *stk_free; + longint *stk_cur; + char *ok_flags; + + *cesta=NULL; + stk_free=stk_cur=stack=getmem(4*(mapsize+2)); + memset(ok_flags=getmem((mapsize+8)/8),0,(mapsize+8)/8); + ok_flags[start>>3]|=1<<(start & 0x7); + for(*stk_free++=start;stk_free!=stk_cur;stk_cur++) + { + char i;word s,d=0xFFFF,ss; + s=(ss=Lo(*stk_cur))<<2; + for(i=0;i<4;i++) if (!(map_sides[s+i].flags & flag)) + { + char c; + word w; + d=map_sectors[ss].step_next[i]; + c=1<<(d & 0x7); + w=d>>3; + if (!(ok_flags[w] & c) && q_kolik_je_potvor(d)>3]|=1<<(start & 0x7); + for(*stk_free++=start;stk_free!=stk_cur;stk_cur++) + { + char i;word s,d,ss; + s=(ss=Lo(*stk_cur))<<2; + for(i=0;i<4;i++) if (!(map_sides[s+i].flags & SD_SOUND_IMPS)) + { + char c; + word w; + d=map_sectors[ss].step_next[i]; + c=1<<(d & 0x7); + w=d>>3; + if (!(ok_flags[w] & c)) + { + int mob; + + ok_flags[w]|=c; + *stk_free++=d | ((stk_cur-stack)<<16); + mob=mob_map[d]-MOB_START; + if (mob>=0) + { + reakce_na_hluk(mob,i+2&3); + if ((mob=mobs[mob].next-MOB_START)>=0) reakce_na_hluk(mob,i+2&3); + } + } + } + } + free(stack); + free(ok_flags); + } + +void refresh_mob_map() + { + int i,s; + + memset(mob_map,0,mapsize); + for(i=0;istay_strategy & MOB_BIG) return 0; + if (mm->dir!=i && i!=-1) return 0; + stop_mob(mm); + if (!mm->next && i==-1) + if (mm->headx==128 || mm->heady==128) smeruj_moba(mm,1); + i=mm->dir;m=mm->next; + } + if (!(map_sides[(sect<<2)+dir].flags & SD_THING_IMPS)) + sect=map_sectors[sect].step_next[dir]; + else return 1; + } + while (1); + } + + +//--------------------------------------------------------------------- +/* Nasledujici procedury a funkce se volaji pro chovani potvory v bitve */ + +static word last_sector; +static TMOB *fleeing_mob; + +static char valid_sectors(word sector) + { + int pp; + + last_sector=sector; + if (map_coord[sector].flags & MC_MARKED) return 0; //nevyhovujici + pp=q_kolik_je_potvor(sector); + if (pp==2) return 0; //moc potvor - nevyhovujici + if (fleeing_mob->stay_strategy & MOB_BIG && pp) return 0; + pp=map_sectors[sector].sector_type; + if (pp==S_DIRA || ISTELEPORT(pp)) return 0; + return 1; + } + + +char flee_monster_zac(TMOB *m) + { + int ss,s; + int i,j; + word *cesta,*c,cntr; + for(j=0;jsector,65535,SD_MONST_IMPS,valid_sectors,NULL); + i=labyrinth_find_path(m->sector,last_sector,SD_MONST_IMPS,valid_sectors,&cesta); + for(j=0;jmode=MBA_FLEE; + m->headx=m->locx+1; + m->actions=6; + m->dostal=0; + return 1; + } + +char akce_moba_zac(TMOB *m) + { + int sect,flg,i,j; + THUMAN *h; + char flee; + int perlives,dper,corlives; + + if (~m->vlajky & MOB_LIVE) return 1; + dper=m->dostal*100/(m->lives+m->dostal); + corlives=m->vlastnosti[VLS_MAXHIT]-m->flee_num*(m->vlastnosti[VLS_MAXHIT]-m->lives)/100; + perlives=(100-m->flee_num)*corlives*q_kolik_je_potvor(m->sector)/(m->vlastnosti[VLS_MAXHIT]); + perlives+=rnd(m->flee_num); + dper+=rnd(m->flee_num); + flee=dper>perlives || m->vlastnosti[VLS_KOUZLA] & SPL_FEAR; + if (flee) + { + if (flee_monster_zac(m)) return 1; + m->dostal=0; + } + if (call_mob_event(m->specproc,SMPR_ATTACK,m)) + { + mob_walk_sound(m); + return 0; + } + sect=map_sectors[m->sector].step_next[m->dir]; + flg=map_sides[(m->sector<<2)+m->dir].flags; + if (!(flg & SD_PLAY_IMPS)) + if (map_coord[sect].flags & MC_PLAYER) + for(i=0;iused && p->lives && p->sektor==sect) + { + if ((m->vlajky & MOB_CASTING && get_spell_track(m->casting))|| m->stay_strategy & MOB_ROGUE) + {stop_all_mobs_on_sector(m->sector);smeruj_moba(m,0);} + else stop_mob(m); + viewsector=sect; + viewdir=m->dir+2 &3; + m->csektor=sect; + if (m->vlajky & MOB_CASTING && rnd(100)<=m->vlastnosti[VLS_SMAGIE]) m->mode=MBA_SPELL;else m->mode=MBA_ATTACK; + bott_draw(1); + return 0; + } + } + for(i=0;i<4;i++) + { + sect=map_sectors[m->sector].step_next[i]; + flg=map_sides[(m->sector<<2)+i].flags; + if (!(flg & SD_MONST_IMPS)) + if (map_coord[sect].flags & MC_PLAYER) + for(j=0;jused && p->lives && p->sektor==sect && !(p->vlastnosti[VLS_KOUZLA] & SPL_INVIS)) + { + m->dir=i; + stop_mob(m); + return 1; + } + } + } + sect=m->sector; + i=q_vidis_postavu(m->sector,m->dir,m,&j,1); + h=postavy+i; + if (i>-1) + if (((m->vlajky & MOB_CASTING && get_spell_track(m->casting))|| m->stay_strategy & MOB_ROGUE) && + (map_coord[m->sector].x==map_coord[h->sektor].x || map_coord[m->sector].y==map_coord[h->sektor].y) + && track_mob(m->sector,m->dir)) + { + m->dir=j; + stop_all_mobs_on_sector(m->sector); + if (~m->stay_strategy & MOB_ROGUE) + m->mode=MBA_SPELL; + else + m->mode=MBA_ATTACK; + smeruj_moba(m,0); + viewsector=h->sektor; + viewdir=m->dir+2 & 3; + return 0; + } + else + { + word *cesta; + + najdi_cestu(m->sector,postavy[i].sektor,SD_MONST_IMPS,&cesta,(m->stay_strategy & MOB_BIG)?1:2); + if (cesta!=NULL) + { + for(j=0;j<4 && map_sectors[sect].step_next[j]!=cesta[0];j++); + m->dir=j & 3; + free(cesta); + if (m->dir & 1)m->headx=mob_go_x[m->dir];else m->heady=mob_go_y[m->dir]; + mob_sound_event(m,MBS_WALK); + return 1; + } + else + return 1; + } + rozhodni_o_smeru(m); + if (m->dir & 1)m->headx=mob_go_x[m->dir];else m->heady=mob_go_y[m->dir]; +// m->headx=mob_go_x[m->dir]; +// m->heady=mob_go_y[m->dir]; + m->vlajky&=~MOB_IN_BATTLE; + return 1; + } + +void mob_animuj() + { + int mob; + + for(mob=0;moblocylocy) return m;else if (m1->locy>m2->locy) return ch;break; + case 1: if (m1->locxlocx) return m;else if (m1->locx>m2->locx) return ch;break; + case 0: if (m1->locy>m2->locy) return m;else if (m1->locylocy) return ch;break; + case 3: if (m1->locx>m2->locx) return m;else if (m1->locxlocx) return ch;break; + } + x=rnd(2); + if (x) return ch; + return m; + } + +static void knock_mob_back(TMOB *mm,int dir) + { + char chk; + int i,sek,mnum,mms; + + if (call_mob_event(mm->specproc,SMPR_KNOCK,mm)) return; + mms=mm->sector;mnum=mm-mobs+MOB_START; + chk=mob_check_next_sector(mms,dir,mm->stay_strategy,mm->vlajky); + if (chk) return; + sek=map_sectors[mms].step_next[dir]; + i=mob_map[sek]; + if (mob_map[mms]!=mnum) mobs[mob_map[mms]-MOB_START].next=0;else mob_map[mms]=mm->next; + if (i) + { + mm->next=i; + uhni_mobe(1,i-1,0); + } + else mm->next=0; + mob_map[sek]=mm-mobs+MOB_START;mm->sector=sek; + recheck_button(mms,1); + recheck_button(sek,1); + } + +int utok_na_sektor(THUMAN *p,TMOB *mm,int ch,int bonus) + { + int dostal; + + dostal=vypocet_zasahu(p->vlastnosti,mm->vlastnosti,ch,bonus,0); + mob_hit(mm,dostal); + if (dostal && p->vlastnosti[VLS_KOUZLA] & SPL_KNOCK) knock_mob_back(mm,p->direction); + if (mm->vlastnosti[VLS_KOUZLA] & SPL_OKO) //oko za oko pro potvoru + { + p->lives-=dostal; + player_check_death(p,0); + } + if (dostal) + { + mm->dir=(p->direction+2)&3; + play_sample_at_sector(H_SND_SWHIT1+rnd(2),viewsector,viewsector,0,0); + if (p->vlastnosti[VLS_KOUZLA] & SPL_DRAIN) + { + p->lives+=dostal*8/(rnd(16)+16); + if (p->lives>p->vlastnosti[VLS_MAXHIT]) p->lives=p->vlastnosti[VLS_MAXHIT]; + } + } + else + { + ddostal=0; + play_sample_at_sector(H_SND_SWMISS1+rnd(2),viewsector,viewsector,0,0); + } + mm->vlajky|=MOB_IN_BATTLE; + neco_v_pohybu=1; + return ddostal; + } + +void sleep_enemy(char regen) + { + int i; + + for(i=0;ivlajky & MOB_LIVE && m->lives>0) + { + if (regen) + { + m->lives+=m->vlastnosti[VLS_HPREG]; + if (m->lives>m->vlastnosti[VLS_MAXHIT]) m->lives=m->vlastnosti[VLS_MAXHIT]; + } + if (m->stay_strategy & MOB_WALK) + { + m->locx=m->headx; + m->locy=m->heady; + mob_check(i,m); + if (m->locx<64 || m->locx>192) m->locx=128; + if (m->locy<64 || m->locy>192) m->locy=128; + if (m->locx==m->headx && m->locy==m->heady) rozhodni_o_smeru(m); + } + } + + } + } + +static int mob_mob_alter(int num) + { + int i; + num-=MOB_START; + if (num<0) return 0xff; + if (mobs[num].dialog>-1 && ~mobs[num].vlajky & MOB_PASSABLE) start_dialog(mobs[num].dialog,num); + else if (mobs[num].stay_strategy & MOB_WATCH) + { + stop_mob(mobs+num); + if (!battle) battle=1; + } + i=mob_mob_alter(mobs[num].next); + return (mobs[num].vlajky & MOB_PASSABLE) & i; + } + +int mob_alter(int sect) + { + char p; + att_player=0xff; + p=mob_mob_alter(mob_map[sect]); +/* if (p) + { + int i;THUMAN *h; + for (i=0;iused && h->lives && h->groupnum==cur_group) + {att_player=group_sort[i];break;} + } + }*/ + return p; + } + +void regen_all_mobs() + { + int i; + TMOB *m; + + for(i=0,m=mobs;ivlajky & MOB_LIVE && m->vlastnosti[VLS_HPREG]) + m->lives=m->vlastnosti[VLS_MAXHIT]; + } + diff --git a/GAME/ENGINE1.C b/GAME/ENGINE1.C new file mode 100644 index 0000000..2b06abd --- /dev/null +++ b/GAME/ENGINE1.C @@ -0,0 +1,1412 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "math.h" +#include "globals.h" +#include "engine1.h" + +#define CTVR 128 + +t_points points; +struct all_view showtabs; +static char backgrnd_mode=0; + +static int lclip,rclip; + +ZOOMINFO zoom; +char zooming_xtable[ZOOM_PHASES][VIEW_SIZE_X]; +short zooming_ytable[ZOOM_PHASES][VIEW_SIZE_Y]; +short zooming_points[ZOOM_PHASES][4] + ={ + {620,349,10,3}, + {600,338,20,7}, + {580,327,30,11}, + {560,316,40,14}, + {540,305,50,18}, + {520,293,60,21}, + {500,282,70,25}, + {480,271,80,28}, + {460,259,90,31} + }; +int zooming_step=1; +int rot_phases=1; +int yreq; +int last_scale; +char secnd_shade=1; + +void sikma_zleva(void); +//#pragma aux sikma_zleva parm modify [EAX EBX ECX EDX ESI EDI] +void sikma_zprava(void); +//#pragma aux sikma_zprava parm modify [EAX EBX ECX EDX ESI EDI] +/*void zooming_dx(void *source,void *target,void *background,void *xlat,long xysize); +//#pragma aux zooming_dx parm [ESI][EDI][EAX][EBX][ECX] modify [EDX] +void zooming32(void *source,void *target,void *background,void *xlat,long xysize); +//#pragma aux zooming32 parm [ESI][EDI][EAX][EBX][ECX] modify [EDX] +void zooming32b(void *source,void *target,void *background,void *xlat,long xysize); +//#pragma aux zooming32b parm [ESI][EDI][EAX][EBX][ECX] modify [EAX EDX] +void zooming_lo(void *source,void *target,void *xlat,long xysize); +//#pragma aux zooming_lo parm [ESI][EDI][EBX][ECX] modify [EAX EDX] +void zooming256(void *source,void *target,void *background,void *xlat,long xysize); +//#pragma aux zooming256 parm [ESI][EDI][EAX][EBX][ECX] modify [EDX] +void zooming256b(void *source,void *target,void *background,void *xlat,long xysize); +//#pragma aux zooming256b parm [ESI][EDI][EAX][EBX][ECX] modify [EAX EDX] +void zooming64(void *source,void *target,void *background,void *xlat,long xysize); +//#pragma aux zooming64 parm [ESI][EDI][EAX][EBX][ECX] modify [EDX] +void zooming64b(void *source,void *target,void *background,void *xlat,long xysize); +//#pragma aux zooming64b parm [ESI][EDI][EAX][EBX][ECX] modify [EAX EDX] +void scroll_support_dx(void *lbuf,void *src1,void *src2,int size1); +//#pragma aux scroll_support_dx parm [EDI][ESI][EDX][ECX] modify [EAX] +void scroll_support_32(void *lbuf,void *src1,void *src2,int size1); +//#pragma aux scroll_support_32 parm [EDI][ESI][EDX][ECX] modify [EAX] +void scroll_support_32b(void *lbuf,void *src1,void *src2,int size1); +//#pragma aux scroll_support_32b parm [EDI][ESI][EDX][ECX] modify [EAX] +void scroll_support_256(void *lbuf,void *src1,void *src2,int size1,void *xlat); +//#pragma aux scroll_support_256 parm [EDI][ESI][EDX][ECX][EBX] modify [EAX]; +void scroll_support_256b(void *lbuf,void *src1,void *src2,int size1,void *xlat); +//#pragma aux scroll_support_256b parm [EDI][ESI][EDX][ECX][EBX] modify [EAX]; +void scroll_support_64(void *lbuf,void *src1,void *src2,int size1,void *xlat); +//#pragma aux scroll_support_64 parm [EDI][ESI][EDX][ECX][EBX] modify [EAX]; +void scroll_support_64b(void *lbuf,void *src1,void *src2,int size1,void *xlat); +//#pragma aux scroll_support_64b parm [EDI][ESI][EDX][ECX][EBX] modify [EAX];*/ +void fcdraw(void *source,void *target, void *table); +//#pragma aux fcdraw parm [EDX][EBX][EAX] modify [ECX ESI EDI]; + +/*void lodka32(void *source,void *target,void *background,void *xlat,long xysize); +//#pragma aux lodka32 parm [ESI][EDI][EAX][EBX][ECX] modify [EDX] +void lodka_dx(void *source,void *target,void *background,void *xlat,long xysize); +//#pragma aux lodka_dx parm [ESI][EDI][EAX][EBX][ECX] modify [EDX] +void lodka32b(void *source,void *target,void *background,void *xlat,long xysize); +//#pragma aux lodka32b parm [ESI][EDI][EAX][EBX][ECX] modify [EDX] + +void lodka256(void *source,void *target,void *background,void *xlat,long xysize); +//#pragma aux lodka256 parm [ESI][EDI][EAX][EBX][ECX] modify [EDX] +void lodka256b(void *source,void *target,void *background,void *xlat,long xysize); +//#pragma aux lodka256b parm [ESI][EDI][EAX][EBX][ECX] modify [EAX EDX] + +void lodka64(void *source,void *target,void *background,void *xlat,long xysize); +//#pragma aux lodka64 parm [ESI][EDI][EAX][EBX][ECX] modify [EDX] +void lodka64b(void *source,void *target,void *background,void *xlat,long xysize); +//#pragma aux lodka64b parm [ESI][EDI][EAX][EBX][ECX] modify [EAX EDX] +*/ + +void *p,*p2,*pozadi,*podlaha,*strop,*sit;int i; +void (*zooming)(void *source,long target,word *background,void *xlat,long xysize); +void (*turn)(long lbuf,void *src1,void *src2,int size1); +word *GetBuffer2nd(); +word *background; +char debug=0,nosides=0,nofloors=0,drwsit=0,show_names=0,show_lives=0; +static long old_timer; + +static void wait_timer() + { + Sleep(10); + } + +/*void zooming1(void *source,long target,word *background,void *xlat,long xysize) + { + wait_timer(); + if (backgrnd_mode) + lodka_dx(source,GetScreenAdr()+target,background+3,xlat,xysize); + else + zooming_dx(source,GetScreenAdr()+target,background+3,xlat,xysize); + showview(0,0,0,0); + } +/* +void zooming2(void *source,long target,word *background,void *xlat,long xysize) + { + word *lbuffer=LockDirectScreen(); + wait_timer(); + if (backgrnd_mode) + lodka256(source,lbuffer+(target>>1),background+3,xlat,xysize); + else + zooming256(source,lbuffer+(target>>1),background+3,xlat,xysize); + UnlockDirectScreen(); + } + +void zooming3(void *source,long target,word *background,void *xlat,long xysize) + { + source;target;background;xlat;xysize; + } + +/*void zooming4(void *source,long target,word *background,void *xlat,long xysize) + { + word *lbuffer=LockDirectScreen(); + wait_timer(); + if (backgrnd_mode) + lodka32b(source,(void *)(target*2),background+3,xlat,xysize); + else + zooming32b(source,(void *)(target*2),background+3,xlat,xysize); + UnlockDirectScreen(); + }*/ +/* +void zooming5(void *source,long target,word *background,void *xlat,long xysize) + { + wait_timer(); + if (backgrnd_mode) + lodka256b(source,(void *)target,background+3,xlat,xysize); + else + zooming256b(source,(void *)target,background+3,xlat,xysize); + } + +void zooming6(void *source,long target,word *background,void *xlat,long xysize) + { + word *lbuffer=LockDirectScreen(); + wait_timer(); + if (backgrnd_mode) + lodka_dx(source,lbuffer+(target),background+3,xlat,xysize); + else + zooming_dx(source,lbuffer+(target),background+3,xlat,xysize); + UnlockDirectScreen(); + } +/* +void zooming7(void *source,long target,word *background,void *xlat,long xysize) + { + wait_timer(); + if (backgrnd_mode) + lodka64b(source,(void *)(target*2),background+3,xlat,xysize); + else + zooming64b(source,(void *)(target*2),background+3,xlat,xysize); + } +*/ + +void turn1(long lbuf,void *src1,void *src2,int size1) + { +//wait_timer(); +// scroll_support_dx(lbuf+GetScreenAdr(),src1,src2,size1); + showview(0,0,0,0); + } + +/*void turn2(long lbuf,void *src1,void *src2,int size1) + { + wait_timer(); + scroll_support_256((lbuf>>1)+lbuffer,src1,src2,size1,xlatmem); + } +*/ +void turn3(long lbuf,void *src1,void *src2,int size1) + { + lbuf;src1;src2;size1; + } +/* +void turn4(long lbuf,void *src1,void *src2,int size1) + { + wait_timer(); + scroll_support_32b((void *)(lbuf*2),src1,src2,size1); + } + +void turn5(long lbuf,void *src1,void *src2,int size1) + { + wait_timer(); + scroll_support_256b((void *)lbuf,src1,src2,size1,xlatmem); + } +*/ +/* +void turn6(long lbuf,void *src1,void *src2,int size1) + { + word *lbuffer=LockDirectScreen(); + wait_timer(); + scroll_support_dx((lbuf)+lbuffer,src1,src2,size1,xlatmem); + UnlockDirectScreen(); + } +/* +void turn7(long lbuf,void *src1,void *src2,int size1) + { + wait_timer(); + scroll_support_64b((void *)(lbuf*2),src1,src2,size1,xlatmem); + } +*/ + + +void calc_points(void) + { + int i,j,x1,y1,x2,y2; + + for (j=0;jtxt_size_x) + { + if (z==-1) z=i-3; + j=((i-z)*txt_size_x)/scale1+txt_size_x; + } + else j=(i*txt_size_x)/len; + *ptr++=(j-old-1); + old=j; + } + + } + +void calc_y_buffer(short *ptr,long txt_size_y, long len,long total) + { + int i,j,old; + + old=-1; + for (i=0;iMIDDLE_X) showtabs.z_table[x][y].used=0; + else + { + showtabs.z_table[x][y].used=1; + rozdil1=points[x][0][y].x-points[x][0][y+1].x; + rozdil2=rozdil1-MIDDLE_X+points[x][0][y+1].x; + rozdil3=points[0][0][y].x-points[0][0][y+1].x; + if (rozdil2<0) + { + showtabs.z_table[x][y].xpos=MIDDLE_X-points[x][0][y].x; + showtabs.z_table[x][y].txtoffset=0; + } + else + { + showtabs.z_table[x][y].xpos=MIDDLE_X-points[x][0][y].x; + showtabs.z_table[x][y].txtoffset=(TXT_SIZE_X_3D*rozdil2/rozdil1); + } + showtabs.z_table[x][y].point_total=rozdil1; + calc_x_buffer(showtabs.z_table[x][y].zoom_table,TXT_SIZE_X_3D,rozdil1,VIEW_SIZE_X,rozdil3); + } + + } + + for (y=0;yTXT_SIZE_X) showtabs.z_table[x][y].used=0; + else + { + showtabs.x_table[x][y].used=1; + rozdil1=points[1][0][y+1].x-points[0][0][y+1].x; + rozdil2=-MIDDLE_X+points[x][0][y+1].x; + if (rozdil2<0) + { + showtabs.x_table[x][y].xpos=MIDDLE_X-points[x][0][y+1].x; + showtabs.x_table[x][y].txtoffset=0; + showtabs.x_table[x][y].max_x=rozdil1; + } + else + { + showtabs.x_table[x][y].xpos=MIDDLE_X-points[x][0][y+1].x; + showtabs.x_table[x][y].txtoffset=(TXT_SIZE_X*rozdil2/rozdil1); + showtabs.x_table[x][y].max_x=MIDDLE_X-points[x-1][0][y+1].x; + } + if (x!=0)showtabs.x_table[x][y].xpos2=VIEW_SIZE_X-(showtabs.x_table[x][y].xpos+rozdil1); + showtabs.x_table[x][y].point_total=rozdil1; + calc_x_buffer(showtabs.x_table[x][y].zoom_table,TXT_SIZE_X,rozdil1,VIEW_SIZE_X,rozdil1); + } + + } + + for(x=0;x>1; + y1=(VIEW_SIZE_Y-y)-MIDDLE_Y; + yp=1;while (points[0][0][yp].y>y1) yp++; + if (xstrd) + { + xl=+points[x-strd-1][0][0].x;xr=+points[x-strd][0][0].x; + } + y1=(VIEW_SIZE_Y-y)-MIDDLE_Y; + xl=xl*(y1+1)/points[0][0][0].y+MIDDLE_X; + xr=xr*(y1+1)/points[0][0][0].y+MIDDLE_X; + if (xl<0) xl=0;if (xr<0) xr=0; + if (xl>639) xl=639;if (xr>639) xr=639; + showtabs.f_table[x][y].lineofs=(y1+MIDDLE_Y)*scr_linelen+xl*2; + showtabs.f_table[x][y].linesize=xr-xl+(xl!=xr); + showtabs.f_table[x][y].counter=(y1-points[0][0][yp].y); + showtabs.f_table[x][y].txtrofs=(y1+MIDDLE_Y-VIEW_SIZE_Y+F_YMAP_SIZE)*1280+xl*2; + } + + for(x=0;x>1; + y1=y-MIDDLE_Y; + yp=1;while (points[0][1][yp].ystrd) + { + xl=+points[x-strd-1][1][0].x;xr=+points[x-strd][1][0].x; + } + xl=xl*(y1-2)/points[0][1][0].y+MIDDLE_X; + xr=xr*(y1-2)/points[0][1][0].y+MIDDLE_X; + if (xl<0) xl=0;if (xr<0) xr=0; + if (xl>639) xl=639;if (xr>639) xr=639; + showtabs.c_table[x][y].lineofs=(y1+MIDDLE_Y)*scr_linelen+xl*2; + showtabs.c_table[x][y].linesize=xr-xl+(xl!=xr); + showtabs.c_table[x][y].counter=points[0][1][yp].y-y1; + showtabs.c_table[x][y].txtrofs=(y1+MIDDLE_Y)*1280+xl*2; + } + + + } + +void calc_zooming(char *buffer,int dvojice,int oldsiz) + { + int poz,roz,i,x; + + poz=-2; + for(i=0;i2) roz=2; + if (roz<1) roz=1; + if (roz==1) *buffer++=1; else *buffer++=0; + poz+=roz; + } + } + +void create_zooming(void) + { + int i,j; + + for (j=0;j=0;i-=zooming_step) + { + zoom.xtable=(long *)&zooming_xtable[i]; + zoom.ytable=(short *)&zooming_ytable[i]; + zoom.texture_line=0; + do_events(); + zooming(GetScreenAdr()+zooming_points[i][2]+zooming_points[i][3]*scr_linelen2+SCREEN_OFFSET,SCREEN_OFFSET,background,xlatmem,(360<<16)+320); + } + } + +*/ + +static void turn_left_right(char right) + { + { + if (!rot_phases) return; + { + long tmp=get_timer_value(); + void *buffer=DxPrepareTurn(SCREEN_OFFLINE); + + int maxtime=5*rot_phases; + int curtime; + float phase; + int last=90; + + do + { + curtime=get_timer_value()-tmp; + phase=(curtime)*(1.0f/(float)maxtime); + //phase=(float)sin(3.14159265*0.5f*phase); + DxTurn(buffer,right,SCREEN_OFFLINE,90,phase,NULL); + do_events(); + } + while (curtime>5; + rev&=3; + if (celx<=0) x3d=&showtabs.z_table[-celx][cely]; else x3d=&showtabs.z_table[celx][cely]; + x0d=&showtabs.z_table[0][cely]; + if (!x3d->used) return; + yd=&showtabs.y_table[cely]; + yp=&showtabs.y_table[cely+1]; + txtsx=*(word *)stena; + txtsy=*((word *)stena+1); + if (rev<2) + { + xofs-=(txtsx>>1)*TXT_SIZE_X/TXT_SIZE_X_3D;yofs-=txtsy>>1; + } + rev&=1; + yss=(points[0][0][cely].y-points[0][0][cely+1].y)*xofs/TXT_SIZE_X; + ysd=(points[0][1][cely].y-points[0][1][cely+1].y)*xofs/TXT_SIZE_X; + yofs=yofs*(yd->vert_size-yss+ysd)/TXT_SIZE_Y+yss; + xofs=xofs*x3d->point_total/TXT_SIZE_X; + if (txtsx>x3d->point_total && celx) + { + realsx=txtsx*x0d->point_total/TXT_SIZE_X_3D; + realsx+=x3d->point_total-x0d->point_total; + } + else realsx=txtsx*x3d->point_total/TXT_SIZE_X_3D; + realsy=txtsy*yd->vert_size/TXT_SIZE_Y-1; + x=x3d->xpos+xofs; + if (-x>realsx) return; + p=stena;p+=SHADE_PAL+2*2+2; + i=0; + while (x<0) + { + p+=x3d->zoom_table[i++]+1; + realsx--;x++; + } + if (x+realsx>640) realsx=640-x; + if (realsx<=0) return; + yofs=yd->drawline-yofs; + yofs+=(plac==1)?(-yp->vert_size+points[0][0][cely+1].y-points[0][0][cely].y):((plac==2)?(yd->vert_size):0); + if (yofs>360) + { + int r=yofs-360,ui; + if (r>realsy) return; + ui=(r*txtsy/realsy); + p+=txtsx*ui;realsy-=r; + yofs=360; + } + if (yofs-realsy<0) realsy=yofs; + if (rev) + zoom.startptr=GetBuffer2nd()+yofs*scr_linelen2+(639-x)+SCREEN_OFFSET; + else + zoom.startptr=GetBuffer2nd()+yofs*scr_linelen2+x+SCREEN_OFFSET; + zoom.texture=p; + zoom.texture_line=txtsx; + zoom.xtable=&x3d->zoom_table[i]; + zoom.ytable=yd->zoom_table; + zoom.palette=(word *)((byte *)stena+6+512*(cely)+(secnd_shade?SHADE_STEPS*512:0)); + zoom.ycount=realsy+1; + zoom.xmax=realsx; + zoom.line_len=scr_linelen; + __try + { + if (rev) sikma_zprava(); else sikma_zleva(); + } + __finally + { + } + } + + +void show_cel2(int celx,int cely,void *stena,int xofs,int yofs,char rev) + { + T_INFO_X *x3d; + T_INFO_Y *yd; + int txtsx,txtsy,realsx,realsy,x,i; + char *p;int plac; + + if (stena==NULL) return ; + plac=rev>>5; + rev&=3; + if (celx==2) + x=celx; + if (rev==2) celx=-celx; + if (celx<=0) x3d=&showtabs.x_table[-celx][cely]; else x3d=&showtabs.x_table[celx][cely]; + if (!x3d->used) return; + yd=&showtabs.y_table[cely+1]; + txtsx=*(word *)stena; + txtsy=*((word *)stena+1); + if (!rev) + { + xofs-=txtsx>>1;yofs-=txtsy>>1; + } + yofs=yofs*yd->vert_size/TXT_SIZE_Y; + xofs=xofs*x3d->point_total/TXT_SIZE_X; + realsx=txtsx*x3d->point_total/TXT_SIZE_X; + realsy=txtsy*yd->vert_size/TXT_SIZE_Y; + if (celx<=0) x=x3d->xpos+xofs; else x=x3d->xpos2+xofs; + if (-x>realsx) return; + p=stena;p+=SHADE_PAL+2*2+2; + i=0; + while (x<0) + { + p+=x3d->zoom_table[i++]+1; + realsx--;x++; + } + if (x+realsx>640) realsx=640-x; + if (realsx<=0) return; + yofs=yd->drawline-yofs; + yofs+=(plac==1)?(-yd->vert_size):((plac==2)?(yd->vert_size):0); + if (yofs>360) + { + int r=yofs-360,ui; + if (r>realsy) return; + ui=(r*txtsy/realsy);realsy-=r; + p+=txtsx*ui; + yofs=360; + } + if (yofs-realsy<0) realsy=yofs; + if (rev==2) + zoom.startptr=GetBuffer2nd()+(yofs)*scr_linelen2+(639-x)+SCREEN_OFFSET; + else + zoom.startptr=GetBuffer2nd()+(yofs)*scr_linelen2+x+SCREEN_OFFSET; + zoom.texture=p; + zoom.texture_line=txtsx; + zoom.xtable=x3d->zoom_table; + zoom.ytable=yd->zoom_table; + zoom.palette=(word *)((byte *)stena+6+512*(cely)+(secnd_shade?SHADE_STEPS*512:0)); + zoom.ycount=realsy+1; + zoom.xmax=realsx; + zoom.line_len=scr_linelen; + if (rev==2) sikma_zprava(); else sikma_zleva(); + } + + + +void draw_floor_ceil(int celx,int cely,char f_c,void *txtr) + { + int y; + + if (nofloors) return; + txtr=(void *)((word *)txtr+3); + if (f_c==0) //podlaha + { + y=(VIEW_SIZE_Y-MIDDLE_Y)-points[0][0][cely].y+1; + if (y<1) y=1; + txtr=(void *)((word *)txtr); + fcdraw(txtr,GetBuffer2nd()+SCREEN_OFFSET,&showtabs.f_table[celx+3][y]); +/* if (debug) + { + memcpy(GetScreenAdr(),GetBuffer2nd(),512000); + showview(0,0,0,0); + }*/ + } + else + { + y=points[0][1][cely].y+MIDDLE_Y+1; + if (y<0) y=0; + fcdraw(txtr,GetBuffer2nd()+SCREEN_OFFSET,&showtabs.c_table[celx+3][y]); +/* if (debug) + { + memcpy(GetScreenAdr(),GetBuffer2nd(),512000); + showview(0,0,0,0); + }*/ + } + + } + + +void OutBuffer2nd(void) + { + int i; + for (i=0;i<480;i++) + memcpy(GetScreenAdr()+i*scr_linelen2,GetBuffer2nd()+i*scr_linelen2,640*2); + } + +void CopyBuffer2nd(void) + { + int i; + for (i=0;i<480;i++) + memcpy(GetBuffer2nd()+i*scr_linelen2,GetScreenAdr()+i*scr_linelen2,640*2); + } + + /*void chozeni(void) + { + char c; char dir=0;word sector=22; + + zooming_forward(); + swap_buffs(); + showview(0,0,0,0); + do + { + while (_bios_keybrd(_KEYBRD_READY)) _bios_keybrd(_KEYBRD_READ); + c=_bios_keybrd(_KEYBRD_READ) >> 8; + switch (c) + { + case 'H':if (mapa[sector][dir]!=-1) + { + sector=mapa[sector][dir]; + render_scene(sector,dir); + if (!debug) zooming_forward(); + swap_buffs(); + showview(0,0,0,0); + }break; + case 'P':if (mapa[sector][(dir+2)&3]!=-1) + { + sector=mapa[sector][(dir+2)&3]; + render_scene(sector,dir); + swap_buffs(); + if (!debug) zooming_backward(); + showview(0,0,0,0); + }break; + case 'M':dir=(dir+1)&3; + render_scene(sector,dir); + if (!debug) turn_left(); + swap_buffs(); + showview(0,0,0,0); + break; + case 'K':dir=(dir-1)&3; + render_scene(sector,dir); + swap_buffs(); + if (!debug) turn_right(); + showview(0,0,0,0); + break; + case ';':debug=!debug;break; + case '<':nosides=!nosides;break; + case '=':nofloors=!nofloors;break; + case '>':drwsit=!drwsit;break; + } + } + while (c!=1); + } +*/ +/*void ask_video(video) + { + char c,ok,er; + printf("\nJaky videomode?:\n" + " 1) 640x480x256 Pomale pocitace\n" + " 2) 640x480xHiColor Pomale pocitace\n" + " 3) 640x480x256 Rychle pocitace\n" + " 4) 640x480xHiColor Rychle pocitace\n"); + screen_buffer_size=640*480*2; + do + { + if (!video) c=_bios_keybrd(_KEYBRD_READ)>>8;else c=video+1; + ok=1;er=0; + line480=1; + switch (c) + { + case 1:exit(0); + case 4:line480=1;er=initmode256(load_file("xlat256.pal")); + zooming=zooming2;ok=0; + turn=turn2; + if (banking) + { + turn=turn5; + zooming=zooming5; + } + break; + case 5:line480=1;er=initmode32(); + zooming=zooming1;ok=0; + turn=turn1; + if (banking) + { + turn=turn4; + zooming=zooming4; + } + break; + case 2:line480=1;er=initmode256(load_file("xlat256.pal")); + zooming=zooming2;ok=0;zooming_step=2;rot_phases=2;rot_step=140; + turn=turn2; + if (banking) + { + turn=turn5; + zooming=zooming5; + } + break; + case 3:line480=1;er=initmode32(); + zooming=zooming1;ok=0;zooming_step=2;rot_phases=2;rot_step=140; + turn=turn1; + if (banking) + { + turn=turn4; + zooming=zooming4; + } + break; + } + if (er) + { + ok=1; + if (er==-1) + printf("Rezim zrejme neni podporovan. Zkuste nainstalovat univbe\n"); + else + printf("Graficka karta asi nepodporuje Linear Frame Buffer. \n" + "Pokud tomu tak neni, zkontrolujte zda neni vypnuty.\n"); + } + } + while (ok); + } + + */ +void report_mode(int mode) + { +/* switch (mode) + { + case 1:zooming=zooming1; turn=turn1;break; + case 2:STOP();break; + case 3:STOP();break; + case 4:STOP();break; + case 5:STOP();break; + case 6:STOP();break; + case 7:STOP();break; + }*/ + } + +__inline void clear_color(void *start,int _size,word _color) + { + word *s = (word *)start; + int i; + for (i = 0; i < _size; i++) s[i] = _color; +/* __asm + { + mov edi,start + mov ecx,_size + movzx eax,_color + mov ebx,eax + shl eax,16 + mov ax,bx + shr ecx,1 + rep stosd + rcl ecx,1 + rep stosw + }*/ + } + + //parm [EDI][ECX][EAX] modify [EBX]; + + +void clear_buff(word *background,word backcolor,int lines) +{ + if (background!=NULL) put_picture(0,SCREEN_OFFLINE,background);else lines=0; + if (lines!=360) + for (i=lines;i<360;i++) + clear_color(GetBuffer2nd()+SCREEN_OFFSET+scr_linelen2*i,640,backcolor); + +} + +void clear_screen(word *screen, word color) +{ +for (i=0;i<480;i++) clear_color(screen+scr_linelen2*i,640,color); +} + +void general_engine_init() + { + calc_points(); + create_tables(); + create_zooming(); + clear_screen(GetScreenAdr(),0); + clear_screen(GetBuffer2nd(),0); + screen_buffer_size=scr_linelen2*480*2; +} + +void map_pos(int celx,int cely,int posx,int posy,int posz,int *x,int *y) + { + char negate2=0; + int xl,xr; + int p1,p2,p; + if (celx<0) + { + negate2=1; + posx=CTVR-posx; + celx=-celx; + } + p1=(points[0][0][cely].y-points[0][1][cely].y); + p2=(points[0][0][cely+1].y-points[0][1][cely+1].y); + last_scale=p=posy*(p2-p1)/CTVR+p1; + *y=points[0][0][cely].y-(posy*(points[0][0][cely].y-points[0][0][cely+1].y)/CTVR)-p*posz/CTVR; + xr=points[celx][0][cely].x-(posy*(points[celx][0][cely].x-points[celx][0][cely+1].x)/CTVR); + if (celx) xl=points[celx-1][0][cely].x-(posy*(points[celx-1][0][cely].x-points[celx-1][0][cely+1].x)/CTVR); + else xl=-xr; + *x=xl+((xr-xl)*posx/CTVR); + if (negate2) *x=-*x; + *x+=MIDDLE_X; + *y+=MIDDLE_Y; + } + +/*void draw_item(int celx,int cely,int posx,int posy,short *pic,int index) + { + int x,y; + int xs,ys,xsr,ysr,xofs,xmax; + T_INFO_Y *yd; + T_INFO_X *x3d; + int ys1,ys2,xs1,xs2; + static long zoomtab_x[640]; + static short zoomtab_y[360]; + static lastcely=-1; + int randx,randy; + static int indextab[][2]={{0,0},{0,10},{1,0},{-1,0},{1,10},{-1,10},{-2,10},{2,10}}; + + if (pic==NULL) return; + if (!cely && !posy) return; + if (cely==VIEW3D_Z-1 && posy) return; + x3d=&showtabs.x_table[abs(celx)]; + if (!x3d[cely].used || !x3d[1].used ) return; + randx=indextab[index & 0x7][0]; + randy=indextab[index & 0x7][1]; + map_pos(celx,cely,64*posx+32+randx,64*posy+randy,0,&x,&y); + yd=&showtabs.y_table; + ys2=yd[1].vert_size; + xs2=x3d[1].point_total; + if (posy) + { + xs1=(x3d[cely].point_total+x3d[cely+1].point_total)>>1; + ys1=(yd[cely].vert_size+yd[cely+1].vert_size)>>1; + } + else + { + xs1=x3d[cely].point_total; + ys1=yd[cely].vert_size; + } + xs=pic[0]; + ys=pic[1]; + xsr=xs*ys1/ys2; + ysr=ys*xs1/xs2; + x-=xsr>>1; + //y+=ysr>>1; + if (-x>=xsr || x>VIEW_SIZE_X) return; + if (x<0) + { + xofs=-x*xs/xsr; + xmax=xsr+x; + x=0; + } + else if (x+xsr>VIEW_SIZE_X) + { + xofs=0; + xmax=VIEW_SIZE_X-x; + } + else + { + xofs=0; + xmax=xsr; + } + if ((cely<<1)+posy!=lastcely) + { + lastcely=(cely<<1)+posy; + calc_x_buffer((long *)&zoomtab_x,xs2,xs1,640,xs2); + calc_y_buffer((short *)&zoomtab_y,ys2,ys1,360); + } + if (y-ysr<0) ysr=y; + zoom.startptr=GetBuffer2nd()+y*640+x+SCREEN_OFFSET; + zoom.texture=(short *)((char *)(&pic[3+SHADE_PAL])+xofs); + zoom.texture_line=xs; + zoom.xtable=(long *)&zoomtab_x; + zoom.ytable=(short *)&zoomtab_y; + zoom.palette=(word *)&pic[3+cely*256+(secnd_shade?SHADE_STEPS*256:0)]; + zoom.ycount=ysr; + zoom.xmax=xmax; + zoom.line_len=1280; + sikma_zleva(); + } +*/ + +static int items_indextab[][2]={{0,0},{-1,3},{1,7},{-1,7},{1,10},{-1,10},{0,10},{-2,15}}; +void draw_item(int celx,int cely,int posx,int posy,short *txtr,int index) + { + int x,y; + int clipl,clipr; + int randx,randy; + + if (txtr==NULL) return; + randx=items_indextab[7-(index & 0x7)][0]; + randy=items_indextab[7-(index & 0x7)][1]; + map_pos(celx,cely,42*posx+42+randx,72*posy+randy,0,&x,&y); + x-=(txtr[0]/2*last_scale)/320; + if (x<0) + { + clipl=-x; + x=0; + } + else clipl=0; + clipr=640-x; + if (clipr>0) + enemy_draw(txtr,GetBuffer2nd()+x+(y+SCREEN_OFFLINE)*scr_linelen2,6+512*cely+(secnd_shade?SHADE_STEPS*512:0),last_scale,y,(clipr<<16)+clipl); + } + + +void put_textured_bar(void *src,int x,int y,int xs,int ys,int xofs,int yofs) + { + word *pos; + word *xy; + + pos=GetScreenAdr()+x+scr_linelen2*y; + xy=src; + xofs=xofs%xy[0]; + yofs=yofs%xy[1]; + if (xofs<0) xofs+=xy[0]; + if (yofs<0) yofs+=xy[1]; + put_textured_bar_(src,pos,xs,ys,xofs,yofs); + } + +void draw_placed_texture(short *txtr,int celx,int cely,int posx,int posy,int posz,char turn) + { + int x,y; + int clipl,clipr; + + if (txtr==NULL) return; + map_pos(celx,cely,posx,posy,posz,&x,&y); + x-=(txtr[0]/2*last_scale)/320; + y+=(txtr[1]/2*last_scale)/320; + if (y>400) y=400; + if (x<0) + { + clipl=-x; + x=0; + } + else clipl=0; + clipr=640-x; + if (clipr>0) + if (turn) enemy_draw_mirror(txtr,GetBuffer2nd()+x+(y+SCREEN_OFFLINE)*scr_linelen2,6+512*cely+(secnd_shade?SHADE_STEPS*512:0),last_scale,y,(clipr<<16)+clipl); + else enemy_draw(txtr,GetBuffer2nd()+x+(y+SCREEN_OFFLINE)*scr_linelen2,6+512*cely+(secnd_shade?SHADE_STEPS*512:0),last_scale,y,(clipr<<16)+clipl); + } + +/*void draw_placed_texture(short *txtr,int celx,int cely,int posx,int posy,int posz,char turn) + { + int x,y,xsr,ysr; + long zoomtab_x[640]; + short zoomtab_y[360]; + int xs,ys,xofs,xmax; + + map_pos(celx,cely,posx,posy,posz,&x,&y); + if (y>460-SCREEN_OFFLINE) return; + xs=txtr[0]; + xsr=xs*last_scale/320; + ys=txtr[1]; + ysr=ys*last_scale/320; + if (turn) x=VIEW_SIZE_X-x; + x-=xsr/2; + y+=ysr/2; + if (-x>=xsr || x>VIEW_SIZE_X) return; + if (x<0) + { + xofs=-x*xs/xsr; + xmax=xsr+x; + x=0; + } + else if (x+xsr>VIEW_SIZE_X) + { + xofs=0; + xmax=VIEW_SIZE_X-x; + } + else + { + xofs=0; + xmax=xsr; + } + calc_x_buffer((long *)&zoomtab_x,320,last_scale,640,last_scale); + calc_y_buffer((short *)&zoomtab_y,320,last_scale,360); + if (y-ysr<0) ysr=y; + if (ysr<=0) return; + if (turn) zoom.startptr=GetBuffer2nd()+y*640+(VIEW_SIZE_X-x)+SCREEN_OFFSET; + else zoom.startptr=GetBuffer2nd()+y*640+x+SCREEN_OFFSET; + zoom.texture=(short *)((char *)(&txtr[3+SHADE_PAL])+xofs); + zoom.texture_line=xs; + zoom.xtable=(long *)&zoomtab_x; + zoom.ytable=(short *)&zoomtab_y; + zoom.palette=(word *)&txtr[3+cely*256+(secnd_shade?SHADE_STEPS*256:0)]; + zoom.ycount=ysr; + zoom.xmax=xmax; + zoom.line_len=1280; + if (turn) sikma_zprava();else sikma_zleva(); + + } + */ + +void set_lclip_rclip(int celx,int cely,int lc,int rc) + { + int x,xs; + lclip=0; + rclip=640; + if (celx>=0) + { + if (rc) + { + x=points[celx][0][cely].x+MIDDLE_X; + xs=points[celx][0][cely].x-points[celx][0][cely+1].x; + rclip=x-rc*xs/TXT_SIZE_X_3D; + if (rclip>640) rclip=640; + } + if (celx>0 && lc) + { + lclip=points[celx-1][0][cely].x+MIDDLE_X; + if (lclip>rclip) lclip=rclip; + } + + } + if (celx<=0) + { + if (lc) + { + int cc=-celx; + x=-points[cc][0][cely].x+MIDDLE_X; + xs=points[cc][0][cely].x-points[cc][0][cely+1].x; + lclip=x+lc*xs/TXT_SIZE_X_3D; + if (lclip<0) lclip=0; + } + if (celx<0 && rc) + { + rclip=-points[(-celx)-1][0][cely].x+MIDDLE_X; + if (rclipstoned) + { + unsigned short *p=(unsigned short *)alloca(SHADE_PAL); + int i; + for (i=0;ipalette[0][i]; + int bw=(GET_R_COLOR(col)+GET_G_COLOR(col)+GET_B_COLOR(col))/3; + if (bw>255) bw=255; + p[i]=RGB(bw,bw,bw); + } + drw->palette=(palette_t *)p; + } + + posx=drw->posx; + posy=drw->posy; + cely=drw->cely; + if (drw->txtr==NULL) return; + posx+=64; + if (!(drw->shiftup & 0x8)) posy+=32; + if (drw->shiftup & 0x1) posy+=128; + if (posy<0 || posy>127) return; + map_pos(drw->celx,drw->cely,posx,posy,0,&x,&y); + xs=(short *)drw->txtr; + xss=*xs*last_scale/320; + if (xss>640) return; + ys=(short *)drw->txtr+1; + yss=*ys*last_scale/320; + lx=x; + grcel=cely; + if (posy>64) grcel++; + if (grcel) grcel--; + if (cely) cely-=1; + x-=(drw->adjust*last_scale)/320; + if (x0) + if (drw->mirror)enemy_draw_mirror_transp(drw->txtr,GetBuffer2nd()+x+(y+SCREEN_OFFLINE)*scr_linelen2,drw->palette+grcel+(secnd_shade?SHADE_STEPS:0),last_scale,y+1,(clipr<<16)+clipl); +else enemy_draw_transp(drw->txtr,GetBuffer2nd()+x+(y+SCREEN_OFFLINE)*scr_linelen2,drw->palette+grcel+(secnd_shade?SHADE_STEPS:0),last_scale,y+1,(clipr<<16)+clipl); + if (show_lives) + { + char s[25]; + + RedirectScreenBufferSecond(); + sprintf(s,"%d",drw->num); + sd=text_width(s)/2; + if (lx-sd>0 && lx+sd<639) + { + int ly=y+SCREEN_OFFLINE-last_scale*5/6; + trans_bar(lx-sd-5,ly-10,sd*2+10,10,0); + set_aligned_position(lx,ly,1,2,s);outtext(s); + } + RestoreScreen(); + } + } + +void draw_player(short *txtr,int celx,int cely,int posx,int posy,int adjust,char *name) + { + int x,y,yc,lx,sd; + int clipl,clipr; + + RedirectScreenBufferSecond(); + map_pos(celx,cely,posx+64,posy+64,0,&x,&y); + lx=x; + x-=(adjust*last_scale)/320; + yc=(20*last_scale)/320+y; + if (x<0) + { + clipl=-x; + x=0; + } + else clipl=0; + clipr=640-x; + if (clipr>0) + enemy_draw(txtr,GetBuffer2nd()+x+(yc+SCREEN_OFFLINE)*scr_linelen2,6+512*cely+(secnd_shade?SHADE_STEPS*512:0),last_scale,y,(clipr<<16)+clipl); + if (show_names && name!=NULL) + { + sd=text_width(name)/2; + if (lx-sd>0 && lx+sd<639) + { + int ly=y+SCREEN_OFFLINE-last_scale*5/6; + trans_bar(lx-sd-5,ly-10,sd*2+10,10,0); + set_aligned_position(lx,ly,1,2,name);outtext(name); + } + } + RestoreScreen(); + } + + +void draw_spectxtr(short *txtr,int celx,int cely,int xpos) + { + int x,y,lx,clipl,clipr; + map_pos(celx,cely,64,64,0,&x,&y); + lx=x; + x-=(((*txtr>>1)+xpos)*last_scale*2)/320; + if (x<0) + { + clipl=-x; + x=0; + } + else clipl=0; + clipr=640-x; + if (clipr>0) + enemy_draw_transp(txtr,GetBuffer2nd()+x+(y+SCREEN_OFFLINE)*scr_linelen2,(char *)txtr+6+512*cely+(secnd_shade?SHADE_STEPS*512:0),last_scale*2,y,(clipr<<16)+clipl); + } + + +void draw_item2(int celx,int cely,int xpos,int ypos,void *txtr,int index) + { + int x,y,xs,ys,ysc,abc,asc,clipl,clipr; + static int indextab[][2]={{0,0},{0,1},{1,0},{-1,0},{1,2},{-1,1},{-2,1},{2,1}}; + + celx--; + asc=(celx<0); + abc=abs(celx);if (asc) abc--; + x=points[abc][0][cely+1].x; + y=points[abc][0][cely+1].y; + xs=showtabs.x_table[0][cely].max_x; + ys=showtabs.y_table[cely+1].vert_size; + ysc=showtabs.y_table[cely].vert_size; + xpos+=indextab[7-index][0]; + ypos+=indextab[7-index][1]; + xpos-=*(word *)txtr/2; + xpos=xs*xpos/500; + ypos=ys*ypos/320; + if (asc) x=-x; + x+=MIDDLE_X; + y+=MIDDLE_Y; + x+=xpos; + y-=ypos; + if (x<0) + { + clipl=-x; + x=0; + } + else clipl=0; + clipr=640-x; + if (clipr>0) + enemy_draw(txtr,GetBuffer2nd()+x+(y+SCREEN_OFFLINE)*scr_linelen2,6+512*cely+(secnd_shade?SHADE_STEPS*512:0),ys,y,(clipr<<16)+clipl); + } + +/* +void main() + { + printf("%d\n",sizeof(showtabs)); + p=load_file("konvert\\bredy.hi"); + calc_points(); + create_tables(); + create_zooming(); + ask_video(); + put_picture(0,100,p);showview(0,0,0,0);free(p); + p2=load_file("konvert\\stena2.hi"); + p=load_file("konvert\\stena2bl.hi"); + strop=load_file("konvert\\strop1.hi"); + podlaha=load_file("konvert\\podlaha1.hi"); + sit=load_file("konvert\\sit.hi"); + build_map(); + render_scene(22,0);showview(0,0,0,0); + chozeni(); + closemode(); + } +*/ + + +int zoom_speed(int zoomspeed) + { + switch (zoomspeed) + { + case 0:zooming_step=0;break; + case 1:zooming_step=2;break; + case 2:zooming_step=1;break; + case -1: switch (zooming_step) + { + case 0:return 0; + case 1:return 2; + case 2:return 1; + } + } + return zoomspeed; + } + + +int turn_speed(int turnspeed) + { + switch (turnspeed) + { + case 0:rot_phases=0;break; + case 1:rot_phases=1;break; + case 2:rot_phases=2;break; + case -1: return rot_phases; + } + return rot_phases; + } + +void set_backgrnd_mode(int mode) + { + backgrnd_mode=mode; + } + +int get_item_top(int celx,int cely,int posx,int posy,word *txtr,int index) + { + int x,y; + int randx,randy; + + randx=items_indextab[7-(index & 0x7)][0]; + randy=items_indextab[7-(index & 0x7)][1]; + map_pos(celx,cely,42*posx+42+randx,72*posy+randy,0,&x,&y); + if (txtr!=NULL) return y-(txtr[1]*last_scale)/320+SCREEN_OFFLINE; + else return y+SCREEN_OFFLINE; + } diff --git a/GAME/ENGINE1.H b/GAME/ENGINE1.H new file mode 100644 index 0000000..be1dac0 --- /dev/null +++ b/GAME/ENGINE1.H @@ -0,0 +1,162 @@ +#ifndef __ENGINE1_H +#define __ENGINE1_H +#define VIEW_SIZE_X 640 +#define VIEW_SIZE_Y 360 +#define TAB_SIZE_X 640 +#define TAB_SIZE_Y 600 +#define MIDDLE_X 320 +#define MIDDLE_Y 112 +#define TXT_SIZE_Y 320 +#define TXT_SIZE_X_3D 74 +#define TXT_SIZE_X 500 +#define VIEW3D_X 4 +#define VIEW3D_Z 5 +#define START_X1 357 +#define START_Y1 305 +#define START_X2 357 +#define START_Y2 -150 +#define FACTOR_3D 3.33 +#define ZOOM_PHASES 9 +#define SCREEN_OFFLINE (17) +#define SCREEN_OFFSET (scr_linelen2*SCREEN_OFFLINE) +#define C_YMAP_SIZE 90 +#define F_YMAP_SIZE 199 +#define CF_XMAP_SIZE 7 + +#define SHADE_STEPS 5 +#define SHADE_PAL (SHADE_STEPS*512*2) + + +void general_engine_init(void); +void draw_floor_ceil(int celx,int cely,char f_c,void *txtr); +void show_cel2(int celx,int cely,void *stena,int xofs,int yofs,char rev); + //zobrazi primou stenu ktera lezi pred nebo napravo od pozorovatele +void show_cel(int celx,int cely,void *stena,int xofs,int yofs,char rev); + void turn_left(); +void turn_right(); +void zooming_backward(word *background); +void zooming_forward(word *background); +void OutBuffer2nd(void); +void CopyBuffer2nd(void); +void report_mode(int); +void draw_item(int celx,int cely,int posx,int posy,short *pic,int index); +void draw_item2(int celx,int cely,int xpos,int ypos,void *texture,int index); +//void textmode_effekt(); +//#pragma aux textmode_effekt modify[eax ebx ecx edx edi]; + + +void clear_buff(word *background,word backcolor,int lines); + +typedef struct zoominfo + { + void *startptr, *texture; + long texture_line,line_len; + long *xtable; + short *ytable; + word *palette; + word ycount; + word xmax; + }ZOOMINFO; + + +typedef struct t_info_y + { + long drawline; //ukazatel na radku na ktere bude stena zacinat + word vert_size; //konecna velikost steny, pokud ma pocatecni velikost TXT_SIZE_Y + word vert_total; //maximalni velikost textury aby jeste nepresahla obrazovku + short zoom_table[TAB_SIZE_Y]; //tabulka pro zoomovaci rutiny + }T_INFO_Y; + +typedef struct t_info_x_3d + { + char used; // 1 pokud je tato strana videt + integer xpos; //bod od leveho okraje + word txtoffset; //posunuti x vuci texture + word point_total; //rozdil mezi levym prednim a levym zadnim okrajem postranni steny (v adresach) + long zoom_table[VIEW_SIZE_X]; //zoomovaci tabulka pro osu x pro postranni steny + }T_INFO_X_3D; + +typedef struct t_info_x + { + char used; // 1 pokud je tato strana videt + integer xpos; //bod od leveho okraje + integer xpos2; //totez ale pro pravou stranu + word txtoffset; //posunuti x vuci texture + word max_x; //pocet viditelnych bodu z textury + word point_total; //celkovy pocet adres mezi levym a pravym okrajem + long zoom_table[VIEW_SIZE_X]; //zoomovaci tabulka pro osu x pro kolme steny + }T_INFO_X; + +typedef struct t_floor_map + { + long lineofs,linesize,counter,txtrofs; + }T_FLOOR_MAP; + +typedef struct all_view + { + T_INFO_Y y_table[VIEW3D_Z+1]; + T_INFO_X_3D z_table[VIEW3D_X][VIEW3D_Z]; + T_INFO_X x_table[VIEW3D_X][VIEW3D_Z+1]; + T_FLOOR_MAP f_table[CF_XMAP_SIZE][F_YMAP_SIZE]; + T_FLOOR_MAP c_table[CF_XMAP_SIZE][C_YMAP_SIZE]; + + }ALL_VIEW; + +typedef struct t_point + { + int x,y; + }T_POINT; + +typedef T_POINT t_points[VIEW3D_X+1][2][VIEW3D_Z+1]; +extern word *background; +extern t_points points; +extern int zooming_step; +extern int rot_phases; +extern int rot_step; +extern word *buffer_2nd; +extern char show_names; +extern char show_lives; +extern char secnd_shade; + +typedef short palette_t[256]; + +typedef struct drw_enemy_struct + { + void *txtr; + int celx,cely,posx,posy,adjust,shiftup,num; + char mirror; + char stoned; + palette_t *palette; + }DRW_ENEMY; + + + + +void enemy_draw(void *src,void *trg,int shade,int scale,int maxspace,int clip); +//#pragma aux enemy_draw parm[ESI][EDI][EBX][EDX][EAX][ECX] +void enemy_draw_transp(void *src,void *trg,void *shade,int scale,int maxspace,int clip); +//#pragma aux enemy_draw_transp parm[ESI][EDI][EBX][EDX][EAX][ECX] +void enemy_draw_mirror_transp(void *src,void *trg,void *shade,int scale,int maxspace,int clip); +//#pragma aux enemy_draw_mirror_transp parm[ESI][EDI][EBX][EDX][EAX][ECX] +void enemy_draw_mirror(void *src,void *trg,int shade,int scale,int maxspace,int clip); +//#pragma aux enemy_draw_mirror parm[ESI][EDI][EBX][EDX][EAX][ECX] +//clip je v poradi vpravo - vlevo (HiLo) + +void draw_enemy(DRW_ENEMY *drw); +void draw_player(short *txtr,int celx,int cely,int posx,int posy,int adjust,char *name); + +void set_lclip_rclip(int celx,int cely,int lc,int rc); +void draw_spectxtr(short *txtr,int celx,int cely,int xpos); + +int turn_speed(int turnspeed); //oba je nutne volat na zacatku +int zoom_speed(int zoomspeed); + +void scroll_and_copy(void *pic,void *slide, void *scr, int size,int shift, void *lineinfo); +//#pragma aux scroll_and_copy parm[esi][ebx][edi][ecx][edx][eax] + +void set_backgrnd_mode(int mode); + +int get_item_top(int celx,int cely,int posx,int posy,word *txtr,int index); + //vraci nejnizsi souradnici y predmetu leziciho na zemi v celx, cely na pozici posx,posy; + +#endif diff --git a/GAME/ENGINE2.ASM b/GAME/ENGINE2.ASM new file mode 100644 index 0000000..bea9b89 --- /dev/null +++ b/GAME/ENGINE2.ASM @@ -0,0 +1,2188 @@ +.model small +.386 + +DGROUP group _DATA + +tzoom struc + startptr DD ? ;0 + texture DD ? ;4 + textline DD ? ;8 + linelen DD ? ;12 + xtable DD ? ;16 + ytable DD ? ;20 + palette DD ? ;24 + ycount DW ? ;28 + xmax DW ? +tzoom ends + +extrn _zoom:dword [8] +extrn _lbuffer:dword +extrn _screen:dword +extrn _gran_mask:dword +extrn _lastbank:dword + +_TEXT segment byte public 'CODE' use32 + assume CS:_TEXT + assume DS:DGROUP + +extrn mapvesaadr_:proc +extrn switchmap_:proc +extrn switchvesabank_:proc + + public sikma_zleva_ +sikma_zleva_: + mov edi,_zoom ;nacti ukazatel do obrazovky + mov ebx,_zoom[offset tzoom.palette] ;ukazatel na paletu + mov cx,word ptr _zoom[offset tzoom.ycount] ;velikost textury na y + shl ecx,16 ;vloz do horni pulky ecx + mov esi,_zoom[offset tzoom.texture] ;nacti ukazatel na texturu +skzl3: mov edx,_zoom[offset tzoom.xtable] ;nacti ukazetel na zvetsovaci tabulku x + push esi ;uchovej esi + push edi ;uchovej edi + mov cx,_zoom[offset tzoom.xmax] +skzl1: xor eax,eax ;vynuluj eax pro spravny vypocet + lodsb ;nacti bod + add esi,[edx] ;posun se od nekolik pozic v texture podle hodnoty v tabulce x + add edx,4 ;posun se v tabulce x o dalsi polozku + or al,al ;test bodu na nulu + jz skz1 ;preskoc transparetni barvu + cmp al,1 ;test bodu na jedna + jz skz2 ;ukonci kresleni linky pokud narazi na 1 + mov ax,[eax*2+ebx] ;konverze barvy podle palety + mov [edi],ax ;nakresli bod na obrazovce +skz1: add edi,2 ;dalsi pozice + dec cx + jnz skzl1 ;opakuj dokola +skz2: pop edi ;obnov edi + pop esi ;obnov esi + mov edx,_zoom[offset tzoom.ytable] ;vyzvedni ukazatel na ytable + mov cx,[edx] ;cx - o kolik pozic se mam v texture posunout dolu + or cx,cx + jz skzskp +skzl2: add esi,_zoom[offset tzoom.textline] ;posun o jednu pozici + dec cx ;sniz citac + jnz skzl2 ;dokud neni nula +skzskp:add edx,2 ;dalsi hodnota v tabulce + mov _zoom[offset tzoom.ytable],edx ;uloaz na puvodni misto + sub edi,_zoom[offset tzoom.linelen] ;odecti tolik, kolik odpovida lince na obrazovce + sub ecx,10000h ;sniz horni pulku ecx o jedna + jnz skzl3 ;opakuj dokud neni nula + ret + + public sikma_zprava_ +sikma_zprava_: + mov edi,_zoom ;nacti ukazatel do obrazovky + mov ebx,_zoom[offset tzoom.palette] ;ukazatel na paletu + mov cx,word ptr _zoom[offset tzoom.ycount] ;velikost textury na y + shl ecx,16 ;vloz do horni pulky ecx + mov esi,_zoom[offset tzoom.texture] ;nacti ukazatel na texturu +skzp3: mov edx,_zoom[offset tzoom.xtable] ;nacti ukazetel na zvetsovaci tabulku x + push esi ;uchovej esi + push edi ;uchovej edi + mov cx,_zoom[offset tzoom.xmax] +skzp1: xor eax,eax ;vynuluj eax pro spravny vypocet + lodsb ;nacti bod + add esi,[edx] ;posun se od nekolik pozic v texture podle hodnoty v tabulce x + add edx,4 ;posun se v tabulce x o dalsi polozku + or al,al ;test bodu na nulu + jz skz3 ;preskoc transparetni barvu + cmp al,1 ;test bodu na jedna + jz skz4 ;ukonci kresleni linky pokud narazi na 1 + mov ax,[eax*2+ebx] ;konverze barvy podle palety + mov [edi],ax ;nakresli bod na obrazovce +skz3: sub edi,2 ;dalsi pozice + dec cx + jnz skzp1 ;opakuj dokola +skz4: pop edi ;obnov edi + pop esi ;obnov esi + mov edx,_zoom[offset tzoom.ytable] ;vyzvedni ukazatel na ytable + mov cx,[edx] ;cx - o kolik pozic se mam v texture posunout dolu + or cx,cx + jz skpskp +skzp2: add esi,_zoom[offset tzoom.textline] ;posun o jednu pozici + dec cx ;sniz citac + jnz skzp2 ;dokud neni nula +skpskp: add edx,2 ;dalsi hodnota v tabulce + mov _zoom[offset tzoom.ytable],edx ;uloaz na puvodni misto + sub edi,_zoom[offset tzoom.linelen] ;odecti tolik, kolik odpovida lince na obrazovce + sub ecx,10000h ;sniz horni pulku ecx o jedna + jnz skzp3 ;opakuj dokud neni nula + ret + + + public zooming32_ +zooming32_: + ;esi - zdrojovy blok + ;edi - cil + ;eax - pozadi + ;zoom.xtable - tabulka pro x + ;zoom.xtable - tabulka pro y + ;zoom.textline - rozdil mezi pravym okrajem a levym okrajem + ; pri prechodu na novou radku + ;ecx ysize:xsize + push ebp + mov ebp,eax + mov ebx,_zoom[offset tzoom.ytable] +z32d: push cx + mov edx,_zoom[offset tzoom.xtable] + push esi +z32c: mov al,[edx] + inc edx + or al,al + jz z32a + lodsw + test ax,8000h + jnz z32e + stosw + stosw + jmp z32b +z32f: test eax,8000h + jz z32g + test eax,80000000h + jz z32h +z32e: mov eax,[ds:ebp] + stosd + jmp z32b +z32g: rol eax,16 + mov ax,[ds:ebp+2] + rol eax,16 + stosd + jmp z32b +z32h: mov ax,[ds:ebp] + stosd + jmp z32b +z32a: lodsd + test eax,80008000h + jnz z32f + stosd +z32b: add ebp,4 + dec cx + jnz z32c + pop esi + mov eax,[ebx] + and eax,0ffffh + add esi,eax + add ebx,2 + add edi,_zoom[offset tzoom.textline] + xor cx,cx + sub ecx,10000h + pop cx + jnz z32d + pop ebp + ret + + public zooming32b_ +zooming32b_: + ;esi - zdrojovy blok + ;edi - cil + ;zoom.xtable - tabulka pro x + ;zoom.ytable - tabulka pro y + ;zoom.textline - rozdil mezi pravym okrajem a levym okrajem + ; pri prechodu na novou radku + ;ecx ysize:xsize + ;zoom.ycount - interni (ulozeni maskovane adr stranky) + ;zoom.xmax - interni (pocet dwordu do prepnuti) + ;zoom.linelen - interni (velikost stranky v dwordech) + + + call mapvesaadr_ ;mapuj spravne edi + push ebp + mov ebp,eax + mov ebx,_zoom[offset tzoom.ytable] +z32bd: push cx + mov edx,_zoom[offset tzoom.xtable] + push esi + push edi +z32bc: mov al,[edx] + inc edx + or al,al + jz z32ba + lodsw + test ax,8000h + jnz z32be + stosw + stosw + jmp z32bb +z32bf: test eax,8000h + jz z32bg + test eax,80000000h + jz z32bh +z32be: mov eax,[ds:ebp] + stosd + jmp z32bb +z32bg: rol eax,16 + mov ax,[ds:ebp+2] + rol eax,16 + stosd + jmp z32bb +z32bh: mov ax,[ds:ebp] + stosd + jmp z32bb +z32ba: lodsd + test eax,80008000h + jnz z32bf + stosd +z32bb: add ebp,4 + movzx eax,di ;prevezmi dolni cast edi do eax + dec eax ;odecti 1 (0=0xffffffff) + cmp eax,_gran_mask ;je vetsi nez granualita? + jc z32gb ;ne, vse je ok + mov eax,_lastbank ;ano, pak vem cislo banky + inc eax ;pricti 1 + mov _lastbank,eax ;zapis jako nove cislo banky + pushad ;uchovej vse + call switchvesabank_ ;prepni banku + popad ;obnov vse + mov edi,0a0000h ;vynuluj dolni cast di +z32gb: dec cx ;tady pokracujem + jnz z32bc ;opakuj cxkrat + pop edi ;obnov edi + add di,1280 ;pricti radek + and di,word ptr _gran_mask ;maskuj granualitou + pop esi + mov eax,[ebx] + and eax,0ffffh + add esi,eax + add ebx,2 + xor cx,cx + sub ecx,10000h + pop cx + jnz z32bd + pop ebp + ret + + + + public zooming_lo_ +zooming_lo_: + ;esi - zdrojovy blok + ;edi - cil + ;zoom.xtable - tabulka pro x + ;zoom.xtable - tabulka pro y + ;zoom.textline - rozdil mezi pravym okrajem a levym okrajem + ; pri prechodu na novou radku + ;ecx ysize:xsize + ;ebx xlat + push ebp + mov bp,cx +zlod: mov cx,bp + mov edx,_zoom[offset tzoom.xtable] + push esi +zloc: xor eax,eax + mov al,[edx] + inc edx + or al,al + jz zloa + lodsw + mov eax,[ebx+eax*2] + stosb + jmp zlob +zloa: lodsw + mov eax,[ebx+eax*2] + stosb + add esi,2 +zlob: dec cx + jnz zloc + pop esi + mov edx,_zoom[offset tzoom.ytable] + mov eax,[edx] + shl eax,1 + and eax,0ffffh + add esi,eax + add edx,2 + mov _zoom[offset tzoom.ytable],edx + add edi,_zoom[offset tzoom.textline] + xor cx,cx + sub ecx,20000h + jnz zlod + pop ebp + ret + + public zooming256_ +zooming256_: + ;esi - zdrojovy blok + ;edi - cil + ;eax - pozadi + ;zoom.xtable - tabulka pro x + ;zoom.xtable - tabulka pro y + ;zoom.textline - rozdil mezi pravym okrajem a levym okrajem + ; pri prechodu na novou radku + ;ecx ysize:xsize + ;ebx xlat + push ebp + mov ebp,eax +z256d: push cx + mov edx,_zoom[offset tzoom.xtable] + push esi +z256c: xor eax,eax + mov al,[edx] + inc edx + or al,al + jz z256a + lodsw + test eax,8000h + jnz z256e + mov al,[ebx+eax*2] + mov ah,al + stosw + jmp z256b +z256e: mov ax,[ds:ebp] + and eax,7fffh + mov al,[ebx+eax*2] + stosb + mov ax,[ds:ebp+2] + and eax,7fffh + mov al,[ebx+eax*2] + stosb + jmp z256b +z256g: mov ax,[ds:ebp] + and eax,7fffh + mov al,[ebx+eax*2] + stosb + jmp z256h +z256i: mov ax,[ds:ebp+2] + and eax,7fffh + mov al,[ebx+eax*2] + stosb + jmp z256b +z256a: lodsw + test eax,8000h + jnz z256g + mov al,[ebx+eax*2] + stosb +z256h: lodsw + test eax,8000h + jnz z256i + mov al,[ebx+eax*2] + stosb +z256b: add ebp,4 + xor ebx,1 + dec cx + jnz z256c + xor ebx,1 + pop esi + mov edx,_zoom[offset tzoom.ytable] + mov eax,[edx] + and eax,0ffffh + add esi,eax + add edx,2 + mov _zoom[offset tzoom.ytable],edx + add edi,_zoom[offset tzoom.textline] + xor cx,cx + sub ecx,10000h + pop cx + jnz z256d + pop ebp + ret + +swap_at_end macro reg16,reg32 + local sw1,sw2 + +sw2: movzx eax,reg16 ;nacti 16 bitovou cast registru + dec eax ;sniz ke kontrole o 1 + cmp eax,_gran_mask ;kontrola zda je vetsi nebo rovny masce + jc sw1 ;kdyz ne tak preskoc na sw1 + mov eax,_lastbank ;vem cislo banky + inc eax ;pricti jednicku + mov _lastbank,eax ;vloz zpatky do banky + pushad + call switchvesabank_ ;prepni banku + popad + sub reg32,_gran_mask ;odecti delku stranky od cele adresy + dec reg32 +sw1: +endm + + + public zooming256b_ +zooming256b_: + ;esi - zdrojovy blok + ;edi - cil + ;zoom.xtable - tabulka pro x + ;zoom.xtable - tabulka pro y + ;zoom.textline - rozdil mezi pravym okrajem a levym okrajem + ; pri prechodu na novou radku + ;ecx ysize:xsize + ;ebx xlat + push ebp + mov ebp,eax +z256bd: push cx + mov edx,_zoom[offset tzoom.xtable] + push edi + call mapvesaadr_ + push esi +z256bc: xor eax,eax + mov al,[edx] + inc edx + or al,al + jz z256ba + lodsw + test eax,8000h + jnz z256be + mov al,[ebx+eax*2] + mov ah,al + stosw + jmp z256bb +z256be: mov ax,[ds:ebp] + and eax,7fffh + mov al,[ebx+eax*2] + stosb + mov ax,[ds:ebp+2] + and eax,7fffh + mov al,[ebx+eax*2] + stosb + jmp z256bb +z256bg: mov ax,[ds:ebp] + and eax,7fffh + mov al,[ebx+eax*2] + stosb + jmp z256bh +z256bi: mov ax,[ds:ebp+2] + and eax,7fffh + mov al,[ebx+eax*2] + stosb + jmp z256bb +z256ba: lodsw + test eax,8000h + jnz z256bg + mov al,[ebx+eax*2] + stosb +z256bh: lodsw + test eax,8000h + jnz z256bi + mov al,[ebx+eax*2] + stosb +z256bb: add ebp,4 + swap_at_end di,edi + xor ebx,1 + dec cx + jnz z256bc + xor ebx,1 + pop esi + pop edi + add edi,640 + mov edx,_zoom[offset tzoom.ytable] + mov eax,[edx] + and eax,0ffffh + add esi,eax + add edx,2 + mov _zoom[offset tzoom.ytable],edx + add edi,_zoom[offset tzoom.textline] + xor cx,cx + sub ecx,10000h + pop cx + jnz z256bd + pop ebp + ret + +; public scroll_left_ +;scroll_left_: ;edi - kam +; ;lbuffer - obrazovka +; ;zoom.startptr - novy obsah obrazovky +; ;ebx - xlat +; ;eax - o_kolik +; mov bx,ax ;horni pulka ebx vi o kolik se posunuje vlevo +; rol ebx,16 +; mov edx,640 ;dolni pulka ebx vi, jak velky blok je presouvan +; sub edx,eax +; sub edx,2 + ; mov bx,dx + ; mov esi,edi ;vypocet esi + ; shl eax,1 ;esi = edi + 2 * o_kolik; + ; add esi,eax + ; mov edx,360 ;napln citac edx cislem udavajici pocet radku + ; add edi,_lbuffer ;k edi na zacatku pricti hodnotu _lbuffer + ; mov eax,esi ;uchovej esi v eax, behem prenosu bude modifikovan +;scrl1: add esi,_lbuffer ;pricti k esi zacatek obrazovky +; xor ecx,ecx ;vynuluj ecx +; mov cx,bx ;do ecx naladuj delku bloku +; shr ecx,1 ;presun 32-bit +; rep movsd +; adc ecx,1 +;; rep movsw +; mov esi,_zoom ;vem ukazatel na novy obsah +; mov ecx,ebx ;vezmi horni pulku EBx +; shr ecx,16 ;to je hodnota, kolik se ma v prava doplnit +; shr ecx,1 ;presun 32-bit +; rep movsd + ; adc ecx,1 + ; rep movsw + ; add _zoom,640*2 ;dalsi radka + ;; add eax,640*2 ;dalsi radka +; mov esi,eax +; dec edx ;dokud neni konec + ; jnz scrl1 + ; ret + ; + +public scroll_support_32_ +scroll_support_32_: + ;edi - lbuffer + pozice na obrazovce + ;esi - oldbuffer + ;edx - newbuffer + ;ebx - xlat + ;ecx - size; + push ebp ;uchovej ebp + mov ebp,360 ;ebp pro tuto chvili predstavuje citac + mov eax,ecx ;uchovej ecx jeste v eac - zachova citac sloupcu +scrl1: push esi ;uchovej esi + shr ecx,1 ;presun ecx bloku + rep movsd + rcl ecx,1 + rep movsw + mov ecx,640 ;dopocitej ecx do 640 + sub ecx,eax + pop esi ;obnov esi + xchg esi,edx ;esi je nyni novy blok + push esi ;uchovek esi + shr ecx,1 ;presun + rep movsd + rcl ecx,1 + rep movsw + pop esi ;obnov esi + xchg esi,edx ;vrat edx a esi do puvodniho stavu + mov ecx,eax ;obnov zase ecx z eax + add esi,1280 ;dalsi radek + add edx,1280 + dec ebp ; dokud nejsme na konci + jnz scrl1 ;opakuj + pop ebp + ret + +movsdx macro ;presun do videopameti s kontrolou na banky + local sw1,konec + push eax + movzx eax,di + add eax,ecx + cmp eax,_gran_mask + ja sw1 + shr ecx,2 + rep movsd + jmp konec +sw1: mov eax,_gran_mask + sub ax,di + inc eax + sub ecx,eax + xchg eax,ecx + shr ecx,2 + rep movsd + xchg eax,ecx + mov eax,_lastbank + inc eax + mov _lastbank,eax + pushad + call switchvesabank_ + popad + mov edi,0a0000h + shr ecx,2 + rep movsd +konec: pop eax +endm +public scroll_support_32b_ +scroll_support_32b_: + ;edi - lbuffer + pozice na obrazovce /pokud mozno del 4 + ;esi - oldbuffer + ;edx - newbuffer + ;ebx - xlat + ;ecx - size pokud mozno / 4; + call mapvesaadr_ ;mapuj spravne edi + push ebp ;uchovej ebp + mov ebp,360 ;ebp pro tuto chvili predstavuje citac + and ecx,not 1 + shl ecx,1 ;korekce ecx na delitele 4x + mov eax,ecx ;uchovej ecx jeste v eax - zachova citac sloupcu +scrl1b: push esi ;uchovej esi + movsdx ;presun ecx bajtu (jen ctverice) + mov ecx,1280 ;dopocitej ecx do 640 + sub ecx,eax + pop esi ;obnov esi + xchg esi,edx ;esi je nyni novy blok + push esi ;uchovek esi + movsdx + pop esi ;obnov esi + xchg esi,edx ;vrat edx a esi do puvodniho stavu + mov ecx,eax ;obnov zase ecx z eax + add esi,1280 ;dalsi radek + add edx,1280 + dec ebp ; dokud nejsme na konci + jnz scrl1b ;opakuj + pop ebp + ret + + +public scroll_support_256_ +scroll_support_256_: + ;edi - lbuffer + pozice na obrazovce + ;esi - oldbuffer + ;edx - newbuffer + ;ebx - xlat + ;ecx - size; + push ebp ;uchovej ebp + mov ebp,360 ;ebp pro tuto chvili predstavuje citac +scrl1a: push ecx ;uchovej ecx jeste v eac - zachova citac sloupcu + push esi ;uchovej esi +scrl2a: lodsw + and eax,7fffh + mov al,[ebx+2*eax] + xor ebx,1 + stosb + dec ecx + jnz scrl2a + pop esi + xchg esi,edx ;esi je nyni novy blok + pop eax + mov ecx,640 ;dopocitej ecx do 640 + sub ecx,eax + push eax + push esi ;uchovek esi +scrl3a: lodsw + and eax,7fffh + mov al,[ebx+2*eax] + xor ebx,1 + stosb + dec ecx + jnz scrl3a + pop esi ;obnov esi + xchg esi,edx ;vrat edx a esi do puvodniho stavu + pop ecx ;obnov zase ecx z eax + add esi,1280 ;dalsi radek + add edx,1280 + xor ebx,1 + dec ebp ; dokud nejsme na konci + jnz scrl1a ;opakuj + pop ebp + ret + +public scroll_support_256b_ +scroll_support_256b_: + ;edi - lbuffer + pozice na obrazovce + ;esi - oldbuffer + ;edx - newbuffer + ;ebx - xlat + ;ecx - size; + call mapvesaadr_ + push ebp ;uchovej ebp + mov eax,360 ;eax pro tuto chvili predstavuje citac + mov ebp,edx +scrl1ba:push eax + push ecx ;uchovej ecx jeste v eac - zachova citac sloupcu + push esi ;uchovej esi + xor eax,eax + shr ecx,1 +scrl2ba:lodsw + and eax,7fffh + mov dl,[ebx+2*eax] + xor ebx,1 + lodsw + and eax,7fffh + mov dh,[ebx+2*eax] + xor ebx,1 + mov [edi],dx + add edi,2 + swap_at_end di,edi + dec ecx + jnz scrl2ba + pop esi + xchg esi,ebp ;esi je nyni novy blok + pop eax + mov ecx,640 ;dopocitej ecx do 640 + sub ecx,eax + push eax + push esi ;uchovek esi + xor eax,eax + shr ecx,1 +scrl3ba:lodsw + and eax,7fffh + mov dl,[ebx+2*eax] + xor ebx,1 + lodsw + and eax,7fffh + mov dh,[ebx+2*eax] + xor ebx,1 + mov [edi],dx + add edi,2 + swap_at_end di,edi + dec ecx + jnz scrl3ba + pop esi ;obnov esi + xchg esi,ebp ;vrat ebp a esi do puvodniho stavu + pop ecx ;obnov zase ecx z eax + pop eax + add esi,1280 ;dalsi radek + add ebp,1280 + xor ebx,1 + dec eax ; dokud nejsme na konci + jnz scrl1ba ;opakuj + pop ebp + ret + + + +public fcdraw_ ;Kresli strop nebo podlahu podle draw_table + ;EDX - sourceTxt + ;EBX - TargerTxt - LineOfset + ; (Lineofs je pocet bajtu odpovidajici + ; souradnicim [0,184] pro podlahu nebo [0,0] + ; pro strop) + ;EAX - draw_table +fcdraw_:mov esi,[eax] + mov edi,esi + add edi,ebx + add esi,edx + mov ecx,[eax+4] + shr ecx,1 + rep movsd + rcl ecx,1 + rep movsw + mov ecx,[eax+8] + add eax,12 + or ecx,ecx + jnz fcdraw_ + ret + +public put_image_ ;vlozi obrazek v hicolor +put_image_: ;ESI - obrazek + ;EDI - obrazovka + ;EAX - startline + ;EBX - velikostx + ;EDX - velikosty + shl eax,1 + xor ecx,ecx + mov cx,[esi] + imul eax,ecx + add esi,eax + add esi,6 + mov eax,ecx +puti_lp:mov ecx,ebx + shr ecx,1 + rep movsd + rcl ecx,1 + rep movsw + mov ecx,eax + sub ecx,ebx + add esi,ecx + sub edi,ebx + sub edi,ebx + add edi,1280 + dec edx + jnz puti_lp + ret + +public put_8bit_clipped_ ;vlozi 8bit obrazek omezen velikosti +put_8bit_clipped_: ;ESI - obrazek + ;EDI - obrazovka + ;EAX - startline + ;EBX - velikostx + ;EDX - velikosty + + push ebp + mov ebp,ebx + xor ecx,ecx + mov cx,[esi] + imul eax,ecx + lea ebx,[esi+6]; + add esi,6+512 + add esi,eax + mov eax,ecx +put8_lp:mov ecx,ebp + push eax +put8lp2:xor eax,eax + lodsb + or eax,eax + jz put8_trns + mov eax,[ebx+eax*2] + stosw +put8nxt:dec ecx + jnz put8lp2 + pop eax + mov ecx,eax + sub ecx,ebp + add esi,ecx + sub edi,ebp + sub edi,ebp + add edi,1280 + dec edx + jnz put8_lp + pop ebp + ret +put8_trns: + add edi,2 + jmp put8nxt + +public textmode_effekt_ + +textmode_effekt_: ;genetuje effekt v textovem rezimu + mov edx,3c4h + mov eax,0402h + out dx,ax + mov eax,0704h + out dx,ax + Mov edx,3ceh + mov eax,0204h + out dx,ax + mov eax,0005h + out dx,ax + mov eax,0406h + out dx,ax + mov bl,8 + xor bh,bh +tde2: mov edi,0xA0000h + mov ecx,32*256 +tde1: not bh + or bh,bh + jz tde3 + shr byte ptr [edi],1 + jmp tde4 +tde3: shl byte ptr [edi],1 +tde4: inc edi + dec ecx + jnz tde1 + mov edx,0x3da + mov bh,3 +tdew2: in al,dx + and al,8 + jz tdew2 +tdew1: in al,dx + and al,8 + jnz tdew1 + dec bh + jnz tdew2 + dec bl + jnz tde2 + mov edx,3c4h + mov eax,0302h + out dx,ax + mov eax,0304h + out dx,ax + Mov edx,3ceh + mov eax,0004h + out dx,ax + mov eax,1005h + out dx,ax + mov eax,0E06h + out dx,ax + ret + +public put_textured_bar__ + ;zobrazi texturovany obdelnik tvoreny cyklickou texturou + ;vstup + ; EDI - pozice na obrazovce + ; EBX - textura + ; ECX - velikosty + ; EDX - velikostx + ; EAX - yofs + ; ESI - xofs + +put_textured_bar__: + push ebp ;uchovej EBP - bude pouzit jako univerzalni registr + mov ebp,eax ;zacneme o EAX radku v texture niz + shl edx,16 ;nachvili uchovej dx v horni pulce + mul word ptr [ebx] ;zjisti pocatecni adresu v texture + shl eax,16 + shrd eax,edx,16 ;EAX=AX*word ptr[ebx] + shr edx,16 + xchg esi,eax ;napln esi pocatkem + lea esi,[esi+512] ;vypocti zacatek v texture+xlat + lea ebx,[ebx+6] ;postav ebx na zacatek xlat + add esi,ebx ;pricti zacatek textury + add esi,eax ;pricti k ukazateli ofset v x +ptb_l2: push eax ;uchovej xofset + push edx ;uchovej velikost v x + push esi ;uchovej zacatek radky v texture + shl ebp,16 ;odsun citac offset do horni pulky ebp + add bp,ax ;pricti k bp offset v x +ptb_l1: xor eax,eax ;pred kazdym bodem vynuluj eax + lodsb ;nacti barvu + or al,al + jz ptb_s1 + mov ax,[ebx+eax*2];vyhledej barvu v palete + mov [edi],ax ;zapis hicolor barvu +ptb_s1: add edi,2 + inc bp ;zvys counter v x + cmp bp,[ebx-6] ;byl dosazen pravy roh textury? + jc ptb_skip1 ;ne pokracuj + mov ax,bp ;nacti eax counterem + sub esi,eax ;odexti to cele od esi - tj spatky doleva + xor bp,bp +ptb_skip1: + dec edx + jnz ptb_l1 + shr ebp,16 ;vrat counter pro y + pop esi ;obnov pocatek v texture + mov ax,[ebx-6] ;nalouduj do eax delku x (horni pulka je zarucene prazdna) + add esi,eax ;pricti k esi + inc ebp ;zvys y counter + cmp bp,[ebx-4] ;test zda jsme dosahli dolniho rohu textury + jc ptb_skip2 ;ne pokracuj + mov eax,ebp ;ano nalouduj eax + mul word ptr [ebx-6];vynasob ho delkou v x + shl eax,16 + shrd eax,edx,16 ;eax=ax*word ptr [ebx-4] + sub esi,eax ;jsme na zacatku + xor ebp,ebp +ptb_skip2: + pop edx ;obnov zbyvajici registry + pop eax + lea edi,[edi+1280] ;presun se na dalsi radek na obrazovky + sub edi,edx + sub edi,edx + dec ecx ;odecti 1 od globalniho citace radek + jnz ptb_l2 ;konec velke smycky + POP EBP + ret + +public trans_bar_ ;kresli transparetni pravouhelnik ucite barvy + ;EDI - X + ;ESI - Y + ;ECX - YS + ;EDX - XS bere se nejmensi sude cislo + ;EBX - BARVA +trans_bar_: + mov eax,1280 + imul eax,esi + shl edi,1 + add edi,eax + add edi,_screen + mov eax,ebx + shl eax,16 + shld ebx,eax,16 + and ebx,7bde7bdeh +trs_l2: mov esi,edi + push edx + shr edx,1 +trs_l1: lodsd + and eax,7bde7bdeh + add eax,ebx + shr eax,1 + stosd + dec edx + jnz trs_l1 + pop edx + add edi,1280 + sub edi,edx + sub edi,edx + dec ecx + jnz trs_l2 + ret + +public trans_line_x_ + ;EDI - X + ;ESI - Y + ;ECX - XS + ;EDX - COLOR +trans_line_x_: + mov eax,1280 + imul eax,esi + shl edi,1 + add edi,eax + add edi,_screen + mov esi,edi + mov eax,edx + shl eax,16 + shld edx,eax,16 + and edx,7bdf7bdfh + ror ecx,1 +trlx_l: lodsd + and eax,7bdf7bdfh + add eax,edx + shr eax,1 + stosd + dec cx + jnz trlx_l + shl ecx,1 + jnc trlx_s + lodsw + and eax,7bdf7bdfh + add eax,edx + shr eax,1 + stosw +trlx_s: ret + +public trans_line_y_ + ;EDI - X + ;ESI - Y + ;ECX - YS + ;EDX - COLOR +trans_line_y_: + mov eax,1280 + imul eax,esi + shl edi,1 + add edi,eax + add edi,_screen + mov esi,edi + and edx,7bdfh +trly_l: mov ax,[esi] + and eax,7bdfh + add eax,edx + shr eax,1 + mov [esi],ax + add esi,1280 + dec ecx + jnz trly_l + ret + + +pic_start equ 2+2+2+512*5+512*5 +ed_stack equ 640*4+480*4 +ed_stk1 equ 480*4 + +public enemy_draw_ +enemy_draw_: ;ESI - Source_picture + ;EDI - Target + ;EBX - Offset of palette + ;EDX - scale (1-320) + ;EAX - max_space (kolik ma nahore mista) + ;ECX - Hi_omezeni z prava, Lo_omezeni zleva + + cmp eax,470 + jc ed_ok1 + ret +ed_ok1: push ebp + sub esp,ed_stack ;vyhrad zasobnik + mov ebp,esp + push ecx ;uchovej ecx +1 + push edi ;uchovej edi +2 + push ebx ;uchovej ebx +3 + mov ebx,eax ;volne misto je ted v ebx + mov edi,ebp ;nastav edi na zacatek tabulek + push ebp ; +4 + movzx ecx,word ptr[esi] ;precti xs + movzx eax,word ptr[esi+2] ;precti ys + imul eax,ecx ;xs*ys + sub eax,ecx ;minus 1 radek + xor ebp,ebp +ed_lp1b:stosd ;zapis hodnotu do tabulky + add ebp,320 ;zmensovani +ed_lp1a:cmp ebp,edx + jc ed_nxt1 ;pri ebp=velikosti obrazku tak konec + jc ed_lp2a + xor eax,eax + dec eax ;zapis -1 na konec tabulky + pop ebx ; +2 + stosd + mov eax,edi ;konecnou pozici pro tabulku x zapis do eax + pop edi ;obnov registry edi exc ebx+1 + add ebx,esi ;najdi adresu prekladove tabulky barev + add ebx,2 ;preskoc transparentni barvu + add esi,pic_start;presun se na zacatek obrazku + pop ecx ; +0 + movzx edx,cx ;vem levy okraj + lea edx,[ebp+edx*4] + lea edx,[edx+ed_stk1];edx ukazuje na sloupce + cmp eax,edx ;je-li levy okraj za platnou tabulkou tak konec + jbe ed_err + shr ecx,16 ;ecx ted obsahuje pravy okraj +ed_lp4: push esi ;uchovej esi +1 + push edi ;uchovej edi +2 + add esi,[ebp] ;spocitej spravnou hodnotu esi + push ecx ;uchovej pravy okraj +3 + push edx ;uchovej ukazatel na tabulku+4 +ed_lp3: mov eax,[edx] + cmp eax,-1 ;testuj konec tabulky + jz ed_end3 ;pri pozitivnim vysledku => konec radky + movzx eax,byte ptr[esi+eax];vem barvu + or al,al + jz ed_skp1 ;preskoc transparentni barvu + dec al + jz ed_shd ;1=shadow + mov eax,[ebx+eax*2];vyzvedni hicolor + stosw ;zapis barvu + jmp ed_skp2 +ed_shd: movzx eax,word ptr[edi];vem barvu + and eax,7bdfh ;stmav + shr eax,1 + stosw ;zapis + jmp ed_skp2 ;skok na konec +ed_skp1:add edi,2 ;preskoc bod +ed_skp2:add edx,4 ;dalsi pozice + dec ecx ;dokud nedosahneme praveho okraje obrazku + jnz ed_lp3 +ed_end3:pop edx ;obnov vse ulozene + pop ecx + pop edi + pop esi ; +0 + add ebp,4 ;dalsi y souradnice + sub edi,1280 ;dalsi radka + cmp dword ptr [ebp],-1 ;test na konec tabulky + jnz ed_lp4 ;jinak pokracuj +ed_err: add esp,ed_stack;vymaz tabulku + pop ebp ;obnov ebp + ret ;konec + +public enemy_draw_mirror_ ;kresli zrcadlove otocenou potvoru +enemy_draw_mirror_: ;ESI - Source_picture + ;EDI - Target + ;EBX - Offset of palette + ;EDX - scale (1-320) + ;EAX - max_space (kolik ma nahore mista) + ;ECX - Hi_omezeni z prava, Lo_omezeni zleva + + push ebp + sub esp,ed_stack ;vyhrad zasobnik + mov ebp,esp + push ecx ;uchovej ecx +1 + push edi ;uchovej edi +2 + push ebx ;uchovej ebx +3 + mov ebx,eax ;volne misto je ted v ebx + mov edi,ebp ;nastav edi na zacatek tabulek + push ebp ; +4 + movzx ecx,word ptr[esi] ;precti xs + movzx eax,word ptr[esi+2] ;precti ys + imul eax,ecx ;xs*ys + sub eax,ecx ;minus 1 radek + xor ebp,ebp +edmlp1b:stosd ;zapis hodnotu do tabulky + add ebp,320 ;zmensovani +edmlp1a:cmp ebp,edx + jc edmnxt1 ;pri ebp konec radky + movzx eax,byte ptr[esi+eax];vem barvu + or al,al + jz edmskp1 ;preskoc transparentni barvu + dec al + jz edmshd ;1=shadow + mov eax,[ebx+eax*2];vyzvedni hicolor + stosw ;zapis barvu + jmp edmskp2 +edmshd: movzx eax,word ptr[edi];vem barvu + and eax,7bdfh ;stmav + shr eax,1 + stosw ;zapis + jmp edmskp2 ;skok na konec +edmskp1:add edi,2 ;preskoc bod +edmskp2:add edx,4 ;dalsi pozice + dec ecx ;dokud nedosahneme praveho okraje obrazku + jnz edmlp3 +edmend3:pop edx ;obnov vse ulozene + pop ecx + pop edi + pop esi ; +0 + add ebp,4 ;dalsi y souradnice + sub edi,1280 ;dalsi radka + cmp dword ptr [ebp],-1 ;test na konec tabulky + jnz edmlp4 ;jinak pokracuj +edmerr: add esp,ed_stack;vymaz tabulku + pop ebp ;obnov ebp + ret ;konec + + +pic_start_15 equ 2+2+2+512 + + + +public put_picture2picture_ ;vlozi obrazek do obrazku (256c->256) +put_picture2picture_: + ;ESI - obrazek 256c + ;EDI - obrazek 256 + ;EAX - Xpos + ;EDX - Ypos + movzx ecx,word ptr [edi] ;vyzvedni sirku obrazku + imul edx,ecx ;nova adresa=edi+(Xpos+sirka*Ypos) + add eax,edx + mov edx,ecx + lea edi,[edi+eax+pic_start] ;edi obsahuje novou adresu + mov ecx,[esi] ;ecx obsahuje Xsize a Ysize obrazku + sub ecx,10000h ;Ysize-1 + lea esi,[esi+pic_start] ;nastav esi na zacatek bitmapy +ppp_lp2:push ecx ;uchovej velikosti obrazku v zasobniku +ppp_lp1:lodsb ;nacti bod ze zdroje + or al,al ;zkontroluj zda to neni transparentni barva + jz ppp_trn ;pokud je tak ji prezskoc + mov [edi],al ;zapis barvu +ppp_trn:inc edi ;dalsi bod + dec cx ;odecitej x sirku + jnz ppp_lp1 ;dokud to neni vse + pop ecx ;obnov ecx + movzx eax,cx ;vem jeste jednou sirku + sub eax,edx ;spocitej kolik bajtu je nutne + sub edi,eax ;prezkocit k dosazeni dalsi radky + sub ecx,10000h ;opakuj pro y radku + jnc ppp_lp2 + ret + +public trans_bar25_ ;ztmaveni o 25% + ;EDI - X + ;ESI - Y + ;ECX - YS + ;EDX - XS bere se nejmensi sude cislo +trans_bar25_: + mov eax,1280 + imul eax,esi + shl edi,1 + add edi,eax + add edi,_screen +trs2_l2:mov esi,edi + push edx + shr edx,1 +trs2_l1:lodsd + mov ebx,eax + and ebx,739c739ch + shr ebx,2 + sub eax,ebx + stosd + dec edx + jnz trs2_l1 + pop edx + add edi,1280 + sub edi,edx + sub edi,edx + dec ecx + jnz trs2_l2 + ret + + + +;public double_xicht_ ;zobrazi zvetseny xicht +; ;ESI - source +; ;EDI - TARGET +;double_xicht_: +; push ebp +; mov ecx,[esi+2] +; lea ebx,[esi+6] +; mov edx,[ebx-6] +; movzx eax,byte ptr [esi] +; mov ebp,[eax*2+ebx] + + + + +public enemy_draw_transp_ +enemy_draw_transp_: ;ESI - Source_picture + ;EDI - Target + ;EBX - Offset of palette + ;EDX - scale (1-320) + ;EAX - max_space (kolik ma nahore mista) + ;ECX - Hi_omezeni z prava, Lo_omezeni zleva + + cmp eax,470 + jc et_ok1 + ret +et_ok1: push ebp + sub esp,ed_stack ;vyhrad zasobnik + mov ebp,esp + push ecx ;uchovej ecx +1 + push edi ;uchovej edi +2 + push ebx ;uchovej ebx +3 + mov ebx,eax ;volne misto je ted v ebx + mov edi,ebp ;nastav edi na zacatek tabulek + push ebp ; +4 + movzx ecx,word ptr[esi] ;precti xs + movzx eax,word ptr[esi+2] ;precti ys + imul eax,ecx ;xs*ys + sub eax,ecx ;minus 1 radek + xor ebp,ebp +et_lp1b:stosd ;zapis hodnotu do tabulky + add ebp,320 ;zmensovani +et_lp1a:cmp ebp,edx + jc et_nxt1 ;pri ebp=velikosti obrazku tak konec + jc et_lp2a + xor eax,eax + dec eax ;zapis -1 na konec tabulky + pop ebx ; +2 + stosd + mov eax,edi ;konecnou pozici pro tabulku x zapis do eax + pop edi ;obnov registry edi exc ebx+1 + cmp byte ptr [esi+5],2 ;obrazek bez palety? + jz et_pl1 + add esi,pic_start;presun se na zacatek obrazku (za paletu) + jmp et_pl2 +et_pl1: add esi,6 ;(obrazek bez palety, presun se za hlavicku) +et_pl2: pop ecx ; +0 + movzx edx,cx ;vem levy okraj + lea edx,[ebp+edx*4] + lea edx,[edx+ed_stk1];edx ukazuje na sloupce + cmp eax,edx ;je-li levy okraj za platnou tabulkou tak konec + jbe et_err + shr ecx,16 ;ecx ted obsahuje pravy okraj +et_lp4: push esi ;uchovej esi +1 + push edi ;uchovej edi +2 + add esi,[ebp] ;spocitej spravnou hodnotu esi + push ecx ;uchovej pravy okraj +3 + push edx ;uchovej ukazatel na tabulku+4 +et_lp3: mov eax,[edx] + cmp eax,-1 ;testuj konec tabulky + jz et_end3 ;pri pozitivnim vysledku => konec radky + movzx eax,byte ptr[esi+eax];vem barvu + test al,80h + jnz et_shd + or al,al + jz et_skp1 ;preskoc transparentni barvu + mov eax,[ebx+eax*2];vyzvedni hicolor + stosw ;zapis barvu + jmp et_skp2 +et_shd: and word ptr[edi],07bdfh + mov eax,[ebx+eax*2];vyzvedni hicolor + and eax,7bdfh ;stmav + add ax,word ptr[edi] + shr eax,1 + stosw ;zapis + jmp et_skp2 ;skok na konec +et_skp1:add edi,2 ;preskoc bod +et_skp2:add edx,4 ;dalsi pozice + dec ecx ;dokud nedosahneme praveho okraje obrazku + jnz et_lp3 +et_end3:pop edx ;obnov vse ulozene + pop ecx + pop edi + pop esi ; +0 + add ebp,4 ;dalsi y souradnice + sub edi,1280 ;dalsi radka + cmp dword ptr [ebp],-1 ;test na konec tabulky + jnz et_lp4 ;jinak pokracuj +et_err: add esp,ed_stack;vymaz tabulku + pop ebp ;obnov ebp + ret ;konec + + +public enemy_draw_mirror_transp_ ;kresli zrcadlove otocenou potvoru pruhledne +enemy_draw_mirror_transp_: ;ESI - Source_picture + ;EDI - Target + ;EBX - Offset of palette + ;EDX - scale (1-320) + ;EAX - max_space (kolik ma nahore mista) + ;ECX - Hi_omezeni z prava, Lo_omezeni zleva + + push ebp + sub esp,ed_stack ;vyhrad zasobnik + mov ebp,esp + push ecx ;uchovej ecx +1 + push edi ;uchovej edi +2 + push ebx ;uchovej ebx +3 + mov ebx,eax ;volne misto je ted v ebx + mov edi,ebp ;nastav edi na zacatek tabulek + push ebp ; +4 + movzx ecx,word ptr[esi] ;precti xs + movzx eax,word ptr[esi+2] ;precti ys + imul eax,ecx ;xs*ys + sub eax,ecx ;minus 1 radek + xor ebp,ebp +etmlp1b:stosd ;zapis hodnotu do tabulky + add ebp,320 ;zmensovani +etmlp1a:cmp ebp,edx + jc etmnxt1 ;pri ebp konec radky + movzx eax,byte ptr[esi+eax];vem barvu + test al,80h + jnz etmshd + or al,al + jz etmskp1 ;preskoc transparentni barvu + mov eax,[ebx+eax*2];vyzvedni hicolor + stosw ;zapis barvu + jmp etmskp2 +etmshd: and word ptr[edi],07bdfh + mov eax,[ebx+eax*2];vyzvedni hicolor + and eax,7bdfh ;stmav + add ax,word ptr[edi] + shr eax,1 + stosw ;zapis + jmp etmskp2 ;skok na konec +etmskp1:add edi,2 ;preskoc bod +etmskp2:add edx,4 ;dalsi pozice + dec ecx ;dokud nedosahneme praveho okraje obrazku + jnz etmlp3 +etmend3:pop edx ;obnov vse ulozene + pop ecx + pop edi + pop esi ; +0 + add ebp,4 ;dalsi y souradnice + sub edi,1280 ;dalsi radka + cmp dword ptr [ebp],-1 ;test na konec tabulky + jnz etmlp4 ;jinak pokracuj +etmerr: add esp,ed_stack;vymaz tabulku + pop ebp ;obnov ebp + ret ;konec + + + + +zobraz_2 macro + lodsw + movzx ebp,ah + movzx ebp,ds:[ebx+ebp*2] + shl ebp,16 + movzx eax,al + movzx eax,[ebx+eax*2] + or eax,ebp + stosd +endm + +zobraz_1 macro + lodsb + movzx eax,al + movzx eax,word ptr [eax*2+ebx] + stosw +endm + + +public show_anm_buff_ ;zobrazi frame animace (normal); + +show_anm_buff_: ;ESI - SOURCE + ;EDI - TARGER + ;EBX - PALETA + + push ebp + mov ecx,180*320 +shwab4: zobraz_2 + dec ecx + jnz shwab4 + ret + +public show_anm_delta_ ;zobrazi frame animace (normal); + + +show_anm_delta_: ;ESI - SOURCE + ;EDI - TARGER + ;EBX - PALETA + + push ebp ;uchovej EBP pro dalsi mozne pouziti + mov ch,180 ;180 radek + mov eax,[esi] ;vem offset na delta data + lea ebp,[esi+eax+4] ;ebp obsahuje tento offset + lea esi,[esi+4] ;esi obsahuje offset na delta control +shwad5: push edi ;uchovej zacatek radky + push edx ;i pro transp data +shwad3: lodsb ;vem skip hodnotu + mov ah,al ;uchovej ji ah - kvuli destruktivnimu testu + and al,not 3fh ;na posledni 2 bity + cmp al,0c0h ;C0 a vyssi znamenaji ze se preskakuje radek + jz shwad1 ;pri pozitivnim testu je preskoc + movzx eax,ah ;vem skip hodnotu do eax + shl eax,2 ;na obrazovce *2 bodu *2 za bod (x8) + add edi,eax ;pricti k edi + lodsb ;vem copy hodnotu + mov cl,al ;zaved counter + xchg esi,ebp ;prohod ukazatele control a data + push ebp ;uchovej control +shwad2: zobraz_2 ;zobraz bod + dec cl ;opakuj tolikrat kolik je copy hodnota + jnz shwad2 + pop ebp ;obnov control + xchg esi,ebp ;prohod ukazatele control a data + jmp shwad3 ;a precti dalsi skip hodnotu +shwad1: pop edx ;obnov registry ukazujici na zacatek radky + pop edi + and ah,03fh ;maskuj spodnich 6 bitu + inc ah ;+1 +shwad4: add edi,640 + dec ch ;odecti counter radek + dec ah ;odecti counter + jnz shwad4 ;a opakuj ah krat + or ch,ch ;je li counter nulovy tak padame + jnz shwad5 + pop ebp ;obnov ebp + ret ;konec + ret + +public klicovani_anm_ + +klicovani_anm_: ;esi source edi target al mirror + or al,al + jnz klicovani_anm_back_ + mov ecx,180 +ka_lp2: mov ebx,320 +ka_lp1: lodsw + movzx eax,ax + test eax,0x8000 + jnz ka_skip + mov edx,eax + shl edx,16 + or eax,edx + mov [edi+1280],eax + mov [edi],eax +ka_skip:add edi,4 + dec ebx + jnz ka_lp1 + add edi,1280 + dec ecx + jnz ka_lp2 + ret + +public klicovani_anm_back_ + +klicovani_anm_back_: ;esi source edi target + mov ecx,180 + add edi,1280 +kba_lp2: mov ebx,320 +kba_lp1: lodsw + sub edi,4 + movzx eax,ax + test eax,0x8000 + jnz kba_skip + mov edx,eax + shl edx,16 + or eax,edx + mov [edi+1280],eax + mov [edi],eax +kba_skip:dec ebx + jnz kba_lp1 + add edi,1280*3 + dec ecx + jnz kba_lp2 + ret + + + + +public small_anm_buff_ ;zobrazi frame v mensim ramecku + +small_anm_buff_: ;ESI - SOURCE + ;EDI - TARGER + ;EBX - PALETA + + mov ecx,179*10000h +shmab4: mov cx,320 +shmab3: zobraz_1 + dec cx + jnz shmab3 + add edi,640 + sub ecx,010000h + jnc shmab4 + ret + +public small_anm_delta_ ;zobrazi frame animace (normal); + + +small_anm_delta_: ;ESI - SOURCE + ;EDI - TARGER + ;EBX - PALETA + + mov ch,180 ;180 radek + mov eax,[esi] ;vem offset na delta data + lea edx,[esi+eax+4] ;ebp obsahuje tento offset + lea esi,[esi+4] ;esi obsahuje offset na delta control +shmad5: push edi ;uchovej zacatek radky +shmad3: lodsb ;vem skip hodnotu + mov ah,al ;uchovej ji ah - kvuli destruktivnimu testu + and al,not 3fh ;na posledni 2 bity + cmp al,0c0h ;C0 a vyssi znamenaji ze se preskakuje radek + jz shmad1 ;pri pozitivnim testu je preskoc + movzx eax,ah ;vem skip hodnotu do eax + shl eax,2 ;na obrazovce *2 bodu *1 zoom *2 za bod (x4) + add edi,eax ;pricti k edi + lodsb ;vem copy hodnotu + mov cl,al ;zaved counter + xchg esi,edx ;prohod ukazatele control a data +shmad2: zobraz_1 ;zobraz bod + zobraz_1 ;zobraz bod + dec cl ;opakuj tolikrat kolik je copy hodnota + jnz shmad2 + xchg esi,edx ;prohod ukazatele control a data + jmp shmad3 ;a precti dalsi skip hodnotu +shmad1: pop edi + and ah,03fh ;maskuj spodnich 6 bitu + inc ah ;+1 +shmad4: add edi,1280 + dec ch ;odecti counter radek + dec ah ;odecti counter + jnz shmad4 ;a opakuj ah krat + or ch,ch ;je li counter nulovy tak padame + jnz shmad5 + ret ;konec + ret + +public scroll_and_copy_ +scroll_and_copy_: ;odscroluje a kopiruje obrazovku do screenu + ;pouzitelne pro titulky + ;0x8000 je transparentni + ;edi screen + ;ebx buffer + ;esi back_picture + ;ecx velikost bufferu (pocet_radku) + ;edx pocet bajtu o kolik je nutne posouvat (*1280) + ;eax - ukazatel na tittle lines + push ebp + mov ebp,eax ;uloz ukazatel na titlelines + mov eax,edx + imul eax,1280 +sac_lp1:push ecx + push eax + mov eax,[ebp] ;nacti zac + mov ecx,[ebp+edx*8] + cmp eax,ecx + jc sac_sk1 + mov eax,ecx +sac_sk1:shl eax,1 ;adresa + add esi,eax ;pricti k pointrum + add edi,eax + add ebx,eax + add ebp,4 ;presun se na kon + shr eax,1 ;eax je zacatek v bodech + mov ecx,[ebp+edx*8] ;vem konec + cmp ecx,[ebp] + jnc sac_sk2 + mov ecx,[ebp] +sac_sk2:push ecx + sub ecx,eax ;kon-zac+1=celk pocet + xchg edx,[esp+4] +sac_lp2:mov eax,[ebx+edx] ;Vem data na dalsim radku + mov [ebx],eax ;Zapis je sem + add ebx,4 ;dalsi pozice + test eax,7fff7fffh ;je to transparentni? + jz sac_all ;pokud ano, zobraz_obrazek + bt eax,15 ;test bitu 15 + jnc sac_1 ;Neni nastaven - zobraz primo barvu + mov ax,[esi] ;jinak vem barvu z obrazku +sac_1: stosw ;zapis barvu + add esi,2 ;dalsi pozice + rol eax,16 ;presun eax na dolni slovo + bt eax,15 ;test bitu 15 + jnc sac_2 ;neni nastaven - zobraz primo barvu + mov ax,[esi] ;jinak vem barvu z obrazku +sac_2: stosw ;zapis barvu + add esi,2 ;dalsi pozice + jmp sac_end +sac_all:movsd ;presun celeho slova +sac_end:sub ecx,2 ;odecti counter + ja sac_lp2 ;je li nad opakuj + add ecx,640 ;pricti sirku, - kolik jsme prejeli + pop eax + sub ecx,eax ;odecti konec -> kolik preskocit + add ebp,4 ;aktualizuj ukazatele + shl ecx,1 ;v adresach + add esi,ecx + add edi,ecx + add ebx,ecx + pop eax + xchg edx,eax + pop ecx ;obnov ecx + dec ecx ;sniz citac radku + jnz sac_lp1 ;dokud neni nula + pop ebp ;obnov ebp + ret ;konec + + + public lodka32_ +lodka32_: + ;esi - zdrojovy blok + ;edi - cil + ;eax - lodka + ;zoom.xtable - tabulka pro x + ;zoom.xtable - tabulka pro y + ;zoom.textline - rozdil mezi pravym okrajem a levym okrajem + ; pri prechodu na novou radku + ;ecx ysize:xsize + push ebp + mov ebp,eax + mov ebx,_zoom[offset tzoom.ytable] +l32d: push cx + mov edx,_zoom[offset tzoom.xtable] + push esi +l32c: mov eax,dword ptr [ebp] + or eax,eax + jnz l32e + mov al,[edx] + inc edx + or al,al + jz l32a + lodsw + stosw + stosw + jmp l32b +l32e: stosd + movzx eax,byte ptr[edx] ;0 - o 4 1 - o 2 + xor eax,1 ;0->1 1->0 + inc eax ;1+1=2 0+1=1 + shl eax,1 ;2*2=4 1*2=2 + add esi,eax + inc edx + jmp l32b +l32a: lodsd + stosd +l32b: add ebp,4 + dec cx + jnz l32c + pop esi + mov eax,[ebx] + and eax,0ffffh + add esi,eax + add ebx,2 + add edi,_zoom[offset tzoom.textline] + xor cx,cx + cmp ecx,60*65536 + cmc + sbb eax,eax + and eax,1280 + sub ebp,eax + sub ecx,10000h + pop cx + jnz l32d + pop ebp + ret + + public lodka32b_ +lodka32b_: + ;esi - zdrojovy blok + ;edi - cil + ;zoom.xtable - tabulka pro x + ;zoom.ytable - tabulka pro y + ;zoom.textline - rozdil mezi pravym okrajem a levym okrajem + ; pri prechodu na novou radku + ;ecx ysize:xsize + ;zoom.ycount - interni (ulozeni maskovane adr stranky) + ;zoom.xmax - interni (pocet dwordu do prepnuti) + ;zoom.linelen - interni (velikost stranky v dwordech) + + + call mapvesaadr_ ;mapuj spravne edi + push ebp + mov ebp,eax + mov ebx,_zoom[offset tzoom.ytable] +l32bd: push cx + mov edx,_zoom[offset tzoom.xtable] + push esi + push edi +l32bc: mov eax,dword ptr [ebp] + or eax,eax + jnz l32be + mov al,[edx] + inc edx + or al,al + jz l32ba + lodsw + stosw + stosw + jmp l32bb +l32be: stosd + movzx eax,byte ptr[edx] ;0 - o 4 1 - o 2 + xor eax,1 ;0->1 1->0 + inc eax ;1+1=2 0+1=1 + shl eax,1 ;2*2=4 1*2=2 + add esi,eax + inc edx + jmp l32bb +l32ba: lodsd + stosd +l32bb: add ebp,4 + movzx eax,di ;prevezmi dolni cast edi do eax + dec eax ;odecti 1 (0=0xffffffff) + cmp eax,_gran_mask ;je vetsi nez granualita? + jc l32gb ;ne, vse je ok + mov eax,_lastbank ;ano, pak vem cislo banky + inc eax ;pricti 1 + mov _lastbank,eax ;zapis jako nove cislo banky + pushad ;uchovej vse + call switchvesabank_ ;prepni banku + popad ;obnov vse + mov edi,0a0000h ;vynuluj dolni cast di +l32gb: dec cx ;tady pokracujem + jnz l32bc ;opakuj cxkrat + pop edi ;obnov edi + add di,1280 ;pricti radek + and di,word ptr _gran_mask ;maskuj granualitou + pop esi + mov eax,[ebx] + and eax,0ffffh + add esi,eax + add ebx,2 + xor cx,cx + cmp ecx,60*65536 + cmc + sbb eax,eax + and eax,1280 + sub ebp,eax + sub ecx,10000h + pop cx + jnz l32bd + pop ebp + ret + + + public lodka256_ +lodka256_: + ;esi - zdrojovy blok + ;edi - cil + ;eax - lodka + ;zoom.xtable - tabulka pro x + ;zoom.xtable - tabulka pro y + ;zoom.textline - rozdil mezi pravym okrajem a levym okrajem + ; pri prechodu na novou radku + ;ecx ysize:xsize + ;ebx xlat + push ebp + mov ebp,eax +l256d: push cx + mov edx,_zoom[offset tzoom.xtable] + push esi +l256c: mov eax,[ebp] + or eax,eax + jnz l256e + movzx eax,byte ptr [edx] + inc edx + or al,al + jz l256a + lodsw + mov al,[ebx+eax*2] + mov ah,al + stosw + jmp l256b +l256e: movzx eax,ax + mov al,[ebx+eax*2] + mov ah,al + stosw + movzx eax,byte ptr[edx] ;0 - o 4 1 - o 2 + xor eax,1 ;0->1 1->0 + inc eax ;1+1=2 0+1=1 + shl eax,1 ;2*2=4 1*2=2 + add esi,eax + inc edx + jmp l256b +l256a: lodsw + mov al,[ebx+eax*2] + stosb + lodsw + mov al,[ebx+eax*2] + stosb +l256b: add ebp,4 + xor ebx,1 + dec cx + jnz l256c + xor ebx,1 + pop esi + mov edx,_zoom[offset tzoom.ytable] + mov eax,[edx] + and eax,0ffffh + add esi,eax + add edx,2 + mov _zoom[offset tzoom.ytable],edx + add edi,_zoom[offset tzoom.textline] + xor cx,cx + cmp ecx,60*65536 + cmc + sbb eax,eax + and eax,1280 + sub ebp,eax + sub ecx,10000h + pop cx + jnz l256d + pop ebp + ret + + + public lodka256b_ +lodka256b_: + ;esi - zdrojovy blok + ;edi - cil + ;zoom.xtable - tabulka pro x + ;zoom.xtable - tabulka pro y + ;zoom.textline - rozdil mezi pravym okrajem a levym okrajem + ; pri prechodu na novou radku + ;ecx ysize:xsize + ;ebx xlat + push ebp + mov ebp,eax +l256bd: push cx + mov edx,_zoom[offset tzoom.xtable] + push edi + call mapvesaadr_ + push esi +l256bc: mov eax,[ebp] + or eax,eax + jnz l256be + movzx eax,byte ptr[edx] + inc edx + or al,al + jz l256ba + lodsw + mov al,[ebx+eax*2] + mov ah,al + stosw + jmp l256bb +l256be: movzx eax,ax + mov al,[ebx+eax*2] + mov ah,al + stosw + movzx eax,byte ptr[edx] ;0 - o 4 1 - o 2 + xor eax,1 ;0->1 1->0 + inc eax ;1+1=2 0+1=1 + shl eax,1 ;2*2=4 1*2=2 + add esi,eax + inc edx + jmp l256bb +l256ba: lodsw + mov al,[ebx+eax*2] + stosb +l256bh: lodsw + mov al,[ebx+eax*2] + stosb +l256bb: add ebp,4 + swap_at_end di,edi + xor ebx,1 + dec cx + jnz l256bc + xor ebx,1 + pop esi + pop edi + add edi,640 + mov edx,_zoom[offset tzoom.ytable] + mov eax,[edx] + and eax,0ffffh + add esi,eax + add edx,2 + mov _zoom[offset tzoom.ytable],edx + add edi,_zoom[offset tzoom.textline] + xor cx,cx + cmp ecx,60*65536 + cmc + sbb eax,eax + and eax,1280 + sub ebp,eax + sub ecx,10000h + pop cx + jnz l256bd + pop ebp + ret + + + +_TEXT ends + + +END + + + + + + +if 0 +;POZOR DUMP! + + + public zooming32b_ +zooming32b_: + ;esi - zdrojovy blok + ;edi - cil + ;zoom.xtable - tabulka pro x + ;zoom.ytable - tabulka pro y + ;zoom.textline - rozdil mezi pravym okrajem a levym okrajem + ; pri prechodu na novou radku + ;ecx ysize:xsize + ;zoom.ycount - interni (ulozeni maskovane adr stranky) + ;zoom.xmax - interni (pocet dwordu do prepnuti) + + push ebp + mov ebp,eax + mov ebx,_zoom[offset tzoom.ytable] +z32bd: push cx + mov edx,_zoom[offset tzoom.xtable] + push esi + push edi + call mapvesaadr_ +z32bc: mov al,[edx] + inc edx + or al,al + jz z32ba + lodsw + test ax,8000h + jnz z32be + stosw + stosw + jmp z32bb +z32bf: test eax,8000h + jz z32bg + test eax,80000000h + jz z32bh +z32be: mov eax,[ds:ebp] + stosd + jmp z32bb +z32bg: rol eax,16 + mov ax,[ds:ebp+2] + rol eax,16 + stosd + jmp z32bb +z32bh: mov ax,[ds:ebp] + stosd + jmp z32bb +z32ba: lodsd + test eax,80008000h + jnz z32bf + stosd +z32bb: add ebp,4 + dec cx + jnz z32bc + pop edi + add edi,2048 + pop esi + mov eax,[ebx] + and eax,0ffffh + add esi,eax + add ebx,2 + xor cx,cx + sub ecx,10000h + pop cx + jnz z32bd + pop ebp + ret + +scroll_support_32b_: + ;edi - lbuffer + pozice na obrazovce + ;esi - oldbuffer + ;edx - newbuffer + ;ebx - xlat + ;ecx - size; + push ebp ;uchovej ebp + mov ebp,360 ;ebp pro tuto chvili predstavuje citac + mov eax,ecx ;uchovej ecx jeste v eac - zachova citac sloupcu +scrl1b: push edi + push esi ;uchovej esi + call mapvesaadr_ + shr ecx,1 ;presun ecx bloku + rep movsd + rcl ecx,1 + rep movsw + mov ecx,640 ;dopocitej ecx do 640 + sub ecx,eax + pop esi ;obnov esi + xchg esi,edx ;esi je nyni novy blok + push esi ;uchovek esi + shr ecx,1 ;presun + rep movsd + rcl ecx,1 + rep movsw + pop esi ;obnov esi + xchg esi,edx ;vrat edx a esi do puvodniho stavu + mov ecx,eax ;obnov zase ecx z eax + add esi,1280 ;dalsi radek + add edx,1280 + pop edi + add edi,2048 + dec ebp ; dokud nejsme na konci + jnz scrl1b ;opakuj + pop ebp + ret + +endif diff --git a/GAME/GAMESAVE.C b/GAME/GAMESAVE.C new file mode 100644 index 0000000..8fd4ef6 --- /dev/null +++ b/GAME/GAMESAVE.C @@ -0,0 +1,1586 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "globals.h" + +#define STATE_CUR_VER 1 + +#define _GAME_ST "_GAME.TMP" +#define _GLOBAL_ST "_GLOBEV.TMP" +#define _SLOT_SAV "slot%02d.SAV" +#define SLOTS_MAX 10 + +#define GM_MAPENABLE 0x1 + +#define SAVE_SLOT_S 34 +#define LOAD_SLOT_S (372+34) +#define SAVE_SLOT_E (34+203) +#define LOAD_SLOT_E (372+34+203) + +#define SSAVE_VERSION 0 + +static FILE *story=NULL; +static char load_another; +char reset_mobiles=0; + +typedef struct s_save + { + int viewsector; + char viewdir; + short version; + char not_used; + int gold; + short cur_group; + char autosave; + char enable_sort; + char shownames; + char showlives; + char zoom_speed; + char turn_speed; + char autoattack; + char music_vol; + char sample_vol; + char xbass; + char bass; + char treble; + char stereing; + char swapchans; + char out_filter; + long glob_flags; + long game_time; + char runes[5]; + char level_name[12]; + short picks; //pocet_sebranych predmetu v mysi + short items_added; //pocet_pridanych predmetu + int sleep_long; + int game_flags; + }S_SAVE; + +#define ZAKLAD_CRC 0xC005 + +static int get_list_count(); + +static word vypocet_crc(char *data,long delka) + { + unsigned long l=0; + do + { + l=(l<<8)|(delka>0?*data++:0);delka--; + l=(l<<8)|(delka>0?*data++:0);delka--; + l%=ZAKLAD_CRC; + } + while(delka>-1); + return l & 0xffff; + } +static unable_open_temp(char *c) + { + char d[]="Unable to open the file : ",*e; + + concat(e,d,c); + closemode(); + MessageBox(NULL,e,NULL,MB_OK|MB_ICONSTOP); + SEND_LOG("(SAVELOAD) Open temp error detected (%s)",c,0); + exit(1); + } + +static unable_write_temp(char *c) + { + char d[]="Unable to write to the temp file : ",*e; + + concat(e,d,c); + closemode(); + MessageBox(NULL,e,NULL,MB_OK|MB_ICONSTOP); + SEND_LOG("(SAVELOAD) Open temp error detected (%s)",c,0); + exit(1); + } + +void expand_map_file_name(char *s) //prepise *.map na fullpath\*.TMP + { + char *c; + char *st; + c=strchr(s,0); + while (c!=s && *c!='.' && *c!='\\') c--; + if (*c=='.') strcpy(c,".TMP"); + concat(st,pathtable[SR_TEMP],s); + strcpy(s,st); + } + +int load_org_map(char *filename,void **sides,void **sectors,void **coords,int *mapsize) + { + FILE *f; + void *temp; + int sect; + long size,r; + char nmapend=1; + char *c; + + c=find_map_path(filename); + f=fopen(c,"rb");free(c); + if (f==NULL) return -1; + do + { + r=load_section(f,&temp,§,&size); + if (r==size) + switch (sect) + { + case A_SIDEMAP: + *sides=temp; + break; + case A_SECTMAP: + *sectors=temp; + if (mapsize!=NULL) *mapsize=size/sizeof(TSECTOR); + break; + case A_MAPINFO: + if (coords!=NULL) *coords=temp;else free(temp); + break; + case A_MAPGLOB: + //memcpy(&mglob,temp,min(sizeof(mglob),size)); + free(temp); + break; + case A_MAPEND : + nmapend=0; + free(temp); + break; + default: free(temp); + } + else + { + if (temp!=NULL)free(temp); + fclose(f); + return -1; + } + } + while (nmapend); + fclose(f); + return 0; + } + +void save_daction(FILE *f,int count,D_ACTION *ptr) + { + if (ptr!=NULL) + { + save_daction(f,count+1,ptr->next); + fwrite(ptr,1,sizeof(D_ACTION),f); + } + else + fwrite(&count,1,2,f); + } + +void load_daction(FILE *fsta) + { + int i,j; + i=0; + while (d_action!=NULL) //vymaz pripadne delaited actions + { + D_ACTION *p; + p=d_action; d_action=p->next;free(p); + } + fread(&i,1,2,fsta);d_action=NULL; + for(j=0;jnext=d_action; + d_action=p; + } + } + +void save_items(FILE *f) + { + int i,j; + short *c; + + for(i=0;ivyk_max) return -2; + fread(map_vyk,vyk_max,sizeof(TVYKLENEK),fsta); + } + return 0; + } + + +void save_all_fly(FILE *fsta) + { + LETICI_VEC *f; + + f=letici_veci; + fwrite(&f,1,sizeof(f),fsta); + while (f!=NULL) + { + short *c; + fwrite(f,1,sizeof(*f),fsta); + c=f->items; + if (c!=NULL) do fwrite(c,1,2,fsta); while (*c++); + f=f->next; + } + } + +int load_all_fly(FILE *fsta) + { + LETICI_VEC *f=NULL,*n,*p; + p=letici_veci; + while (p!=NULL) {stop_fly(letici_veci,0);p=p->next;} + fread(&f,1,sizeof(f),fsta); + p=letici_veci; + while (f!=NULL) + { + short items[100],*c; + n=New(LETICI_VEC); + c=items;memset(items,0,sizeof(items)); + if (fread(n,1,sizeof(*n),fsta)!=sizeof(*n)) + { + free(n); + if (p!=NULL) p->next=NULL; + return -2; + } + if (n->items!=NULL) + { + do + fread(c,1,2,fsta); + while (*c++); + n->items=NewArr(short,c-items); + memcpy(n->items,items,(c-items)*sizeof(short)); + } + if (p==NULL) p=letici_veci=n;else p->next=n; + p=n; + f=n->next; + n->next=NULL; + } + return 0; + } + + + + +int save_map_state() //uklada stav mapy pro savegame (neuklada aktualni pozici); + { + char sta[200]; + char *bf; + FILE *fsta; + int i; + long siz; + TSTENA *org_sides; + TSECTOR *org_sectors; + short res=-1; + int ver=0; + + restore_sound_names(); + strcpy(sta,level_fname); + expand_map_file_name(sta); + fsta=fopen(sta,"wb");if (fsta==NULL) unable_open_temp(sta); + SEND_LOG("(SAVELOAD) Saving map state for current map",0,0); + if (load_org_map(level_fname,&org_sides,&org_sectors,NULL,NULL)) goto err; + siz=(mapsize+7)/8; + bf=(char *)getmem(siz); + ver=0; + fwrite(&ver,sizeof(ver),1,fsta); //<------------------------- + ver=STATE_CUR_VER; + fwrite(&ver,sizeof(ver),1,fsta); //<------------------------- + fwrite(&mapsize,sizeof(mapsize),1,fsta); //<------------------------- + memset(bf,0,siz); + fwrite(&siz,1,sizeof(siz),fsta); //<------------------------- + for(i=0;i>3]|=1<<(i & 7); + if (!fwrite(bf,siz,1,fsta)) goto err; //<------------------------- + for(i=0;i>3]|=1<<(i & 7); + if (!fwrite(bf,siz,1,fsta)) goto err; //<------------------------- + save_map_description(fsta); + for(i=0;iSTATE_CUR_VER) goto err; + if (!fread(&i,sizeof(mapsize),1,fsta)) goto err; + if (mapsize!=i) goto err; + SEND_LOG("(SAVELOAD) Loading map state for current map",0,0); + fread(&siz,1,sizeof(siz),fsta); + bf=(char *)getmem(siz); + if (!fread(bf,siz,1,fsta)) goto err; + for (i=0;i>3]>>(i & 7)) & 1) map_coord[i].flags|=MC_AUTOMAP; + if (!fread(bf,siz,1,fsta)) goto err; + for (i=0;i>3]>>(i & 7)) & 1) map_coord[i].flags|=MC_DISCLOSED; + } + else + { + if (mapsize!=i) return fclose(fsta); + SEND_LOG("(SAVELOAD) Loading map state for current map",0,0); + fread(&siz,1,sizeof(siz),fsta); + bf=(char *)getmem(siz); + if (!fread(bf,siz,1,fsta)) goto err; + for (i=0;i>3]>>(i & 7)) & 1; + } + load_map_description(fsta); + while (fread(&i,1,2,fsta) && i<=mapsize*4) + if (fread(map_sides+i,1,sizeof(TSTENA),fsta)!=sizeof(TSTENA)) goto err; + while (fread(&i,1,2,fsta) && i<=mapsize) + if (fread(map_sectors+i,1,sizeof(TSECTOR),fsta)!=sizeof(TSECTOR)) goto err; + if (reset_mobiles) //reloads mobiles if flag present + { + char mm[MAX_MOBS]; + for(i=0;i> 1) | (c << 7); + /* + __asm + { + mov al,c + rol al,1; + } + } +*/ +//#pragma aux rotate parm [al] value [al]="rol al,1"; + +/* errors + -1 end of file + 1 disk error + 2 internal error + 3 checksum error + */ +int pack_status_file(FILE *f,char *status_name) + { + int stt; + char rcheck=0; + long fsz; + char *buffer,*c,*fullnam; + word crc; + + SEND_LOG("(SAVELOAD) Packing status file '%s'",status_name,0); + fullnam=alloca(strlen(status_name)+strlen(pathtable[SR_TEMP])+1); + if (fullnam==NULL) return 2; + strcpy(fullnam,pathtable[SR_TEMP]); + strcat(fullnam,status_name); + stt=open(fullnam,O_RDONLY | O_BINARY); + fsz=filelength(stt); + c=buffer=getmem(fsz+12+4+2); + strcpy(c,status_name);c+=12; + *(long *)c=fsz+2; + c+=sizeof(long); + read(stt,c,fsz); + close(stt); + crc=vypocet_crc(c,fsz); + c+=fsz; + memcpy(c,&crc,sizeof(crc)); + fsz+=12+4+2; + rcheck=(fwrite(buffer,1,fsz,f)!=(unsigned)fsz); + free(buffer); + return rcheck; + } + +int unpack_status_file(FILE *f) + { + int stt; + char rcheck=0; + long fsz; + char *buffer,*c,*fullnam; + char name[13]; + word crc,crccheck; + + name[12]=0; + name[11]=0; + fread(name,1,12,f); + SEND_LOG("(SAVELOAD) Unpacking status file '%s'",name,0); + if (name[0]==0) return -1; + fread(&fsz,1,4,f); + c=buffer=(char *)getmem(fsz); + if (fread(buffer,1,fsz,f)!=(unsigned)fsz) return 1; + fullnam=alloca(strlen(name)+strlen(pathtable[SR_TEMP])+2); + if (fullnam==NULL) return 2; + strcpy(fullnam,pathtable[SR_TEMP]); + strcat(fullnam,name); + fsz-=2; + crc=vypocet_crc(c,fsz); + c+=fsz;memcpy(&crccheck,c,sizeof(crccheck)); + if (crc!=crccheck) + { + free(buffer); + return 3; + } + stt=open(fullnam,O_BINARY | O_RDWR | O_CREAT | O_TRUNC, _S_IREAD | _S_IWRITE); + if (stt==-1) + { + free(buffer); + return 1; + } + rcheck=(write(stt,buffer,fsz)!=fsz) ; + free(buffer); + close(stt); + return rcheck; + } + +int pack_all_status(FILE *f) + { + char *c; + WIN32_FIND_DATA inf; + HANDLE res; + + concat(c,pathtable[SR_TEMP],"*.TMP"); + res=FindFirstFile(c,&inf); + if (res!=INVALID_HANDLE_VALUE) + do + { + int i; + if (inf.cFileName[0]!='~') + { + i=pack_status_file(f,inf.cFileName); + if (i) return i; + } + } + while (FindNextFile(res,&inf)); + FindClose(res); + c[0]=0; + fwrite(c,1,12,f); + return 0; + } + +int unpack_all_status(FILE *f) + { + int i; + + i=0; + while (!i) i=unpack_status_file(f); + if (i==-1) i=0; + return i; + } + +int save_basic_info() + { + FILE *f; + char *c; + S_SAVE s; + short *p; + int i; + char res=0; + THUMAN *h; + + concat(c,pathtable[SR_TEMP],_GAME_ST); + SEND_LOG("(SAVELOAD) Saving basic info for game (file:%s)",c,0); + f=fopen(c,"wb"); + if (f==NULL) return 1; + s.viewsector=viewsector; + s.viewdir=viewdir; + s.version=SSAVE_VERSION; + s.not_used=0; + s.gold=money; + s.cur_group=cur_group; + s.shownames=show_names; + s.showlives=show_lives; + s.autoattack=autoattack; + s.turn_speed=turn_speed(-1); + s.zoom_speed=zoom_speed(-1); + s.game_time=game_time; + s.enable_sort=enable_sort; + s.sleep_long=sleep_ticks; + s.sample_vol=get_snd_effect(SND_GFX); + s.music_vol=get_snd_effect(SND_MUSIC); + s.xbass=get_snd_effect(SND_XBASS); + s.bass=get_snd_effect(SND_BASS); + s.treble=get_snd_effect(SND_TREBL); + s.stereing=get_snd_effect(SND_LSWAP); + s.swapchans=get_snd_effect(SND_SWAP); + s.out_filter=get_snd_effect(SND_OUTFILTER); + s.autosave=autosave_enabled; + s.game_flags=(enable_glmap!=0); + strncpy(s.level_name,level_fname,12); + for(i=0;i<5;i++) s.runes[i]=runes[i]; + if (picked_item!=NULL) + for(i=1,p=picked_item;*p;i++,p++);else i=0; + s.picks=i; + s.items_added=item_count-it_count_orgn; + res|=(fwrite(&s,1,sizeof(s),f)!=sizeof(s)); + if (i) + res|=(fwrite(picked_item,2,i,f)!=(unsigned)i); + if (s.items_added) + res|=(fwrite(glob_items+it_count_orgn,sizeof(TITEM),s.items_added,f)!=(unsigned)s.items_added); + res|=save_spells(f); + if (!res) res|=(fwrite(postavy,1,sizeof(postavy),f)!=sizeof(postavy)); + for(i=0,h=postavy;idemon_save!=NULL) + fwrite(h->demon_save,sizeof(THUMAN),1,f); //ulozeni polozek s demony + res|=save_dialog_info(f); + fclose(f); + SEND_LOG("(SAVELOAD) Done... Result: %d",res,0); + return res; + } + +int load_basic_info() + { + FILE *f; + char *c; + S_SAVE s; + int i; + char res=0; + TITEM *itg; + THUMAN *h; + + concat(c,pathtable[SR_TEMP],_GAME_ST); + SEND_LOG("(SAVELOAD) Loading basic info for game (file:%s)",c,0); + f=fopen(c,"rb"); + if (f==NULL) return 1; + res|=(fread(&s,1,sizeof(s),f)!=sizeof(s)); + if (s.game_flags & GM_MAPENABLE) enable_glmap=1;else enable_glmap=0; + i=s.picks; + if (picked_item!=NULL) free(picked_item); + if (i) + { + picked_item=NewArr(short,i); + res|=(fread(picked_item,2,i,f)!=(unsigned)i); + } + else picked_item=NULL; + itg=NewArr(TITEM,it_count_orgn+s.items_added); + memcpy(itg,glob_items,it_count_orgn*sizeof(TITEM)); + free(glob_items);glob_items=itg; + if (s.items_added) + res|=(fread(glob_items+it_count_orgn,sizeof(TITEM),s.items_added,f)!=(unsigned)s.items_added); + item_count=it_count_orgn+s.items_added; + res|=load_spells(f); + for(i=0,h=postavy;idemon_save!=NULL) free(h->demon_save); + if (!res) res|=(fread(postavy,1,sizeof(postavy),f)!=sizeof(postavy)); + for(i=0,h=postavy;iprogramovano=0; + h->provadena_akce=h->zvolene_akce=NULL; + h->dostal=0; + if (h->demon_save!=NULL) + { + h->demon_save=New(THUMAN); + fread(h->demon_save,sizeof(THUMAN),1,f);//obnova polozek s demony + } + } + res|=load_dialog_info(f); + fclose(f); + viewsector=s.viewsector; + viewdir=s.viewdir; + cur_group=s.cur_group; + show_names=s.shownames; + show_lives=s.showlives; + autoattack=s.autoattack; + turn_speed(s.turn_speed); + zoom_speed(s.zoom_speed); + game_time=s.game_time; + sleep_ticks=s.sleep_long; + enable_sort=s.enable_sort; + autosave_enabled=s.autosave; + money=s.gold; + for(i=0;i<5;i++) runes[i]=s.runes[i]; + set_snd_effect(SND_GFX,s.sample_vol); + set_snd_effect(SND_MUSIC,s.music_vol); + set_snd_effect(SND_XBASS,s.xbass); + set_snd_effect(SND_BASS,s.bass); + set_snd_effect(SND_TREBL,s.treble); + set_snd_effect(SND_LSWAP,s.stereing); + set_snd_effect(SND_SWAP,s.swapchans); + set_snd_effect(SND_OUTFILTER,s.out_filter); + if (level_fname==NULL || strncmp(s.level_name,level_fname,12)) + { + strncpy(loadlevel.name,s.level_name,12); + loadlevel.start_pos=viewsector; + loadlevel.dir=viewdir; + send_message(E_CLOSE_MAP); + load_another=1; + } + else load_another=0; + for(i=0;i0) + { + SEND_LOG("(ERROR) Error detected during unpacking game... Loading stopped (result:%d)",r,0); + return r; + } + load_book(); + load_global_events(); + if ((t=load_saved_shops())!=0) return t; + if ((t=load_basic_info())!=0) return t; + running_battle=0; + norefresh=0; + if (!load_another) restore_current_map(); + else + { + save_map=0; + norefresh=1; + } + for(t=0;t0) + { + int xs,ys; + d=c; + while (size && *d!='\r' && *d!='\n') {d++;size--;}; + if (!size) break; + *d=0; + { + char *e,*or; + or=e=getmem(strlen(c)+2); + zalamovani(c,e,STORY_XS,&xs,&ys); + while (*e) + { + str_add(&ls,e); + if (text_width(e)>STORY_XS) abort(); + e=strchr(e,0)+1; + } + c=d+1;size--; + if (*c=='\n' || *c=='\r') {c++;size--;}; + free(or); + } + } + free(text_data); + } + else ls=NULL; + if (story_text!=NULL) release_list(story_text); + story_text=ls; + cur_story_pos=get_list_count();if (cur_story_pos<0) cur_story_pos=0; + redraw_story_bar(cur_story_pos); + } + +static void read_story(int slot) + { + static task_num=-1; + + if (task_num!=-1) term_task(task_num); + if (slot!=-1) + task_num=add_task(8196,read_story_task,slot); + } + + +static int get_list_count() + { + int count,i,max=0; + + if (story_text==NULL) return 0; + count=str_count(story_text); + for(i=0;i0) + { + if (id!=last_select) + { + set_font(H_FBOLD,NORMAL_COLOR); + if (last_select!=-1) place_name(force_save,last_select,1); + set_font(H_FBOLD,SELECT_COLOR); + place_name(force_save,id,1); + last_select=id; + read_story(id); + } + } + else + id=-1; + return id; + } + +char updown_scroll(int id,int xa,int ya,int xr,int yr); + +static char updown_noinst=0; + +static EVENT_PROC(updown_scroll_hold) + { + user_ptr; + WHEN_MSG(E_MOUSE) + { + MS_EVENT *ms; + + ms=get_mouse(msg); + if (ms->event_type==0x4 || !ms->tl1 || ms->tl2 || ms->tl3) + { + send_message(E_DONE,E_MOUSE,updown_scroll_hold); + send_message(E_DONE,E_TIMER,updown_scroll_hold); + updown_noinst=0; + } + } + WHEN_MSG(E_TIMER) + { + MS_EVENT *ms; + + updown_noinst=1; + ms=&ms_last_event; + ms->event_type=0x2; + send_message(E_MOUSE,ms); + if (updown_noinst) + { + send_message(E_DONE,E_MOUSE,updown_scroll_hold); + send_message(E_DONE,E_TIMER,updown_scroll_hold); + updown_noinst=0; + } + else + updown_noinst=1; + } + } + +static char updown_scroll(int id,int xa,int ya,int xr,int yr) + { + int count; + xr,yr,xa,ya; + if (story_text==NULL) return 0; + cur_story_pos+=id; + count=get_list_count(); + if (cur_story_pos>count) cur_story_pos=count; + if (cur_story_pos<0) cur_story_pos=0; + redraw_story_bar(cur_story_pos); + if (updown_noinst) + { + updown_noinst=0; + return 1; + } + send_message(E_ADD,E_MOUSE,updown_scroll_hold); + send_message(E_ADD,E_TIMER,updown_scroll_hold); + return 1; + } + +static char close_saveload(int id,int xa,int ya,int xr,int yr) + { + xa;ya;xr;yr;id; + if (ms_last_event.event_type & 0x8) + { + unwire_proc(); + wire_proc(); + } + return 1; + } + +char clk_load_konec(int id,int xa,int ya,int xr,int yr) + { + id;xa;ya;xr;yr; + send_message(E_CLOSE_MAP,-1); + return 1; + } + +static char clk_load_proc(int id,int xa,int ya,int xr,int yr); + +#define CLK_LOAD_ERROR 5 +T_CLK_MAP clk_load_error[]= + { + {-1,59,14+SCREEN_OFFLINE,306,46+SCREEN_OFFLINE,updown_scroll,2,H_MS_ZARE}, + {1,59,310+SCREEN_OFFLINE,306,332+SCREEN_OFFLINE,updown_scroll,2,H_MS_ZARE}, + {-1,LOAD_SLOT_S,SCREEN_OFFLINE,LOAD_SLOT_E,350,clk_load_proc,3,H_MS_DEFAULT}, + {-1,30,0,85,14,clk_load_konec,2,H_MS_DEFAULT}, + {-1,0,0,639,479,empty_clk,0xff,H_MS_DEFAULT}, + }; + + +static char clk_load_proc_menu(int id,int xa,int ya,int xr,int yr) + { + id=bright_slot(yr-18); + xa;ya;xr;yr; + if (ms_last_event.event_type & 0x2 && id>=0 && used_pos[id]) + send_message(E_CLOSE_MAP,id); + return 1; + } + +#define CLK_LOAD_MENU 5 +T_CLK_MAP clk_load_menu[]= + { + {-1,59,14+SCREEN_OFFLINE,306,46+SCREEN_OFFLINE,updown_scroll,2,H_MS_ZARE}, + {1,59,310+SCREEN_OFFLINE,306,332+SCREEN_OFFLINE,updown_scroll,2,H_MS_ZARE}, + {-1,LOAD_SLOT_S,SCREEN_OFFLINE,LOAD_SLOT_E,350,clk_load_proc_menu,3,H_MS_DEFAULT}, + {-1,0,0,639,479,clk_load_konec,8,H_MS_DEFAULT}, + {-1,0,0,639,479,empty_clk,0xff,H_MS_DEFAULT}, + }; + +static char clk_load_proc(int id,int xa,int ya,int xr,int yr) + { + id=bright_slot(yr-18); + xa;ya;xr;yr; + if (ms_last_event.event_type & 0x2 && id>=0 && used_pos[id]) + { + if (load_game(id)) + { + message(1,0,0,"",texty[79],texty[80]); + redraw_load(); + showview(0,0,0,0); + change_click_map(clk_load_error,CLK_LOAD_ERROR); + } + else + { + unwire_proc(); + wire_proc(); + if (battle) konec_kola(); + unwire_proc(); + if (!load_another) + { + wire_main_functs(); + cur_mode=MD_GAME; + bott_draw(1); + pick_set_cursor(); + for(id=0;idmsg==E_KEYBOARD) + { + c=*(char *)msg->data; + if (c==13) + { + send_message(E_KEYBOARD,c); + save_game(slot_pos,global_gamename); + wire_proc(); + read_slot_list(); + msg->msg=-2; + } + else if(c==27) + { + send_message(E_KEYBOARD,c); + msg->msg=-2; + wire_save_load(1); + } + } + } +static char clk_askname_stop(int id,int xa,int ya,int xr,int yr) + { + id,xa,ya,xr,yr; + if (ms_last_event.event_type & 0x2) + { + send_message(E_KEYBOARD,13); + return 1; + } + else + { + send_message(E_KEYBOARD,27); + return 1; + } + } + + +static void save_it(char ok) + { + if (ok) + { + save_game(slot_pos,global_gamename); + read_slot_list(); + wire_proc(); + GlobEvent(MAGLOB_AFTERSAVE,viewsector,viewdir); + } + else + { + wire_save_load(force_save); + } + } + +#define CLK_ASK_NAME 2 +T_CLK_MAP clk_ask_name[]= + { + {-1,0,0,639,479,clk_askname_stop,8+2,H_MS_DEFAULT}, + {-1,0,0,639,479,empty_clk,0xff,H_MS_DEFAULT}, + }; + + + +void wire_ask_gamename(int id) + { + int x,y; + + x=SAVE_SLOT_S; + y=id*SLOT_SPACE+21+SCREEN_OFFLINE; + slot_pos=id; + schovej_mysku(); + put_picture(x,y,ablock(H_LOADTXTR)); + strcpy(global_gamename,slot_list[id]); + clk_ask_name[0].id=add_task(16384,type_text_v2,global_gamename,x,y,SAVE_SLOT_E-SAVE_SLOT_S,SAVE_NAME_SIZE,H_FBOLD,RGB555(31,31,0),save_it); + change_click_map(clk_ask_name,CLK_ASK_NAME); + ukaz_mysku(); + } + + +#define CLK_SAVELOAD 11 +T_CLK_MAP clk_load[]= + { + {-1,LOAD_SLOT_S,SCREEN_OFFLINE,LOAD_SLOT_E,350,clk_load_proc,3,H_MS_DEFAULT}, + {-1,59,14+SCREEN_OFFLINE,306,46+SCREEN_OFFLINE,updown_scroll,2,H_MS_ZARE}, + {1,59,310+SCREEN_OFFLINE,306,332+SCREEN_OFFLINE,updown_scroll,2,H_MS_ZARE}, + {-1,54,378,497,479,start_invetory,2+8,-1}, + {-1,337,0,357,14,go_map,2,H_MS_DEFAULT}, + + {-1,291,0,313,14,go_book,2,H_MS_DEFAULT}, + {-1,87,0,142,14,game_setup,2,H_MS_DEFAULT}, + {-1,30,0,85,14,konec,2,H_MS_DEFAULT}, + {1,147,0,205,14,clk_saveload,2,H_MS_DEFAULT}, + {-1,267,0,289,15,clk_sleep,2,H_MS_DEFAULT}, + {-1,0,0,639,479,close_saveload,9,H_MS_DEFAULT}, + }; + + +static char clk_save_proc(int id,int xa,int ya,int xr,int yr) + { + id=bright_slot(yr-18); + xa;ya;xr;yr; + if (ms_last_event.event_type & 0x2 && id>=0) + { + unwire_proc(); + wire_ask_gamename(id); + } + return 1; + } + + +T_CLK_MAP clk_save[]= + { + {-1,SAVE_SLOT_S,SCREEN_OFFLINE,SAVE_SLOT_E,350,clk_save_proc,3,H_MS_DEFAULT}, + {-1,59+274,14+SCREEN_OFFLINE,306+274,46+SCREEN_OFFLINE,updown_scroll,2,H_MS_ZARE}, + {1,59+274,310+SCREEN_OFFLINE,306+274,332+SCREEN_OFFLINE,updown_scroll,2,H_MS_ZARE}, + {-1,54,378,497,479,start_invetory,2+8,-1}, + {-1,337,0,357,14,go_map,2,H_MS_DEFAULT}, + {-1,291,0,313,14,go_book,2,H_MS_DEFAULT}, + {-1,87,0,142,14,game_setup,2,H_MS_DEFAULT}, + {-1,30,0,85,14,konec,2,H_MS_DEFAULT}, + {0,207,0,265,14,clk_saveload,2,H_MS_DEFAULT}, + {-1,267,0,289,15,clk_sleep,2,H_MS_DEFAULT}, + {-1,0,0,639,479,close_saveload,9,H_MS_DEFAULT}, + }; + +static EVENT_PROC(saveload_keyboard) + { + user_ptr; + WHEN_MSG(E_KEYBOARD) + { + switch (GET_DATA(word)>>8) + { + case 1:unwire_proc();wire_proc();break; + case 'H':if (last_select>0) bright_slot((last_select-1)*SLOT_SPACE+1);break; + case 'P':if (last_select>3]>>(i & 7)) & 1; + load_map_description(fsta); + while (fread(&i,1,2,fsta) && i<=mapsize*4) + if (fread(map_sides+i,1,sizeof(TSTENA),fsta)!=sizeof(TSTENA)) goto err; + while (fread(&i,1,2,fsta) && i<=mapsize) + if (fread(map_sectors+i,1,sizeof(TSECTOR),fsta)!=sizeof(TSECTOR)) goto err; + res=0; + err: + free(bf); + fclose(fsta); + SEND_LOG("(SAVELOAD) Partial restore for map: %s (%s)",level_fname,"DONE"); + return res; + } + + +int load_map_automap(char *mapfile) + { + int i; + + SEND_LOG("(SAVEGAME) CRITICAL SECTION - Swapping maps: %s <-> %s",level_fname,mapfile); + kill_all_sounds(); + for(i=0;i>3)*2048+((g)>>3)*64+((b)>>3)) +#define GET_R_COLOR(col) ((col & 0xF800)>>8) +#define GET_G_COLOR(col) ((col & 0x07E0)>>3) +#define GET_B_COLOR(col) ((col & 0x001F)<<3) + +#define NOSHADOW(x) ((x)|BGSWITCHBIT) + +#define SWAPPATH pathtable[SR_TEMP] +#define TEMP_FILE "~SKELDAL.TMP" +#define PICTURES "..\\OBRAZKY\\" +#define PIC_FADE_PAL_SIZE (10*512+6) + +#define E_REFRESH 256 //udalost refresh scene +#define E_KOUZLO_KOLO 257 //funkce kouzel kazde jedno kolo +#define E_KOUZLO_ANM 258 //funkce kouzel kazdy frame + +//Registracni konstranty +#define H_DESK 0 +#define H_TOPBAR 1 +#define H_OKNO 2 +#define H_KOMPAS 3 +#define H_SIPKY_S 4 +#define H_SIPKY_SV 8 +#define H_SIPKY_SZ 9 +#define H_SIPKY_V 5 +#define H_SIPKY_Z 7 +#define H_SIPKY_J 6 +#define H_BACKMAP 10 +#define H_IOBLOUK 11 +#define H_IDESKA 12 +#define H_IMRIZ1 13 +#define H_RAMECEK 14 +#define H_ENEMY 15 +#define H_FBOLD 16 +#define H_FSYMB 17 +#define H_FLITT 18 +#define H_FLITT5 19 +#define H_FONT6 20 +#define H_FONT7 21 +#define H_FTINY 22 +#define H_FKNIHA 23 +#define H_KOUZLA 24 +#define H_POWERBAR 25 +#define H_POWERLED 26 +#define H_LODKA 27 +#define H_BATTLE_BAR 33 +#define H_BATTLE_MASK 34 +#define H_MZASAH1 35 +#define H_MZASAH2 36 +#define H_MZASAH3 37 +#define H_PZASAH 38 +#define H_BATTLE_CLICK 39 +#define H_SIPKY_END 40 +#define H_LEBKA 41 +#define H_KOSTRA 42 +#define H_KNIHA 43 +#define H_NS_LOGO 44 +#define H_WINTXTR 45 +#define H_SAVELOAD 46 +#define H_SVITEK 47 +#define H_LOADTXTR 48 +#define H_DIALOGY_DAT 49 +#define H_DIALOG 50 +#define H_MS_DEFAULT 51 +#define H_MS_SOUBOJ 52 +#define H_MS_WHO 53 +#define H_MS_LIST 54 +#define H_MS_ZARE 55 +#define H_POSTAVY 60 +#define H_BOTTBAR 66 +#define H_RUNEHOLE 68 +#define H_RUNEMASK 69 +#define H_CHARS 70 +#define H_CHARS_MAX 6 +#define H_POSTAVY_DAT 76 +#define H_SOUND_DAT 77 +#define H_SND_SWHIT1 78 +#define H_SND_SWHIT2 79 +#define H_SND_SWMISS1 80 +#define H_SND_SWMISS2 81 +#define H_SND_SIP1 82 +#define H_SND_SIP2 83 +#define H_SND_KNIHA 84 +#define H_SND_OBCHOD 85 +#define H_SND_LEKTVAR 86 +#define H_SND_TELEPIN 87 +#define H_SND_TELEPOUT 88 +#define H_SND_HEK1M 89 +#define H_SND_HEK2M 90 +#define H_SND_HEK1F 91 +#define H_SND_HEK2F 92 +#define H_SND_EAT 93 +#define H_SND_WEAR 94 +#define H_SND_PUTINV 95 +#define H_RUNEBAR1 100 +#define H_RUNEBAR2 101 +#define H_RUNEBAR3 102 +#define H_RUNEBAR4 103 +#define H_RUNEBAR5 104 +#define H_SPELLDEF 105 +#define H_BUTBIG 106 +#define H_BUTSMALL 107 +#define H_TELEPORT 108 +#define H_XICHTY 112 +#define H_XICHTY_MAX 6 +#define H_DIALOG_PIC 124 +#define H_SHOP_PIC 125 +#define H_SPELL_ANM 127 +#define H_SPELL_WAV 128 +#define H_TELEP_PCX 129 +#define H_TELEP_CNT 14 +#define H_FX 143 +#define H_KILL 144 +#define H_KILL_MAX 10 +#define H_CHECKBOX 154 +#define H_SETUPBAR 155 +#define H_SOUPAK 156 +#define H_SETUPOK 157 +#define H_POSTUP 158 +#define H_LODKA0 159 +#define H_LODKA1 160 +#define H_LODKA2 161 +#define H_LODKA3 162 +#define H_LODKA4 163 +#define H_LODKA5 164 +#define H_LODKA6 165 +#define H_LODKA7 166 +#define H_FLETNA 167 +#define H_FLETNA_BAR 168 +#define H_FLETNA_MASK 169 +#define H_SND_SEVER 170 +#define H_SND_VYCHOD 171 +#define H_SND_JIH 172 +#define H_SND_ZAPAD 173 +#define H_SND_RAND1 174 +#define H_SND_RAND2 175 +#define H_SND_RAND3 176 +#define H_SND_RAND4 177 +#define H_FBIG 178 +#define H_CHARGEN 179 +#define H_CHARGENB 180 +#define H_CHARGENM 181 +#define H_BGR_BUFF 182 +#define H_KREVMIN 183 +#define H_KREVMID 184 +#define H_KREVMAX 185 +#define H_ARMAGED 186 +#define H_ARMA_CNT 13 +#define H_FIRST_FREE 225 +#define H_MENUS_FREE 32768 + +#define MAX_HLAD(x) (((x)->vlastnosti[VLS_MAXHIT]/2+2*24)*HODINA) +#define MAX_ZIZEN(x) (((x)->vlastnosti[VLS_MAXHIT]/3+24)*HODINA) +#define concat(c,s1,s2) \ + c=alloca(strlen(s1)+strlen(s2)+1);\ + strcpy(c,s1);\ + strcat(c,s2) + +#define get_ap(vls) (((vls[VLS_POHYB])>0 && (vls[VLS_POHYB])<15)?1:(vls[VLS_POHYB])/15) + +#define SAVE_NAME_SIZE 32 + +#define mgochrana(x) (100-(x)) +//#define mgochrana(x) (1000/(10+(x))) + +//typy sektoru + +#define ISTELEPORT(c) ((c)==S_TELEPORT || (c)>=S_USERTELEPORT && (c)<=S_USERTELEPORT_END) +#define ISTELEPORTSECT(sect) ISTELEPORT(map_sectors[sect].sector_type) + +#undef S_NORMAL + +#define S_NORMAL 1 +#define S_SCHODY 2 +#define S_SMER 5 +#define S_VODA 9 +#define S_SLOUP 10 +#define S_DIRA 11 +#define S_TELEPORT 12 +#define S_LAVA 4 +#define S_LODKA 3 +#define S_TLAC_OFF 13 +#define S_TLAC_ON 14 +#define S_FLT_SMER 15 +#define S_LEAVE 19 +#define S_VIR 20 +#define S_SSMRT 21 +#define S_ACID 22 +#define S_USERTELEPORT 50 +#define S_USERTELEPORT_END 58 + +//sector flags + +#define MC_AUTOMAP 0x1 //automapovano +#define MC_FLY 0x2 //fly na sektoru +#define MC_PLAYER 0x4 //hrac na sektoru +#define MC_SHADING 0x100 //druhe stinovani (do tmy) +#define MC_DEAD_PLR 0x8 //mrtvy hrac na sektoru +#define MC_DPLAYER (MC_PLAYER | MC_DEAD_PLR) //nejaky hrac na sektoru +#define MC_SPECTXTR 0x10 //specialni textura na sektoru (viz spectxtr) +#define MC_SAFEPLACE 0x20 //bezpecne misto (pod vodou muzou dychat); +#define MC_MARKED 0x80 //oznaceny sektor (pro volne pouziti) +#define MC_DISCLOSED 0x40 //odhaleno kouzlem automapping +#define MC_SHOW_STAIRS 0x200 //obrazek schodu +#define MC_STAIRS_DOWN 0x400 //obrazek schodu dolu (nebo sipka) +#define MC_NOAUTOMAP 0x800 //nelze najit automapingem +#define MC_NOSUMMON 0x1000 //nelze privolat hrace + +//adresare +#define SR_DATA 0 +#define SR_GRAFIKA 1 +#define SR_ZVUKY 2 +#define SR_FONT 3 +#define SR_MAP 4 +#define SR_MUSIC 5 +#define SR_TEMP 6 +#define SR_BGRAFIKA 7 +#define SR_ITEMS 8 +#define SR_ENEMIES 9 +#define SR_VIDEO 10 +#define SR_DIALOGS 11 +#define SR_SAVES 12 +#define SR_WORK 13 +#define SR_CD 14 +#define SR_MAP2 15 +#define SR_ORGMUSIC 16 + +//globalni cisla k casovacum +#define TM_BACK_MUSIC 1 +#define TM_SCENE 2 +#define TM_FAST_TIMER 3 +#define TM_SOUND_RANDOMIZER 4 +#define TM_BOTT_MESSAGE 5 +#define TM_FLY 6 +#define TM_CLEAR_ZASAHY 7 +#define TM_REGEN 8 +#define TM_WAITER 9 +#define TM_SCENE2 10 +#define TM_HACKER 11 +#define TM_FX 12 +#define TM_CHECKBOX 13 +#define TM_FLETNA 14 +#define TM_DELAIER 15 +#define TM_VZPLANUTI 16 + +//umisteni predmetu + +#define PL_NIKAM 0 +#define PL_BATOH 1 +#define PL_TELO_H 2 +#define PL_TELO_D 3 +#define PL_HLAVA 4 +#define PL_NOHY 5 +#define PL_KUTNA 6 +#define PL_KRK 7 +#define PL_RUKA 8 +#define PL_OBOUR 9 +#define PL_PRSTEN 10 +#define PL_SIP 11 + +//hracovi_pozice +#define PO_BATOH 0 +#define PO_TELO_H 1 +#define PO_TELO_D 2 +#define PO_HLAVA 3 +#define PO_NOHY 4 +#define PO_KUTNA 5 +#define PO_KRK 6 +#define PO_RUKA_L 7 +#define PO_RUKA_R 8 + + +//hracovi vlastnosti + +#define VLS_MAX 24 +#define VLS_SILA 0 +#define VLS_SMAGIE 1 +#define VLS_POHYB 2 +#define VLS_OBRAT 3 +#define VLS_MAXHIT 4 +#define VLS_KONDIC 5 +#define VLS_MAXMANA 6 +#define VLS_OBRAN_L 7 +#define VLS_OBRAN_H 8 +#define VLS_UTOK_L 9 +#define VLS_UTOK_H 10 +#define VLS_OHEN 11 +#define VLS_VODA 12 +#define VLS_ZEME 13 +#define VLS_VZDUCH 14 +#define VLS_MYSL 15 +#define VLS_HPREG 16 +#define VLS_MPREG 17 +#define VLS_VPREG 18 +#define VLS_MGSIL_L 19 +#define VLS_MGSIL_H 20 +#define VLS_MGZIVEL 21 +#define VLS_DAMAGE 22 +#define VLS_KOUZLA 23 + + +//rezimy interakce + +#define MD_GAME 0 +#define MD_MAP 1 +#define MD_INV 2 +#define MD_SETUP 3 +#define MD_INBATTLE 4 +#define MD_PRESUN 5 +#define MD_PREZBROJIT 6 +#define MD_UTEK 7 +#define MD_KZ_VYBER 8 +#define MD_END_GAME 9 +#define MD_SHOP 10 +#define MD_ANOTHER_MAP 11 + +//typy map +#define ME_NORMAL 0 //normal map +#define ME_SOPKA 1 //sopka +#define ME_LEDOV 2 //ledove jeskyne +#define ME_PVODA 3 //pod vodou +#define ME_MESTO 4 //nejde sleep (ve meste) + +#define CASE_KEY_1_6 case 2:\ + case 3:\ + case 4:\ + case 5:\ + case 6:\ + case 7 + +typedef struct tdregisters + { + int h_num; + char name[13]; + void (*proc)(void **,long *); + char path; + }TDREGISTERS; + +typedef struct tstena + { + char prim,sec,oblouk,side_tag; + unsigned short sector_tag; + char xsec,ysec; + unsigned long flags; + char prim_anim,sec_anim,lclip,action; + }TSTENA; + +typedef struct tsector + { + char floor,ceil; + char flags,sector_type; //sector_type = 0 - sector not used; + char action,side_tag; + unsigned short step_next[4]; + unsigned short sector_tag; + }TSECTOR; + +typedef struct tvyklenek + { + short sector,dir,xpos,ypos,xs,ys; + short items[9]; + short reserved; + }TVYKLENEK; + + + +typedef TSTENA TSIDEDEF[][4]; +typedef TSECTOR TSECTORDEF[]; + +typedef struct tmap_edit_info + { + short x,y,layer,flags; + }TMAP_EDIT_INFO; + +typedef TMAP_EDIT_INFO TMAP_EDIT[]; + +typedef + struct mapglobal + { + char back_fnames[4][13]; + int fade_r,fade_g,fade_b; + int start_sector; + int direction; + char mapname[30]; + char map_effector; + char local_monsters; + char map_autofadefc; + }MAPGLOBAL; + +typedef struct the_timer + { + int zero; + int id; + int counter,count_max,calls; + void (*proc)(struct the_timer *); + long userdata[4]; + struct the_timer *next; + char zavora; + }THE_TIMER; + +typedef struct d_action + { + unsigned short action,sector,side,flags,nocopy,delay; + struct d_action *next; + }D_ACTION; + +extern word color_topbar[7]; + + +extern MAPGLOBAL mglob; //globalni informace o levelu +extern TSTENA *map_sides; //popisy jednotlivych sten (map_sides[(sector<<2)+dir]) +extern TSECTOR *map_sectors; //popisy sektoru map_sectors[sector] +extern TVYKLENEK *map_vyk; //mapa vyklenku +extern word vyk_max; //pocet vyklenku v mape +extern char *flag_map; //mapa prenasenych flagu +extern TMAP_EDIT_INFO *map_coord; //mapa souradnic a flagu +extern int viewsector; //aktualni sektor vyhledu +extern int viewdir; //aktualni smer vyhledu +extern THE_TIMER timer_tree; //strom casovych udalosti +extern D_ACTION *d_action; //spojovy seznam zpozdenych akci +extern char *pathtable[]; //tabulka adresaru +extern char level_preload; //informace o preloadingu +extern char **texty; //globalni tabulka textu +extern char **level_texts; //lokalni tabulka textu +extern char *level_fname; //jmeno levelu +extern int mapsize; //pocet sektoru v mape +extern int hl_ptr; //ukazatel na konec staticke tabulky registraci +extern int end_ptr; //ukazatel na uplny konec tabulky registraci +extern short **map_items; //ukazatel na mapu predmetu +extern int default_ms_cursor; //cislo zakladniho mysiho kurzoru +extern void *cur_xlat; //aktualni tabulka pro 256 barev +extern void (*unwire_proc)(); //procedura zajistujici odpojeni prave ukoncovane interakce +extern void (*wire_proc)(); //procedura zajistujici pripojeni drive ukoncene interakce +extern char cur_mode; //cislo aktualni interakce +extern word minimap[VIEW3D_Z+1][VIEW3D_X*2+1]; //minimalizovana mapa s informacemi pro sestaveni vyhledu +extern char norefresh; //vypina refresh obrazovky +extern char cancel_render; //okamzite zrusi renderovani sceny na dobu jednoho frame - nastavit na 1 pri zmene interakce!!! +extern char cancel_pass; //okamzite zrusi plynuly prechod +extern char reverse_draw ; //kresba odpredu dozadu +extern char gamespeed; //rychlost hry +extern char gamespeedbattle; //akcelerace rychlosti pro bitvy +extern int num_ofsets[]; //tabulka offsetu pro steny +extern int back_color; //cislo barvy pozadi +extern char cur_group; //cislo aktualni skupiny +extern char group_select; //1 = prave byla sestavena nova skupina +extern unsigned short barvy_skupin[POCET_POSTAV+1]; //cisla barev skupin +extern char battle; //jednicka znaci ze bezi bitva +extern char battle_mode; //rezim bitvy 0=programovani +extern char neco_v_pohybu; //jednicka znaci ze se nektere potvory jeste hejbou +extern short select_player; //vybrana postava nebo -1 +extern char group_sort[POCET_POSTAV]; //pretrideni skupin +extern char global_anim_counter; +extern char one_buffer; //1 zapina pouziti pouze jednoho bufferu pro render +extern char save_map; //1 oznamuje ze pri opusteni levelu je nutne ulozit stav mapy +extern long money; //stav konta hracu +extern long level_map[]; //tabulka urovni +extern char true_seeing; //1 oznamuje ze bezi kouzlo true_seeing +extern char set_halucination; +extern int hal_sector; //cislo sektoru a smeru pri halucinaci +extern int hal_dir; +extern char side_touched; //promena se nastavuje na 1 pri kazdem uspesnem dotyku steny +extern char *texty_knihy; //jmeno souboru s textamy knihy +extern int cur_page; //cislo stranky v knize; +extern long game_time; //hraci cas +extern char autoattack; +extern char enable_sort; +extern char last_send_action; //naposled vyslana akce +extern char see_monster; //jednicka pokud hraci vidi nestvuru +extern char lodka; +extern char anim_mirror; //je li 1 pak animace kouzel a zbrani jsou zrcadlove otocene +extern char insleep; //je li 1 pak bezi sleep +extern char pass_zavora; //je-li 1 pak bezi passing (hraci zrovna jdou) +extern short moving_player; //cislo presouvaneho hrace +extern int bgr_distance; //vzdalenost pozadi od pohledu +extern int bgr_handle; //cislo handle k obrazku pozadi; +extern char enable_glmap; //povoluje globalni mapu; +extern int charmin; +extern int charmax; + +extern int autoopenaction; +extern int autoopendata; + +extern char doNotLoadMapState; + +//debug !!!!! +extern int dhit; +extern int ddef; +extern int ddostal; +extern int dlives; +extern int dmzhit; +extern int dsee; +extern char show_debug; +extern char *debug_text; +extern char map_with_password; +extern int debug_enabled; +extern char marker; //tato promenna je 0, jen v pripade ze je 1 probehne assert +#define MARKER_SET() {SEND_LOG("(MARKER) Marker Sets",0,0);marker=1;} +#define MARKER_RESET() {SEND_LOG("(MARKER) Marker Resets",0,0);marker=0;} +#define MARKER_HIT(action) if (marker) \ + { \ + SEND_LOG("(MARKER) Marker hit!",0,0);\ + action;\ + MARKER_RESET();\ + } + +//builder - skeldal + +int set_video(int mode); +void *game_keyboard(EVENT_MSG *msg,void **usr); +void calc_animations(void); +int load_map(char *filename); +void other_draw(); +void refresh_scene(); +void pcx_fade_decomp(void **p,long *s); +void pcx_15bit_decomp(void **p,long *s); +void pcx_15bit_autofade(void **p,long *s); +void pcx_15bit_backgrnd(void **p,long *s); +void pcx_8bit_decomp(void **p,long *s); +void hi_8bit_correct(void **p,long *s); +void pcx_8bit_nopal(void **p,long *s); +void set_background(void **p,long *s); +void wav_load(void **p,long *s); +void wire_main_functs(); +void ukaz_kompas(); +void *timming(EVENT_MSG *msg,void **data); +void do_timer(); +void hold_timer(int id,char hld); +THE_TIMER *add_to_timer(int id,int delay,int maxcall,void *proc); +void delete_from_timer(int id); +THE_TIMER *find_timer(int id); +void objekty_mimo(); +void mouse_set_cursor(int cursor); +void set_font(int font,int c1,...); +void bott_draw(char); +void bott_draw_proc(); +THE_TIMER *add_to_timer(int id,int delay,int maxcall,void *proc); +void mouse_set_default(int cursor); +void create_frame(int x,int y,int xs,int ys,char clear); +void save_dump(); +void bott_disp_text(char *); +void bott_text_forever(); +char chod_s_postavama(char sekupit); +void hide_ms_at(int line); //schova mysku ktera je nad line +int cislovka(int i); +void wire_kniha(); +void purge_temps(char z); //z=1 vymaze i swapsoubor +void destroy_player_map(); //je nutne volat pred presunem postav +void build_player_map(); //je nutne volat po presunem postav +int postavy_propadnout(int sector); +void postavy_teleport_effect(int sector,int dir,int postava,char eff); +void reg_grafiku_postav(); +void play_movie_seq(char *s,int y); +void check_postavy_teleport(); //je-li viewsector=teleport pak presune postavy + +//builder +#define MAIN_NUM 0 +#define LEFT_NUM 1 +#define RIGHT_NUM 2 +#define CEIL_NUM 3 +#define FLOOR_NUM 4 +#define OBL_NUM 5 +#define OBL2_NUM 6 +#define BACK_NUM 7 + +#define MSG_DELAY (50*10) + + +extern char bott_display; //cislo udava co je zobrazeno v dolni casti +extern int vmode; +extern char runes[5]; + + +typedef struct spectxtr + { + word sector; + word handle; + char count; + char pos; + signed char xpos; + char repeat; + }SPECTXTR; + +#define MAX_SPECTXTRS 64 +typedef SPECTXTR SPECTXT_ARR[MAX_SPECTXTRS]; + +extern SPECTXT_ARR spectxtr; + +void add_spectxtr(word sector,word fhandle,word count,word repeat,integer xpos); +void calc_spectxtrs(void); +void init_spectxtrs(void); +void play_fx(int x,int y); +void draw_fx(); +void play_fx_at(int where); +void draw_blood(char mode,int mob_dostal,int mob_dostal_pocet); + //kresli krev. mode=1 nasaveni, mode=0 kresleni, pri mode=0 se parametry ignoruji + +#define FX_MAGIC 0 +#define FX_BOOK 1 +#define FX_MONEY 2 + + + + +#define BOTT_NORMAL 0 +#define BOTT_TEXT 1 +#define BOTT_FLETNA 2 +#define BOTT_RUNA 3 + + +void step_zoom(char smer); +void turn_zoom(int smer); +void a_touch(int sector,int dir); +int do_action(int action_numb,int sector,int direct,int flags,int nosend); +void delay_action(int action_numb,int sector,int direct,int flags,int nosend,int delay); +long load_section(FILE *f,void **section, int *sct_type,long *sect_size); +void prepare_graphics(int *ofs,char *names,long size,void *decomp,int class); +void show_automap(char full); +void draw_medium_map(); +void anim_sipky(int h,int mode); +void redraw_scene(); +void calc_game(); +void do_delay_actions(); +void real_krok(EVENT_MSG *msg,void **data); +void sort_groups(); +void recheck_button(int sector,char auto_action); +void start_dialog(int entr,int mob); +void show_money(); +void chveni(int i); +void render_scene(int,int); +void bott_draw_fletna(); +void bott_disp_rune(char rune, int item); +extern char noarrows; +void display_ver(int x,int y,int ax,int ay); +void check_players_place(char mode); + + +void add_leaving_place(int sector); +void save_leaving_places(void); +void load_leaving_places(void); +int set_leaving_place(void); +int get_leaving_place(char *level_name); + + +//click_map + +typedef struct t_clk_map + { + int id,xlu,ylu,xrb,yrb; + char (*proc)(int id,int xa,int ya,int xr,int yr); + char mask; + int cursor; + }T_CLK_MAP; + +#define CLK_MAIN_VIEW 17 +#define MS_GAME_WIN 256 +extern T_CLK_MAP clk_main_view[]; //clickovaci mapa pro hlavni vyhled + +void change_click_map(T_CLK_MAP *map,int mapsize); +void ms_clicker(EVENT_MSG *msg,void **usr); +void restore_click_map(void *map,int mapsize); +void save_click_map(void **map,int *mapsize); +void set_game_click_map(void); +void change_global_click_map(T_CLK_MAP *map,int mapsize); +char empty_clk(int id,int xa,int ya,int xr,int yr); //tato udalost slouzi ke zruseni nekterych mist v globalni mape +void disable_click_map(void); + +char start_invetory(int id,int xa,int ya,int xr,int yr); +char go_map(int id,int xa,int ya,int xr,int yr); +char konec(int id,int xa,int ya,int xr,int yr); +char return_game(int id,int xa,int ya,int xr,int yr); +char clk_step(int id,int xa,int ya,int xr,int yr); +char clk_touch(int id,int xa,int ya,int xr,int yr); +char go_book(int id,int xa,int ya,int xr,int yr); +char clk_saveload(int id,int xa,int ya,int xr,int yr); +char clk_sleep(int id,int xa,int ya,int xr,int yr); + + +//inventory viewer - items + +#define IT_ICONE_SIZE (2+2+2+2*256+55*45) +#define MAX_INV 30 +#define HUMAN_PLACES 9 +#define HUMAN_RINGS 4 + +extern int item_count; //pocet predmetu ve hre +extern int it_count_orgn; //puvodni pocet predmetu ve hre (pri loadmap) +extern short water_breath; //vec pro dychani pod vodou +extern short flute_item; + +void load_items(void); +void load_item_map(void *p,long s); +void draw_placed_items_normal(int celx,int cely,int sect,int side); + +#define SPL_INVIS 0x1 //hrac je neviditelny +#define SPL_OKO 0x2 //hrac ma kouzlo oko za oko +#define SPL_TVAR 0x4 //hrac ma kouzlo nastav tvar +#define SPL_DRAIN 0x8 //hrac kazdym utokem drainuje nepritele +#define SPL_MANASHIELD 0x10 //hrac je chranen stitem z many +#define SPL_SANC 0x20 //hraci je kazde zraneni snizeno na polovic +#define SPL_HSANC 0x40 //hrac nikdy nedostane zraneni vetsi nez 18 +#define SPL_BLIND 0x80 //hrac je slepy +#define SPL_REGEN 0x100 //hrac ma regeneraci pri boji +#define SPL_ICE_RES 0x200 //hrac je chranen proti ledu +#define SPL_FIRE_RES 0x400 //hrac je chranen proti ohni +#define SPL_KNOCK 0x800 //knock target back +#define SPL_FEAR 0x1000 //hrac nebo nestvura jsou posedle kouzlem "strach" +#define SPL_STONED 0x2000 //hrac nebo nestvura jsou zkamenele +#define SPL_LEVITATION 0x4000 //hrac nebo nestvura levituji, takze se na ne neuplatnuji nektere efekty sektoru +#define SPL_DEMON 0x8000 //hrac je zmenen v demona + + +#define AC_ATTACK 1 +#define AC_MOVE 2 +#define AC_CANCEL 3 +#define AC_RUN 4 +#define AC_ARMOR 5 +#define AC_STAND 6 +#define AC_MAGIC 7 +#define AC_START 8 +#define AC_THROW 9 + +#define TYP_NESPEC 0 +#define TYP_UTOC 1 +#define TYP_VRHACI 2 +#define TYP_STRELNA 3 +#define TYP_ZBROJ 4 +#define TYP_SVITEK 5 +#define TYP_LEKTVAR 6 +#define TYP_MECH 7 +#define TYP_VODA 7 +#define TYP_JIDLO 8 +#define TYP_SPECIALNI 9 +#define TYP_RUNA 10 +#define TYP_PENIZE 11 +#define TYP_SVITXT 12 +#define TYP_PRACH 13 +#define TYP_OTHER 14 + +#define ITF_DUPLIC 0x8000 //Predmet je duplikaci jineho predmetu +#define ITF_FREE 0x4000 //Predmet byl duplikaci, ted je jeho pozice volna +#define ITF_DESTROY 0x1 +#define ITF_NOREMOVE 0x2 +#define IT_FACES 5 + +#define TPW_MEC 0 +#define TPW_SEKERA 1 +#define TPW_KLADIVO 2 +#define TPW_HUL 3 +#define TPW_DYKA 4 +#define TPW_STRELNA 5 +#define TPW_OST 6 +#define TPW_MAX 7 + +#define TSP_WATER_BREATH 1 //cislo specialni veci pro dychani pod vodou +#define TSP_FLUTE 2 + +#define MAX_SLEEP 4320 + +typedef struct titem + { + char jmeno[32]; //32 Jmeno predmetu + char popis[32]; //64 + short zmeny[24]; //112 Tabulka, jakych zmen ma na hracovy vlastnosti + short podminky[4];//120 Tabulka, jake vlastnosti musi mit hrac k pouziti predmetu + short hmotnost,nosnost,druh; //126 druh = Typ predmetu + short umisteni; //128 Kam se predmet umisti? + word flags; //130 ruzne vlajky + short spell,magie,sound_handle;//136 specialni kouzla / rukojet zvuku + short use_event; //140 specialni udalost + unsigned short ikona,vzhled; //144 ikony a vzhled + short user_value; //146 uzivatelska hodnota + short keynum; //148 cislo klice + short polohy[2][2]; //156 souradnice poloh pro zobrazeni v inv + char typ_zbrane; //160 Typ zbrane + char unused; + short sound; //cislo zvuku + short v_letu[16]; //192 + int cena; + char weapon_attack; //relativni handle k souboru s animaci utok + char hitpos; //pozice zasahu animace + char shiftup; + char byteres; + short rezerva[12]; //224 rezervovane + }TITEM; + +#define PLAYER_MAX_LEVEL 40 + + +typedef struct hum_action + { + short action,data1,data2,data3; + }HUM_ACTION; + + + +typedef struct thuman + { + char used; //1 kdyz je pozice pouzita + char spell; //1 kdyz postava ma na sobe aspon 1 kouzlo. + char groupnum; //cislo skupiny 0-6 + signed char xicht; //cislo obliceje 0-5 + char direction; //smer otoceni + short sektor; //sektor postaveni + short vlastnosti[VLS_MAX]; //mapa aktualnich vlastnosti po korekcich + short bonus_zbrani[TPW_MAX]; //bonusy za zbrane + short lives; //pocet zraneni + short mana; //mnozstvi many + short kondice; //kondice postavy + short actions; //aktualni pocet AP + short mana_battery; //udaj po nabyti nakouzlene many + short stare_vls[VLS_MAX]; //mapa vlastnosti pred korekcemi + short wearing[HUMAN_PLACES]; //nosene predmety + short prsteny[HUMAN_RINGS]; //nosene prsteny + short sipy; //pocet sipu v toulci + short inv_size; //velikost inventare 6-30 + short inv[MAX_INV]; //inventar + short level; //uroven + short weapon_expy[TPW_MAX]; //zkusenosti za zbrane + long exp; //zkusenost + char female; //1 kdyz zena + char utek; //hodnota udavajici pocet kroku pri uteku + HUM_ACTION *zvolene_akce; //ukazatel na tabulku zvolenych akci + HUM_ACTION *provadena_akce; //ukazatel na aktualni akci + char programovano; //pocet programovanych akci + char jmeno[15]; //jmeno + short zasah; //posledni zasah postavy ??? + short dostal; //cislo ktere se ukazuje na obrazku s postavou jako zasah + short bonus; //bonus pro rozdeleni vlastnosti + int jidlo; //max 25000 //pocet kol o hladu zbyvajicich + int voda; //max 20000 //pocet kol o zizny zbyvajicich + struct thuman *demon_save; //ukazatel na postavu ulozenou behem kouzla demon + }THUMAN; + +extern TITEM *glob_items; //tabulka predmetu +extern int ikon_libs; +extern short *picked_item; //retezec sebranych predmetu +extern int item_in_cursor; +extern THUMAN postavy[POCET_POSTAV]; //postavy +extern THUMAN postavy_2[]; //postavy +extern THUMAN *human_selected; //vybrana postava v invetorari +extern int sleep_ticks; +extern int face_arr[IT_FACES]; +char pick_item_(int id,int xa,int ya,int xr,int yr); +void wire_inv_mode(THUMAN *select); +void init_inventory(void); +void init_items(); +void push_item(int sect,int pos,short *picked_item); +void pop_item(int sect,int pos,int mask,short **picked_item); +int count_items_inside(short *place); +int count_items_total(short *place); +char put_item_to_inv(THUMAN *p,short *picked_items); //funkce vklada predmet(y) do batohu postavy +void pick_set_cursor(); //nastavuje kurzor podle vlozeneho predmetu; +void calc_fly(); +void zmen_skupinu(THUMAN *p); +void add_to_group(int num); +void group_all(void); +void build_items_called(void **p,long *s); +void real_regeneration(); //regenerace postav behem hry v realu (pouze kondice a mana) +char sleep_regenerace(THUMAN *p); //regenerace postav behem spani +char check_jidlo_voda(THUMAN *p); +void prepocitat_postavu(THUMAN *human_selected); +void sleep_players(va_list args); //Pozor !!! TASK +void item_sound_event(int item,int sector); +short create_item_money(int obnos); //vytvori predmet penize s urcitym obnosem +char check_map_specials(THUMAN *p); +void destroy_items(short *items); //nici predmety v mysi +void do_items_specs(void); //vola specialni akci predmetu v mysi +short duplic_item(short item); //duplikuje vec a vraci id cislo klonu +int advance_vls(int id); +short create_unique_item(TITEM *it);//vytvari jedinecnou vec pro hru (jako duplikat niceho :-)) +int calculate_weight(THUMAN *p); +int weigth_defect(THUMAN *p); + + + +#define SHP_SELL 0x1 //objekt lze prodat +#define SHP_BUY 0x2 //objekt lze koupit +#define SHP_AUTOADD 0x4 //objekt pribyva casem +#define SHP_SPECIAL 0x8 //objekt se objevi jen obcas +#define SHP_TYPE 0x80 //objekt je popis typu +#define SHP_NOEDIT 0x40 //objekt se nenahrava do editoru. + +typedef struct tproduct + { + short item; //cislo predmetu ktere nabizi + int cena; //cena za jeden + short trade_flags; //vlajky + int pocet; //pocet predmetu na sklade + int max_pocet; + }TPRODUCT; + +typedef struct tshop + { + char keeper[16]; + char picture[13]; + int koef; + int products; + int shop_id; + int list_size; + short spec_max; //maximalni pocet specialnich predmetu + TPRODUCT *list; + }TSHOP; + + +void enter_shop(int shopid); +void load_shops(void); +void reroll_all_shops(); +char save_shops(); +char load_saved_shops(); + +//macros + +#define MAX_ACTIONS 40 +#define MA_GEN 0 +#define MA_SOUND 1 +#define MA_TEXTG 2 +#define MA_TEXTL 3 +#define MA_SENDA 4 +#define MA_FIREB 5 +#define MA_DESTI 6 +#define MA_LOADL 7 +#define MA_DROPI 8 +#define MA_DIALG 9 +#define MA_SSHOP 10 +#define MA_CLOCK 11 +#define MA_CACTN 12 +#define MA_LOCK 13 +#define MA_SWAPS 14 +#define MA_WOUND 15 +#define MA_IFJMP 16 +#define MA_CALLS 17 +#define MA_HAVIT 18 +#define MA_STORY 19 +#define MA_IFACT 20 +#define MA_SNDEX 21 +#define MA_MOVEG 22 +#define MA_PLAYA 23 +#define MA_CREAT 24 +#define MA_ISFLG 25 +#define MA_CHFLG 26 +#define MA_CUNIQ 27 +#define MA_MONEY 28 +#define MA_GUNIQ 29 +#define MA_PICKI 30 +#define MA_WBOOK 31 +#define MA_RANDJ 32 +#define MA_ENDGM 33 +#define MA_GOMOB 34 +#define MA_SHRMA 35 +#define MA_MUSIC 36 +#define MA_GLOBE 37 //global events +#define MA_IFSEC 38 //if sector num +#define MA_IFSTP 39 //if sector type + +#define MAGLOB_LEAVEMAP 0 // v urcitou nastavenou hodinu a minutu dene +#define MAGLOB_STARTSLEEP 1 // postavy maji jit spat. +#define MAGLOB_ENDSLEEP 2 // postavy se probouzi +#define MAGLOB_CLICKSAVE 3 // ped otevenm SAVE dialogu +#define MAGLOB_AFTERSAVE 4 // po uloen hry +#define MAGLOB_BEFOREMAGIC 5 // ped vyvolnm kouzla +#define MAGLOB_AFTERMAGIC 6 //po vyvoln kouzla +#define MAGLOB_BEFOREMAPOPEN 7 //ped otevenm mapy +#define MAGLOB_AFTERMAPOPEN 8 //po uzaven mapy +#define MAGLOB_BEFOREBATTLE 9 //ped sputnm souboje +#define MAGLOB_AFTERBATTLE 10 //po ukonen souboje +#define MAGLOB_BEFOREBOOK 11 //pred otevenm knihy +#define MAGLOB_AFTERBOOK 12 //po uzaven knihy +#define MAGLOB_ONROUND 13 //pi kadm kole nebo po 10s +#define MAGLOB_ONDEADMAN 14 //pi umrt mue +#define MAGLOB_ONDEADWOMAN 15 //pi umrt eny +#define MAGLOB_ONDEADALL 16 //pi umrt vech postav +#define MAGLOB_ONHITMAN 17 //pi zsahu mue +#define MAGLOB_ONHITWOMAN 18 //pi zsahu eny +#define MAGLOB_ONNEWRUNE 19 //pi nalezen nov runy +#define MAGLOB_ONPICKITEM 20 //pi sebrn pedmtu (pro speciln pedmty) +#define MAGLOB_ONSTEP 21 //pi kroku (ped animaci) +#define MAGLOB_ONTURN 22 //pi otoen (ped animaci) +#define MAGLOB_ALARM 23 //pi sputn alarmu +#define MAGLOB_ONFIREMAGIC 24 +#define MAGLOB_ONWATERMAGIC 25 +#define MAGLOB_ONGROUNDMAGIC 26 +#define MAGLOB_ONAIRMAGIC 27 +#define MAGLOB_ONMINDMAGIC 28 +#define MAGLOB_ONSPELLID1 29 //pi jednom konrtnm kouzle +#define MAGLOB_ONSPELLID2 30 //pi jednom konrtnm kouzle +#define MAGLOB_ONSPELLID3 31 //pi jednom konrtnm kouzle +#define MAGLOB_ONSPELLID4 32 //pi jednom konrtnm kouzle +#define MAGLOB_ONSPELLID5 33 //pi jednom konrtnm kouzle +#define MAGLOB_ONSPELLID6 34 //pi jednom konrtnm kouzle +#define MAGLOB_ONSPELLID7 35 //pi jednom konrtnm kouzle +#define MAGLOB_ONSPELLID8 36 //pi jednom konrtnm kouzle +#define MAGLOB_ONSPELLID9 37 //pi jednom konrtnm kouzle +#define MAGLOB_ONTIMER1 38 //cas - pocet hernich sekund od nastaveni +#define MAGLOB_ONTIMER2 39 //cas - pocet hernich sekund od nastaveni +#define MAGLOB_ONTIMER3 40 //cas - pocet hernich sekund od nastaveni +#define MAGLOB_ONTIMER4 41 //cas - pocet hernich sekund od nastaveni +#define MAGLOB_ONFLUTE1 42 //zahrani urcite melodie +#define MAGLOB_ONFLUTE2 43 //zahrani urcite melodie +#define MAGLOB_ONFLUTE3 44 //zahrani urcite melodie +#define MAGLOB_ONFLUTE4 45 //zahrani urcite melodie +#define MAGLOB_ONFLUTE5 46 //zahrani urcite melodie +#define MAGLOB_ONFLUTE6 47 //zahrani urcite melodie +#define MAGLOB_ONFLUTE7 48 //zahrani urcite melodie +#define MAGLOB_ONFLUTE8 49 //zahrani urcite melodie + +#define MAGLOB_NEXTID 50 //mus bt posledn + + + + +#define MC_PASSSUC 0x1 +#define MC_PASSFAIL 0x2 +#define MC_TOUCHSUC 0x4 +#define MC_TOUCHFAIL 0x8 +#define MC_LOCKINFO 0x10 +#define MC_EXIT 0x20 +#define MC_INCOMING 0x40 +#define MC_STARTLEV 0x80 +#define MC_CLOSEDOOR 0x100 +#define MC_ANIM 0x200 +#define MC_ANIM2 0x400 +#define MC_SUCC_DONE 0x800 +#define MC_SPEC_SUCC 0x1000 +#define MC_OPENDOOR 0x2000 +#define MC_VYKEVENT 0x4000 +#define MC_WALLATTACK 0x8000 + +typedef struct tma_gen + { + unsigned action : 6; + unsigned cancel : 1; + unsigned once : 1; + unsigned flags : 16; + }TMA_GEN; + +typedef struct tma_sound + { + char action,flags,eflags; //3 + char bit16; + char volume; //5 + char soundid; //6 + unsigned short freq; //8 + long start_loop,end_loop,offset;//20 + char filename[12]; //32 + }TMA_SOUND; + + +typedef struct tma_text + { + char action,flags,eflags,pflags; + long textindex; + }TMA_TEXT; + +typedef struct tma_send_action + { + char action,flags,eflags,change_bits; + unsigned short sector,side,s_action; + char delay; + }TMA_SEND_ACTION; + +typedef struct tma_fireball + { + char action,flags,eflags; + short xpos,ypos,zpos,speed,item; + }TMA_FIREBALL; + +typedef struct tma_loadlev + { + char action,flags,eflags; + short start_pos; + char dir; + char name[13]; + }TMA_LOADLEV; + + + +typedef struct tma_dropitm + { + char action,flags,eflags; + short item; + }TMA_DROPITM; + +typedef struct tma_codelock + { + char action,flags,eflags; + char znak; + char string[8]; + char codenum; + }TMA_CODELOCK; + +typedef struct tma_cancelaction + { + char action,flags,eflags,pflags; + short sector,dir; + }TMA_ACTN; + +typedef struct tma_swapsectors + { + char action,flags,eflags,pflags; + short sector1,sector2; + }TMA_SWAPS; + +typedef struct tma_wound + { + char action,flags,eflags,pflags; + short minor,major; + }TMA_WOUND; + + + +typedef struct tma_lock + { + char action,flags,eflags; + short key_id; + short thieflevel; + }TMA_LOCK; + +typedef struct tma_two_parms + { + char action,flags,eflags; + short parm1,parm2; + }TMA_TWOP; + +typedef struct tma_create_unique + { + char action,flags,eflags; + TITEM item; + }TMA_UNIQUE; + +typedef struct tma_globe + { + char action,flags,eflags,event; //event - MAGLOB_XXXX + unsigned short sector; //sektor of action target, when event occured + unsigned char side; //side of action target, when event occured + unsigned char cancel; //1 - cancel event + unsigned long param; //event depend param - zero is default + }TMA_GLOBE; + + +typedef struct tma_ifsec +{ + char action,flags,eflags; + unsigned char side; //side of action target, when event occured + unsigned short sector; //sektor of action target, when event occured + short line; //jump line + char invert; //invert condition +}TMA_IFSEC; + + + +extern TMA_LOADLEV loadlevel; + +typedef union tmulti_action + { + struct tma_gen general; + struct tma_sound sound; + struct tma_text text; + struct tma_send_action send_a; + struct tma_fireball fireball; + struct tma_loadlev loadlev; + struct tma_dropitm dropi; + struct tma_codelock clock; + struct tma_cancelaction cactn; + struct tma_lock lock; + struct tma_swapsectors swaps; + struct tma_wound wound; + struct tma_two_parms twop; + struct tma_create_unique uniq; + struct tma_globe globe; + struct tma_ifsec ifsec; + }TMULTI_ACTION; + +extern int **macros; //tabulka maker +extern void *macro_block; //alokovany blok maker (pri unloadu free!) +extern int macro_block_size; //velikost bloku; + +void load_macros(int size,void *data); +void call_macro(int side,int flags); +void call_macro_ex(int side,int flags, int runatsect); +char get_player_triggered(int p); //zjistuje zda hrac s cislem p byl makrem zasazen; +char save_load_trigger(short load); //uklada/obnovuje trigger vlajky. -1 uklada, jinak hodnota ulozeneho triggeru +char save_codelocks(FILE *fsta); //uklada do savegame nastaveni kodovych zamku (128 bytu); +char load_codelocks(FILE *fsta); //obnovuje ze savegame nastaveni kodovych zamku (128 bytu); + + +typedef struct letici_vec + { + struct letici_vec *next; + int sector,smer; + int xpos,ypos,zpos; + short item; + short *items; + int counter; + char anim_pos; + char flags; + short owner; + int speed; + int velocity; + short hit_bonus; + short damage; + short lives; + }LETICI_VEC; + + +extern LETICI_VEC *letici_veci; //spojovy seznam leticich veci +extern LETICI_VEC *letici_veci2; //spojovy seznam leticich veci aktualni pred zahajenim renderace +#define FLY_NEHMOTNA 1 //leti rovne +#define FLY_DESTROY 2 //znici se +#define FLY_DESTROY_SEQ 4 //bezi nicici sekvence +#define FLY_NEDULEZITA 8 //nema vliv na souboj +#define FLY_IN_FLY 16 //Nastaveno, pokud fly ma vliv na okoli (v letu) +#define FLY_BURNT 32 //vyhorela - bude uvolnena +#define FLY_UNUSED 64 //nevyuzita - muze byt uvolnena +#define TFLY LETICI_VEC +LETICI_VEC *throw_fly(int x,int y, char rovne); + +/* postup pri niceni fly + +Pri triggeru zniceni + 1) Je Destroy? - > nastav DESTROY_SEQ + 2) Po zniceni -> nastav BURNT + 3) Pokud je pri zpracovani BURNT -> nastav UNUSED + 4) Pokud je unused -> vymaz ji + +Tento slozity postup je zaveden, z duvodu viceulohoveho zpracovani, aby mel +system jistotu ze vsechny pripadne kopie fly jsou znicene a neukazuji + na neplatne objekty + + Zkratka - pokud je fly znicena, musi ji system potvrdit jeste vlajkou UNUSED, aby + ji mohl uvolnit + */ + +LETICI_VEC *create_fly(); //vytvari fly - optimalizuje tim ze hleda nevyuzity fly nosice, a teprve pokud neuspeje alokuje novy prostor. +void draw_fly_items(int celx,int cely,int sector,int side); +void add_fly(LETICI_VEC *p); +void build_fly_map(); +void destroy_fly_map(); +void stop_fly(LETICI_VEC *p,char zvuk); + + + +//gamesaver +void leave_current_map(); +int save_map_state(); //uklada stav mapy pro savegame (neuklada aktualni pozici); +int load_map_state(); //obnovuje stav mapy; nutno volat po zavolani load_map; +void restore_current_map(); //pouze obnovuje ulozeny stav aktualni mapy +int load_game(int slotnum); +int save_game(int slotnum,char *gamename); +void wire_save_load(char save); +#define autosave() if (autosave_enabled) save_game(9,"AUTOSAVE"); +extern char autosave_enabled; +int load_map_automap(char *mapfile); + /* ^^^ Tato funkce zmeni mapu, bez zmeny grafiky a stavu cele hry. + Jeji vyuziti je pro zobrazeni automapingu jineho levelu nez aktualniho + Pred navratem do hry je treba udelat load_map_automap(level_fname);!!!*/ + +//setup +char q_runsetup(char *); +void user_setup(); +void setup_dialoge(); +char game_setup(int id,int xa,int ya,int xr,int yr); +void GamePause(); +void show_textured_button(int x,int y,int xs,int ys,int texture,void *border3d); + +//sounder & music + +extern short sample_volume; //hlastitost samplu +extern char **sound_table; + +void init_tracks(); +void recalc_volumes(int sector,int side); +void play_effekt(int x,int y,int xd,int yd,int side,int sided,TMA_SOUND *p); +void create_playlist(char *playlist); +void play_next_music(char **c); +void purge_playlist(); +void restore_sound_names(); +void play_sample_at_sector(int sample,int sector1,int sector2,int track, char loop); +void play_sample_at_channel(int sample,int channel,int vol); +void stop_track(int track); +char test_playing(int track); +void stop_track_free(int track); +void mute_all_tracks(char all); +void kill_all_sounds(); +void create_sound_table(char *template,long size); +void create_sound_table_old(); +void start_play_flute(); +void stop_play_flute(); +void pc_speak_play_sample(char *sample,int size,char step,int freq); +char enable_sound(char enbl); + + +//enemy +#define MOBS_INV 16 +#define MOB_POSIT 0 +#define MOB_ATTACK 1 +#define MOB_TOHIT 2 + +#define MAX_MOBS 255 + + +#define MOB_IN_BATTLE 0x1 +#define MOB_ATTACKING 0x2 +#define MOB_TO_HIT 0x4 +#define MOB_DEATH 0x5 +#define MOB_START 1 + +#define MOB_WALK 0x1 +#define MOB_WATCH 0x2 +#define MOB_LISTEN 0x4 +#define MOB_BIG 0x8 +#define MOB_GUARD 0x10 +#define MOB_PICK 0x20 +#define MOB_PICKING 0x40 +#define MOB_ROGUE 0x80 +#define MOB_SENSE 0x4 +#define MOB_PASSABLE 0x2 +#define MOB_MOBILE 0x8 +#define MOB_RELOAD 0x10 +#define MOB_SAMPLE_LOOP 0x40 +#define MOB_LIVE 0x80 //potvora zije +#define MOB_CASTING 0x20 + +typedef struct tmob + { + char name[30]; //jmeno moba + short casting; + short adjusting[6*16]; //volba stredu pro animace + word sector,dir; //pozice + char locx,locy; //presna pozice + char headx,heady; //pozice kam mob miri + short anim_counter; //citac animaci + short vlastnosti[24]; //zakladni vlastnosti potvory + short inv[MOBS_INV]; //batoh potvory + short lives; //pocet zivotu potvory + short cislo_vzoru; //informace urcujici ze ktereho vzoru byl mob vytvoren + short speed; //rychlost pohybu + short dohled; //kam dohldne + short dosah; //okamik zatku souboje + char stay_strategy; //chovani moba ve statickem modu (nepronasleduje) + char walk_data; //cislo potrebne pro pohyb moba v bludisti + word bonus; //bonus za zabiti + char flee_num; //pravdepodobnost uteku + char anim_counts[6]; //pocet animacnich policek pro kazdy pohyb + char mobs_name[7]; //zaklad jmena souboru pro moba + long experience; //zkusenost + char vlajky; //BIT0 - 1 v boji + char anim_phase; //cinnost kterou mob dela + short csektor; //Cilovy sektor + short home_pos; //domaci pozice + short next; //Cislo dalsiho moba, ktery stoji na jeho pozici + char actions; //pocet akci ktere muze potvora provest v kole + char hit_pos; //animacni pozice, kdy potvora zasahne + word sounds[4]; //zvuky z listu + signed char palette; // pocet pouzitelnych palet / cislo palety + char mode; //akce potvory + short dialog; //cislo dialogu, -1 kdyz neni; + char dialog_flags; //vlajky mapovane do dialogu; + word money; //penize + word specproc; //specproc + word dostal; //pocet zivotu, ktere mu byly ubrany poslednim zasahem + char user_data; //data uzivatelem definovane - treba pro spec. + }TMOB; + + +extern TMOB mobs[MAX_MOBS]; +extern char *mob_map; + +void draw_mob(int num,int curdir,int celx,int cely,char shiftup); +void calc_mobs(); +void najdi_cestu(word start,word konec,int flag,word **cesta, int aimbig); +void sirit_zvuk(word start); +void check_all_mobs(); +void build_all_players(); +void init_mobs(); +void refresh_mob_map(); +char akce_moba_zac(TMOB *m); +void mob_animuj(); //animuje prave bojovou akci potvor na sektoru +void sleep_enemy(char regen); +int vyber_potvoru(int sect,int dir,int *z); +void mob_hit(TMOB *mm,int dostal); +int mob_alter(int sect); +void check_all_mobs_battle(); //kontroluje zda je nekdo v battle +void manashield_check(short *vls,short *lives,short *mana,int dostal); +char track_mob(int sect,int dir);//trackuje pritomnost potvory v urcitem smeru +void stop_all_mobs(); +int utok_na_sektor(THUMAN *p,TMOB *m,int chaos,int bonus); +int vyber_potvoru(int sect,int dir,int *chaos); //vybere potvoru ze sektoru a smeru. Vraci take pocet potvor v promenne *chaos +void load_enemies(short *data,int size,int *grptr,TMOB *template,long tsize); +char mob_test_na_bitvu(TMOB *p); //nastavi p->vlajky|MOB_INBATTLE pokud potvora muze vstoupit do bitvy; +void send_mob_to(int m,word *path); +void save_enemy_paths(FILE *f); +int load_enemy_paths(FILE *f); +void regen_all_mobs(); + + +//souboje +extern int mob_dostal; // ikona pro zasah moba +extern int mob_dostal_pocet; // ciselna hodnota toho kolik mob dostal; +extern short vybrana_zbran; //zbran_kterou utoci select_player; +extern char mute_hit_sound; //nastavit, pokud je nutne zabranit zvuku vzdechy, automaticky se resetuje +extern int hromadny_utek; //1 postavy utikaji hromadne. + +extern char running_battle; + +#define MAX_WEAPON_SKILL 10 + +void zacni_souboj(TMOB *p,int delka,short sector); +char q_zacit_souboj(TMOB *p,int d,short sector); +void stop_mob(TMOB *p); +void start_battle(); +int vypocet_zasahu(short *utocnik,short *obrance, int chaos,int zbran,int bonusplus); +void rozhodni_o_smeru(TMOB *p); +void krok_moba(TMOB *p); +void pomala_regenerace_postavy(THUMAN *p); +char zasah_veci(int sector,TFLY *fl); +void vymaz_zasahy(THE_TIMER *q); +char check_end_game(); +void wire_end_game(); +void auto_group(); +void wire_fly_casting(int i); +void konec_kola(); +void send_experience(TMOB *p,int dostal); +void send_weapon_skill(int druh); +void check_player_new_level(THUMAN *p); +void poloz_vsechny_predmety(); +char player_check_death(THUMAN *p, char afterround); //pokud je battle, nezabije postavu, ale az po skonceni kola (afterround==1) +char player_hit(THUMAN *p,int zraneni,char manashield); +void enforce_start_battle(); +void pozdrz_akci(); +void uprav_podle_kondice(THUMAN *p,int *chaos); //upravi parametr chaos podle kondice pro obranu +THUMAN *isplayer(int sector,THUMAN *h,char death); + /* Vraci nasledujiciho hrace na sektoru. Pokud je h==NULL vraci prvniho. + pokud je vysledek NULL neni dalsiho hrace + Death=1 pocita i mrtvoly + */ +int trace_path(int sector,int dir); //zjistuje zda je mozne strilet + + +int numplayers(int sector,char death); + /* Vraci pocet hracu na sektoru, death=1 pocita i mrtvoly */ +TMOB *ismonster(int sector,TMOB *m); + /* Vraci dalsi nestvuru na sektoru, pokud je m==NULL vraci prvni. + Pokud je vysledek NULL neni nestvura na sektoru*/ + +void correct_level(); + + + +//kouzla +extern char running_anm; +extern short teleport_target; +extern char hlubina_level; +extern word *anim_render_buffer; +extern char spell_cast; //0=neni rezim vyberu kouzla; + +#define isdemon(p) ((p)->stare_vls[VLS_KOUZLA] & SPL_DEMON) + + +void kouzla_init(); +void test_play(int handle); +void cast(int num,THUMAN *p,int owner,char backfire); +int add_spell(int num,int cil,int owner,char noanim); +void klicovani_anm(void *target,void *source,char mirror); +//#pragma aux klicovani_anm parm [edi][esi][eax] modify [ecx edx ebx] +int get_spell_color(THUMAN *p,int num); +int get_spell_mana(int num); +int get_spell_um(int num); +char ask_who(int num); +void display_spell_in_icone(int handle,int xicht); +void reinit_kouzla_full(); +char get_rune_enable(THUMAN *p,int strnum); +void remove_all_mob_spells(); +int save_spells(FILE *f); +int load_spells(FILE *f); +char get_spell_track(int num); +void mob_cast(int num,TMOB *m,int mob_num); +void thing_cast(int num,int postava,int sector,TMOB *victim,char noanim);//vyvolavaji veci +void area_cast(int num,int sector,int owner,char noanim); +int select_teleport_target(); +char get_spell_teleport(int num); +void spell_throw(int cil,int what); //to je procedura ktera umoznuje potvoram strilet +void play_big_mgif_animation(int block); +void unaffect_demon(int cil); //ukonci demona pri jeho smrti +char *get_rune_name(int strnum); +void spell_sound(char *name); + + +//interface +#define WINCOLOR RGB555(24,24,24) // 11000 11000 0 11000 +#define BAR_COLOR RGB555(15,13,11) +#define SETUP_COL1 RGB555(20,31,20) +#define SETUP_COL2 RGB555(31,31,12) +#define S_WINPOS_X 100 +#define S_WINPOS_Y 100 +#define S_WINPOS_XS 320 +#define S_WINPOS_YS 300 + +typedef struct enc_file + { + FILE *f; + char *to_delete; + }ENCFILE; + +void add_window(int x,int y,int xs,int ys,int texture,int border,int txtx,int txty); +int message(int butts,char def,char canc,char *keys,...); +void type_text(); //event procedura (parms: X,Y,TEXT,MAX_SPACE,MAX_CHARS); +void type_text_v2(va_list args);//char *text_buffer,int x,int y,int max_size,int max_chars,int font,int color,void (*exit_proc)(char)); +void zalamovani(char *source,char *target,int maxxs,int *xs,int *ys); +void col_load(void **data,long *size); +void open_story_file(); +void write_story_text(char *text); +void close_story_file(); +char labyrinth_find_path(word start,word konec,int flag,char (*proc)(word),word **cesta); + //tato procedura je obecne hledani cesty. Start - startovni cislo sektoru + //Konec - cilove cislo sektoru + //flag - je podminkovy flag pro nepruchozi steny + //proc - je procedura volana pro kazdy sektor + //cesta - je ukazatel na ukazatel na vyslednou cestu + //pokud je cesta=NULL pak vraci pouze zda cesta existuje ci nikoliv +void radio_butts_gr(); +void start_check(); //testuje stav pocitace a rozhodne zda lze program spustit +void check_number_1phase(char *exename); //check serial number! Task!// +void animate_checkbox(int first_id,int last_id,int step); +void fletna_pridej_notu(char note); +void check_fletna(); +char fletna_get_buffer_pos(); +void check_global_fletna(); +void fletna_glob_add_note(char note); + + +char *find_map_path(char *filename); //vyhledava jmeno mapy v alternativnich cestach. + //Vysledny retezec je nutne uvolnit (free) ! +FILE *enc_open(char *filename,ENCFILE *fil); //dekoduje a otevira TXT soubor (ENC) +void enc_close(ENCFILE *fil); //uzavira dekodovany soubor. +int load_string_list_ex(char ***list,char *filename); + +int smlouvat_nakup(int cena,int ponuka,int posledni,int puvod,int pocet); +int smlouvat_prodej(int cena,int ponuka,int posledni,int puvod,int pocet); +int smlouvat(int cena,int puvod,int pocet,int money,char mode); + +void disable_intro(); +void show_jrc_logo(char *filename); + + +//dialogy +void call_dialog(int entr,int mob); +char save_dialog_info(FILE *f); +char load_dialog_info(FILE *f); +short *q_item_one(int i,int itnum); //test zda postava i ma vec itnum +short *q_item(int itnum,int sector); //test zda-li aspon jeden na sectoru ma vec itnum +void change_flag(int flag,char mode); //meni vlajku = 0 - reset, 1 - set, 2 - neg +char test_flag(int flag); //vraci stav vlajky; + + + +//generator +char enter_generator(); + +//kniha +#define add_to_book(odst) add_text_to_book(texty_knihy,odst) +void add_text_to_book(char *filename,int odst); +void write_book(int page); +int count_pages(); +void save_book(); +void load_book(); +void prekodovat(char *c); + + +//menu +int enter_menu(char open); //task! +void titles(va_list args); //task! +void run_titles(va_list args); //task! +void effect_show(va_list args); //effektni zobrazeni // task! +void konec_hry(); + + +//globmap +void wire_global_map(); +void wire_automap_file(char *mapfile); +char set_select_mode(char mode); + +void PodporaStitu(THUMAN *h, short *vlastnosti); + +typedef struct _tag_globalEventDef +{ + unsigned short sector; //sektor of action target, when event occured + unsigned char side; //side of action target, when event occured + unsigned char cancel; // + long param; //event depend param - zero is default +}SGlobalEventDef; + +extern SGlobalEventDef GlobEventList[MAGLOB_NEXTID]; + +static __inline char GlobEvent(int event, int sector, int side) +{ + if (GlobEventList[event].sector || GlobEventList[event].side) + call_macro_ex(sector*4+side,MC_INCOMING,GlobEventList[event].sector*4+GlobEventList[event].side); + return !GlobEventList[event].cancel; +} + + +static __inline char GlobEvents(int firstevid, int lastevid, int sector, int side, long param) +{ + int i; + for (i=firstevid;i<=lastevid;i++) if (GlobEventList[i].param==param) + { + return GlobEvent(i,sector,side); + } + return 1; +} + + +static __inline char TimerEvents(int sector, int side, long time) +{ + int i; + for (i=MAGLOB_ONTIMER1;i<=MAGLOB_ONTIMER4;i++) if (GlobEventList[i].param && GlobEventList[i].param<=time) + { + GlobEventList[i].param=0; + return GlobEvent(i,sector,side); + } + return 1; +} + +//extras +#include "extras.h" diff --git a/GAME/GLOBMAP.C b/GAME/GLOBMAP.C new file mode 100644 index 0000000..42f6271 --- /dev/null +++ b/GAME/GLOBMAP.C @@ -0,0 +1,662 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "engine1.h" +#include +#include "globals.h" + +#define GLOBMAP "GLOBMAP.DAT" + +#define ODDELOVACE ";:=,\n{}" +#define OD_COMMAND oddelovace[0] +#define OD_CRIT oddelovace[1] +#define OD_SET oddelovace[2] +#define OD_COMMA oddelovace[3] +#define OD_NEWLINE oddelovace[4] +#define OD_IN oddelovace[5] +#define OD_OUT oddelovace[6] +#define OD_COMMENT '`' + +#define INDEXU 256 + +typedef struct index_def + { + char mapname[13]; + char *text; + char defined; + }INDEX_DEF; + +static INDEX_DEF *index_tab=NULL; +static char last_index=1; + +static int usemap; + +static FILE *glbm; +static char oddelovace[]=ODDELOVACE; +static last_oddelovac; +static linecounter=0; +static int enter_sector=0; +static char *symbolmap[]= + { + "A !", + "B &&", + "D BREAK", + "O CURMAP", // krit + "E DRAW", + "F ESCAPE", + "G FLG", // krit + "P IFDEF", // krit + "I INDX", + "I INDEX", + "K MAP", + "Q SEKTOR", // krit + "Q SECTOR", // krit + "L TEXT", + "M UNDEF", + "N USEMAP", + "C ||", + }; + +#define OP_NOT 'A' +#define OP_AND 'B' +#define OP_OR 'C' +#define OP_INDX 'I' +#define OP_DRAW 'E' +#define OP_TEXT 'L' +#define OP_MAP 'K' +#define OP_UNDEF 'M' +#define OP_FLG 'G' +#define OP_USEMAP 'N' +#define OP_BREAK 'D' +#define OP_ESCAPE 'F' +#define OP_CURMAP 'O' +#define OP_ISDEF 'P' +#define OP_SEKTOR 'Q' + +#define ODD last_oddelovac + +static char cti_int_num(int *readed) + { + return !fscanf(glbm,"%d",readed); + } + +static int find_symbol(char **symbolmap,int list_len,int offset,char *symbol) + { + int start_pos; + char chr=0; + + start_pos=0; + while (start_pos*symbol) return -1; + if (chr && ss[offset-1]!=chr) return -1; + start_pos++; + } + if (*symbol) return -1; + return start_pos; + } + +static char get_symbol(char *symb) + { + int i; + + i=find_symbol(symbolmap,sizeof(symbolmap)/sizeof(char *),2,symb); + if (i==-1) return 0;else return symbolmap[i][0]; + } + +static int cti_oddelovac(void)//cte prvni oddelovac - preskakuje mezery + { + int c; + do + { + c=getc(glbm); + if (c==OD_COMMENT) while((c=getc(glbm))!='\n'); + if (c=='\n') linecounter++; + if (strchr(oddelovace,c)!=NULL || c==EOF) return c; + } + while (c==' ' || c=='\x9'); + ungetc(c,glbm); + return 0; + } + +static int cti_retezec(int znaku,char *text,char mezera,char upcase) + { + int c; + + znaku--; + if (mezera) + { + while((c=getc(glbm))==32 || c==9); + } + else c=getc(glbm); + while (strchr(oddelovace,c)==NULL && ((c!=32 && c!=9) || !mezera) && c!=EOF) + { + if (upcase) c=toupper(c); + if (znaku) + { + *text++=c; + znaku--; + } + c=getc(glbm); + } + if (c!=32 && c!=9) ungetc(c,glbm); + *text=0; + return 0; + } + +static void error(char *text) + { + char popis[300]; + + sprintf(popis,"Chyba v souboru "GLOBMAP" na radce %d.\r\n%s",linecounter,text); + SEND_LOG("(ERROR) %s : %s",popis,text); + closemode(); + MessageBox(NULL,popis,NULL,MB_OK|MB_ICONSTOP); + exit(0); + } + +static void ex_error(char znak) + { + char ex_text[100]; + + sprintf(ex_text,"Ocekava se znak '%c'",znak); + error(ex_text); + } + +static void ready_index_tab(void) + { + index_tab=NewArr(INDEX_DEF,INDEXU); + memset(index_tab,0,INDEXU*sizeof(INDEX_DEF)); + } + +static void purge_index_tab(void) + { + if (index_tab) + { + int i; + for(i=0;i<255;i++) if (index_tab[i].text!=NULL) free(index_tab[i].text); + free(index_tab); + index_tab=NULL; + } + } + +static char test_kriterii(void) + { + char last_op=0; + char not_op=0; + char text[128]; + char hodn; + char vysl=0; + char symb,*c; + + while (ODD==0 || ODD==OD_NEWLINE) + { + cti_retezec(100,text,1,1); + c=text;if (*c=='!') not_op=1,c++; + symb=get_symbol(c); + switch (symb) + { + case OP_AND:last_op=1;break; + case OP_NOT:not_op=!not_op;break; + case OP_OR:last_op=0;break; + case OP_SEKTOR: + { + int c; + if (cti_int_num(&c)) error("Oekv se slo"); + hodn=c==enter_sector; + } + break; + case OP_CURMAP:cti_retezec(100,text,1,1); + hodn=!strcmp(level_fname,text); + break; + case OP_ISDEF:{ + int c; + if (cti_int_num(&c)) error("Oekv se slo"); + hodn=index_tab[c].defined; + } + break; + case OP_FLG: + { + int flag_num; + + if (cti_int_num(&flag_num)) error("Za FLG mus bt slo!"); + if (flag_num>255) error("slo vlajky (FLG) mus bt v rozsahu 0-255!"); + hodn=(test_flag(flag_num)!=0); + } + break; + default: + { + char c[200]; + sprintf(c,"%s%s.TMP",pathtable[SR_TEMP],text); + hodn=!access(c,0); + } + break; + } + hodn^=not_op;not_op=0; + if (last_op) vysl&=hodn;else vysl|=hodn; + ODD=cti_oddelovac(); + } + return vysl; + } + +static char proved_prikaz() + { + char prikaz[20]; + char text[128]; + int c; + char op; + + ODD=cti_oddelovac(); + while (ODD==OD_NEWLINE) ODD=cti_oddelovac(); //preskoc prazdne radky + if (ODD==OD_IN) return 0; //cti znak { + do + { + while (ODD==OD_NEWLINE || ODD==OD_COMMAND) ODD=cti_oddelovac(); + if (ODD!=0) error("Oekv se jmno definice (pklad: INDX=)"); + cti_retezec(20,prikaz,1,1); + op=get_symbol(prikaz); + if (op==OP_BREAK) return 1; + ODD=cti_oddelovac(); + if (ODD!=OD_SET) ex_error(OD_SET); + switch(op) + { + case OP_INDX: + if (cti_int_num(&c)) error("INDX=?"); + if (c<0 || c>255) error("INDX=<0,255>"); + index_tab[last_index=c].defined=1; + break; + case OP_TEXT: + cti_retezec(128,text,0,0); + index_tab[last_index].text=NewArr(char,strlen(text)+1); + strcpy(index_tab[last_index].text,text); + break; + case OP_MAP: + cti_retezec(13,index_tab[last_index].mapname,1,1); + break; + case OP_DRAW: + { + char file[20]; + int xp,yp; + int h; + + cti_retezec(20,file,1,1); + ODD=cti_oddelovac();if (ODD!=OD_COMMA)ex_error(OD_COMMA); + if (cti_int_num(&xp)) error("Oekv se slo xp"); + ODD=cti_oddelovac();if (ODD!=OD_COMMA)ex_error(OD_COMMA); + if (cti_int_num(&yp)) error("Oekv se slo yp"); + h=find_handle(file,pcx_8bit_decomp); + if (h==-1) def_handle(h=end_ptr++,file,pcx_8bit_decomp,SR_DIALOGS); + put_picture(xp,yp+SCREEN_OFFLINE,ablock(h)); + } + break; + case OP_UNDEF: + if (cti_int_num(&c)) error("UNDEF=?"); + if (c<0 || c>255) error("UNDEF=<0,255>"); + index_tab[c].defined=0; + break; + case OP_USEMAP: + { + char file[20]; + cti_retezec(20,file,1,1); + usemap=find_handle(file,pcx_8bit_nopal); + if (usemap==-1) def_handle(usemap=end_ptr++,file,pcx_8bit_nopal,SR_DIALOGS); + } + break; + case OP_ESCAPE: + { + char *s; + cti_retezec(20,prikaz,1,1); + fclose(glbm); + s=find_map_path(prikaz); + if ((glbm=fopen(s,"r"))==NULL) error(s); + free(s); + return 0; + } + default:error(prikaz); + } + ODD=cti_oddelovac(); + if (ODD!=OD_COMMAND && ODD!=OD_NEWLINE && ODD!=EOF) ex_error(OD_COMMAND); + } + while (ODD!=OD_NEWLINE && ODD!=EOF); + return 0; + } + +static void preskoc_prikaz(void) + { + char ending=0; + int uroven=0; + char last; + char text; + + do + { + last=ODD; + ODD=cti_oddelovac(); + switch (ODD) + { + case 0:cti_retezec(1,&text,0,0);ending=1;break; + case '\n':if (ending && uroven==0) return;break; + case EOF: if (uroven!=0)ex_error(OD_OUT);return;break; + case '{': if (last==OD_CRIT || last==OD_NEWLINE) uroven++;break; + case '}': if (last==OD_NEWLINE) uroven--; if (uroven<0) ex_error(OD_IN); + else if (uroven==0)return;break; + } + if (ODD!=0) ending=0; + } + while(1); + } + +static void do_script(void) + { + char *s; + char vysledek; + + s=find_map_path(GLOBMAP); + linecounter=0; + glbm=fopen(s,"r"); + free(s); + if (glbm==NULL) error("Chyb uveden soubor..."); + ODD=cti_oddelovac(); + do + { + if (ODD==0) //existuji kriteria + { + vysledek=test_kriterii(); + } + else vysledek=1; + if (ODD==OD_CRIT) //oddelovac kriterii + { + char c=0; + if (vysledek)c=proved_prikaz();else preskoc_prikaz(); + if (c) break; + } + ODD=cti_oddelovac(); + } + while(ODD!=EOF); + fclose(glbm); + } + +static int found_place=0; + + +static char flp_validate2(word sector) + { + TMOB *m; + char c; + + if (mob_map[sector]) + { + m=mobs+mob_map[sector]-1; + if (m->vlajky & ~MOB_PASSABLE) return 0; + if (!m->next) + if (mobs[m->next-1].vlajky & ~MOB_PASSABLE) return 0; + } + c=map_sectors[sector].sector_type; + if (c==S_DIRA || ISTELEPORT(c) || c==S_LAVA || c==S_VODA ) return 0; + return 1; + } + +static char flp_validate(word sector) + { + TMOB *m; + char c; + + if (found_place) return 0; + if (mob_map[sector]) + { + m=mobs+mob_map[sector]-1; + if (m->vlajky & ~MOB_PASSABLE) return 0; + if (!m->next) + if (mobs[m->next-1].vlajky & ~MOB_PASSABLE) return 0; + } + c=map_sectors[sector].sector_type; + if (~map_coord[sector].flags & 1) return 0; + if (c==S_DIRA || ISTELEPORT(c) || c==S_LAVA || c==S_VODA ) return 0; + if (c==S_LEAVE && !found_place) found_place=sector; + return 1; + } + + +static int find_leave_place(int sector) + { + found_place=0; + if (map_sectors[sector].sector_type==S_LEAVE) return sector; + labyrinth_find_path(sector,65535,(SD_PLAY_IMPS | SD_SECRET),flp_validate,NULL); + return found_place; + } + +macro_load_another_map(); + +static select_mode; + + +static char load_index_map(int index) + { + TMA_LOADLEV x; + int lv,i; + THUMAN *h; + + + if (select_mode) + { + char *a; + + a=alloca(strlen(index_tab[index].mapname)+1);strcpy(a,index_tab[index].mapname); + wire_automap_file(a); + return 1; + } + if (!strcmp(index_tab[last_index].mapname,level_fname)) return 0; + lv=find_leave_place(viewsector); + if (lv<1) + { + bott_disp_text(texty[121]); + return 0; + } + for(i=0,h=postavy;iused && h->lives) + if (h->sektor!=lv && !labyrinth_find_path(h->sektor,lv,(SD_PLAY_IMPS | SD_SECRET),flp_validate2,NULL)) + { + char c[20]; + bott_disp_text(itoa(i,c,10)); + return 0; + } + if (!GlobEvent(MAGLOB_LEAVEMAP,viewsector,viewdir)) return 0; + for(i=0,h=postavy;iused && h->lives) h->sektor=lv; + viewsector=lv; + strncpy(x.name,index_tab[index].mapname,12); + x.start_pos=0; + x.dir=0; + macro_load_another_map(&x); + return 0; + } + +static char *fly_text; +static int fly_x,fly_y,fly_xs,fly_ys; +static void *fly_background; + +EVENT_PROC(global_map_point) + { + MS_EVENT *ms; + + user_ptr; + WHEN_MSG(E_INIT) + { + fly_background=NULL;last_index=0;fly_text=NULL; + fly_x=0;fly_y=0;fly_xs=4;fly_ys=4; + } + WHEN_MSG(E_MOUSE) + { + int x,y,i,xs,ys; + char *ptr; + ms=get_mouse(msg); + if (ms->event_type & 0x1) + { + x=ms->x;y=ms->y-SCREEN_OFFLINE; + if (y<0 || y>359) return; + else + { + alock(usemap); + ptr=ablock(usemap); + ptr+=640*y+x+6; + i=*ptr; + } + y+=60; + schovej_mysku(); + if (fly_background!=NULL)put_picture(fly_x,fly_y,fly_background); + set_font(H_FTINY,RGB555(31,31,0)); + xs=fly_xs;ys=fly_ys; + if (i!=last_index) + { + free(fly_background); + last_index=i; + if (index_tab[i].defined) + { + fly_text=index_tab[i].text; + mouse_set_default(H_MS_ZARE); + set_ms_finger(5,5); + } + else + { + fly_text=NULL; + mouse_set_default(H_MS_DEFAULT); + } + + if (fly_text!=NULL) + { + xs=text_width(fly_text)+4; + ys=text_height(fly_text)+4; + fly_background=NewArr(word,xs*ys*2+6); + } + else + { + fly_text=NULL;xs=4;ys=4; + fly_background=NULL; + } + } + if (fly_text!=NULL) + { + if ((x+xs)>639) x=639-xs; + get_picture(x,y,xs,ys,fly_background); + trans_bar(x,y,xs,ys,0); + position(x+2,y+2);outtext(fly_text); + } + send_message(E_MOUSE,msg); + ukaz_mysku(); + showview(fly_x,fly_y,fly_xs+1,fly_ys); + showview(fly_x=x,fly_y=y,(fly_xs=xs)+1,fly_ys=ys); + aunlock(usemap); + } + if (ms->event_type & 0x2 && ms->y>SCREEN_OFFLINE && ms->y<378) + { + if (last_index && index_tab[last_index].defined) if (load_index_map(last_index)) return; + else;else return; + unwire_proc(); + wire_proc(); + msg->msg=-1; + } + if (ms->event_type & 0x8) + { + unwire_proc(); + wire_proc(); + msg->msg=-1; + } + } + WHEN_MSG(E_DONE) + { + free(fly_background); + } + } + +void unwire_global_map() + { + purge_index_tab(); + send_message(E_DONE,E_MOUSE,global_map_point); + set_select_mode(0); + pick_set_cursor(); + } + + +void wire_global_map() + { + unwire_proc(); + schovej_mysku(); + ready_index_tab(); + do_script(); + ukaz_mysku(); + showview(0,0,0,0); + send_message(E_ADD,E_MOUSE,global_map_point); + unwire_proc=unwire_global_map; + change_click_map(NULL,0); + } + +static void *old_wire_save; +static int old_viewsector; +static void empty_unwire() + { + + } + +static void unwire_automap_file() + { + load_map_automap(level_fname); + wire_proc=old_wire_save; + viewsector=old_viewsector; + build_player_map(); + bott_draw(0); + wire_proc(); + } + +void wire_automap_file(char *mapfile) + { + int c; + if ((c=get_leaving_place(mapfile))==0) return; + old_wire_save=wire_proc; + old_viewsector=viewsector; + viewsector=c; + unwire_proc(); + unwire_proc=empty_unwire; + wire_proc=unwire_automap_file; + save_map_state(); + load_map_automap(mapfile); + noarrows=1; + cur_mode=MD_ANOTHER_MAP; + show_automap(1); + cancel_render=1; + } + +char set_select_mode(char mode) + { + char last=select_mode; + select_mode=mode; + return last; + } + +void cestovat() + { + + } + + diff --git a/GAME/INTERFAC.C b/GAME/INTERFAC.C new file mode 100644 index 0000000..402a7a9 --- /dev/null +++ b/GAME/INTERFAC.C @@ -0,0 +1,1623 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "globals.h" +#include "engine1.h" + +#define MES_MAXSIZE 500 +#define CHECK_BOX_ANIM 6 + +static char *error_hack="....Source compiled."; +static char shadow_enabled=1; + +word color_topbar[7]={0,RGB555(22,14,4),RGB555(24,16,6),RGB555(25,17,7)}; + +int input_txtr=H_LOADTXTR; + +void create_frame(int x,int y,int xs,int ys,char clear) + { + word *line; + word *col; + int i; + + x-=VEL_RAMEC; + y-=VEL_RAMEC; + xs=(xs+VEL_RAMEC-1)/VEL_RAMEC+1; + ys=(ys+VEL_RAMEC-1)/VEL_RAMEC+1; + line=GetScreenAdr()+y*scr_linelen2+x; + col=line; + put_8bit_clipped(ablock(H_RAMECEK),col,0,VEL_RAMEC,VEL_RAMEC);col+=VEL_RAMEC; + for(i=1;ilight,border3d->shadow); + + for(i=border3d->bsize-1;i>=0;i--) + if (border3d->ctldef & (1<x,w->y,w->xs-10,w->ys-10,w->color,&w->border3d); + if (shadow_enabled) + { + trans_bar((w->x+10),w->y+w->ys-10,(w->xs-10),10,0); + trans_bar(w->x+w->xs-10,w->y+10,10,w->ys-20,0); + } + else shadow_enabled=1; + } + +void add_window(int x,int y,int xs,int ys,int texture,int border,int txtx,int txty) + { + CTL3D wb; + WINDOW *p; + + xs&=~1; + wb.bsize=abs(border); + wb.ctldef=-1*(border<0); + wb.light=txtx; + wb.shadow=txty; + p=create_window(x,y,xs,ys,texture,&wb); + p->draw_event=show_textured_win; + desktop_add_window(p); + + } + + +void zalamovani(char *source,char *target,int maxxs,int *xs,int *ys) + { + strcpy(target,source); + xs[0]=0; + ys[0]=0; + if ((xs[0]=text_width(target))>maxxs) + { + char c[2]=" "; + char *ls,*ps,*cs; + int sum; + + cs=ps=target; + do + { + ls=NULL; + sum=0; + while (summaxws) maxws=z1; + if (z2>wsys) wsys=z2; + } + maxws+=10; + if (maxws<50) maxws=50; + wscelk=(pocet_textu-1)*(maxws+20); + if (wscelk>maxxs) maxxs=wscelk; + wsy=10+wsys; + maxys+=wsy+40; + if (maxys<50) maxys=50; + maxxs+=20; + add_window(x1=320-(maxxs>>1),y1=180-(maxys>>1),x2=maxxs+10,y2=maxys+10,H_WINTXTR,2,0,0); + message_win[0].xlu=x1; message_win[0].ylu=y1; message_win[0].xrb=x1+x2;message_win[0].yrb=y1+y2; + change_click_map(message_win,2); + set_window_modal(); + y=10; + while (text[0]) + { + define(-1,10,y,1,1,0,label,text); + y+=text_height(text); + text=strchr(text,0)+1; + } + wsx=(maxxs-wscelk)>>1; + for(i=1;iid; + send_message(E_DONE,E_KEYBOARD,message_keyboard,keys); + close_current(); + restore_click_map(clksav,clksav2); + return id; + } + +//------------------ + +void type_text(EVENT_MSG *msg,void **data) + { + static int x,y; + static char text[255],index; + static char *source; + static int max_size,max_chars; + + data; + if (msg->msg==E_INIT) + { + int *p; + char *c; + + set_font(H_FBOLD,RGB555(31,31,31)); + p=msg->data; + x=p[0]; + y=p[1]; + c=*(char **)(p+2); + max_size=*(int *)(p+3); + max_chars=*(int *)(p+4); + strcpy(text,c); + source=c; + index=strchr(text,0)-text; + strcat(text,"_"); + schovej_mysku(); + put_textured_bar(ablock(input_txtr),x,y,max_size,text_height(text),0,0); + position(x,y);outtext(text); + ukaz_mysku(); + showview(x,y,max_size,20); + } + else + if (msg->msg==E_MOUSE) + { + MS_EVENT *ms; + + ms=get_mouse(msg); + if (ms->event_type & 0x8) send_message(E_KEYBOARD,27); + if (ms->event_type & 0x2) send_message(E_KEYBOARD,13); + } + else if (msg->msg==E_KEYBOARD) + { + char c; + + c=*(char *)msg->data; + set_font(H_FBOLD,RGB555(31,31,31)); + if (c) + { + switch (c) + { + case 8:if (index) index--; text[index]='_';text[index+1]=0;break; + case 13:text[index]=0;strcpy(source,text); + case 27:send_message(E_DONE,E_MOUSE,type_text); + send_message(E_DONE,E_KEYBOARD,type_text); + return; + default:if (c>=32) + { + text[index]=c;index++; + text[index]='_'; + text[index+1]=0; + if (text_width(text)>max_size || strlen(text)>(unsigned)max_chars) text[--index]=0; + } + } + schovej_mysku(); + put_textured_bar(ablock(input_txtr),x,y,max_size,text_height(text),0,0); + position(x,y);outtext(text); + ukaz_mysku(); + showview(x,y,max_size,20); + } + msg->msg=-1; + } + } + +#define COL_SIZE 776 + +typedef void (*type_text_exit_proc)(char); + +void type_text_v2(va_list args) +//rutina je pro vstup radky, po ukonceni zavola proceduru exit_proc pokud uzivatel stiskne ENTER +//volat jako task +//#pragma aux type_text_v2 parm [] + { + char *text_buffer=va_arg(args,char *); + int x=va_arg(args,int); + int y=va_arg(args,int); + int max_size=va_arg(args,int); + int max_chars=va_arg(args,int); + int font=va_arg(args,int); + int color=va_arg(args,int); + type_text_exit_proc exit_proc=va_arg(args,type_text_exit_proc); + + int xs,ys,tw; + char *text,pos,len; + char wait_loop=1,ok=0,edit=0; + short *back_pic; + int i; + + task_sleep(NULL); + schovej_mysku(); + set_font(font,color); + xs=max_size+text_width("_"); + if (max_chars<257) text=alloca(257); else text=alloca(max_chars); + for(i=0;i<255;i++) text[i]=i+1; + text[i]=0;ys=text_height(text)+5; + strcpy(text,text_buffer); + back_pic=getmem(xs*ys*2+6); + get_picture(x,y,xs,ys,back_pic); + pos=strlen(text); + len=pos; + tw=text_width(text); + do + { + char sz[2]=" "; + word znak,px; + + put_picture(x,y,back_pic); + position(x,y); + set_font(font,color); + outtext(text); + sz[0]=text[pos];text[pos]=0; + px=text_width(text);text[pos]=sz[0]; + position(px+x,y+3);outtext("_"); + ukaz_mysku(); + showview(x,y,xs,ys); + znak=*(word *)task_wait_event(E_KEYBOARD); //proces bude cekat na klavesu + schovej_mysku(); + if (task_quitmsg()==1) znak=27; + switch(znak & 0xff) + { + case 8:if (pos>0) + { + pos--; + strcpy(&text[pos],&text[pos+1]); + len--; + } + break; + case 13:strcpy(text_buffer,text); + ok=1; + case 27:wait_loop=0; + break; + case 0:switch(znak>>8) + { + case 'K': if (pos>0) pos--;break; + case 'M': if (pospos) + { + strcpy(text+pos,text+pos+1); + len--; + } + break; + case 't':while (pos0) + { + pos--; + if (text[pos]==' ') break; + } + break; + } + break; + default:sz[0]=znak & 0xff; + if (edit) + { + if (sz[0]<32 || tw+text_width(sz)>max_size || len>=max_chars) break; + memmove(&text[pos+1],&text[pos],len-pos+1); + text[pos]=sz[0]; + len++; + pos++; + } + else + { + text[0]=sz[0]; + text[1]=0; + len=1; + pos=1; + } + break; + } + tw=text_width(text); + edit=1; + } + while (wait_loop); + put_picture(x,y,back_pic); + position(x,y); + set_font(font,color); + outtext(text); + ukaz_mysku(); + showview(x,y,xs,ys); + free(back_pic); + exit_proc(ok); + } + + +void col_load(void **data,long *size) + { + int siz=*size; + char *s,*c; + int palcount; + int i;//,j,k; + + palcount=siz/COL_SIZE; + *size=PIC_FADE_PAL_SIZE*palcount; + s=getmem(*size); + c=*data;c+=8; + for(i=0;i>16) +#define Lo(x) ((x)& 0xffff) + + +char labyrinth_find_path(word start,word konec,int flag,char (*proc)(word),word **cesta) + { + longint *stack; + longint *stk_free; + longint *stk_cur; + char *ok_flags; + char vysl; + + if (cesta!=NULL) *cesta=NULL; + stk_free=stk_cur=stack=getmem(4*(mapsize+2)); + memset(ok_flags=getmem((mapsize+8)/8),0,(mapsize+8)/8); + ok_flags[start>>3]|=1<<(start & 0x7); + for(*stk_free++=start;stk_free!=stk_cur;stk_cur++) + { + char i;word s,d,ss; + s=(ss=Lo(*stk_cur))<<2; + for(i=0;i<4;i++) if (!(map_sides[s+i].flags & flag)) + { + char c; + word w; + d=map_sectors[ss].step_next[i]; + c=1<<(d & 0x7); + w=d>>3; + if (!(ok_flags[w] & c) && proc(d)) + { + ok_flags[w]|=c; + *stk_free++=d | ((stk_cur-stack)<<16); + } + if (d==konec) break; + } + if (d==konec) break; + } + vysl=0; + if (stk_free!=stk_cur) + { + if (cesta!=NULL) + { + int count=0; + longint *p,*z; + word *x; + + z=p=stk_free-1; + while (Lo(*p)!=start) + { + int l; + count++; + l=*p; + p=Hi(l)+stack; + *z--=Lo(l); + } + x=*cesta=getmem(count*2+2); + z++; + while (count--) + { + *x++=(word)*z++; + } + *x++=0; + } + vysl=1; + } + free(stack); + free(ok_flags); + return vysl; + } + +typedef struct radio_butt_data + { + void *picture; + char *texty; + }TRADIO_BUTT_DATA; + +static void radio_butts_init(OBJREC *o,long *params) + { + char *c,*z; + long cnt=0,*q,*d,*zz; + int i; + TRADIO_BUTT_DATA *rd; + + d=params; + for (i=0;i<*params;i++) + { + d+=1; + c=get_title(d); + cnt+=strlen(c);cnt++; + } + rd=New(TRADIO_BUTT_DATA); + o->userptr=(void *)rd; + zz=q=(long *)getmem(cnt+8); + *q++=1;*q++=*params; + d=params; + z=(char *)q; + for (i=0;i<*params;i++) + { + d+=1; + c=get_title(d); + strcpy(z,c); + z=strchr(z,'\0');z++; + } + rd->picture=NULL; + rd->texty=(char *)zz; + } + +static void radio_butts_draw(int x1,int y1,int x2,int y2,OBJREC *o) + { + int step,size,sizpul,i; + long *params; + char *texts; + CTL3D *clt; + TRADIO_BUTT_DATA *rd; + + x2; + rd=(TRADIO_BUTT_DATA *)o->userptr; + params=(long *)rd->texty; + step=(y2-y1)/(*(params+1)); + size=(step*9)/10; + sizpul=size>>1; + if (rd->picture==NULL) + { + rd->picture=NewArr(short,3+(size)*(y2-y1)); + get_picture(x1,y1,size,y2-y1,rd->picture); + } + else + put_picture(x1,y1,rd->picture); + + texts=(char *)(params+2); + clt=def_border(5,curcolor); + for (i=0;i<*(params+1);i++,y1+=step) + { + if (*(long *)o->data==i) + { + int xx1=x1+2,yy1=y1+1,xx2=x1+size-2,yy2=y1+size-3,xxs=(xx1+xx2)>>1,yys=(yy1+yy2)>>1; + curcolor=0x0; + line(xx2+1,yy1+2,xxs+2,yy2+2); + line(xx1+1,yys+2,xxs+1,yy2+2); + curcolor=RGB555(31,31,31); + line(xx2,yy1+1,xxs+1,yy2+1); + line(xx1,yys+1,xxs,yy2+1); + line(xx2,yy1,xxs+1,yy2); + line(xx1,yys,xxs,yy2); + } + draw_border(x1+1,y1+1,size-2,size-2,clt); + if (*params) + { + set_aligned_position(x1+size+5,y1+sizpul,0,1,texts); + outtext(texts); + texts=strchr(texts,'\0')+1; + } + } + } + +static void radio_butts_event(EVENT_MSG *msg,OBJREC *o) + { + MS_EVENT *ms; + int sel; + + if (msg->msg==E_MOUSE) + { + ms=get_mouse(msg); + if (ms->event_type & 0x02) + { + TRADIO_BUTT_DATA *rd; + long *params; + + rd=(TRADIO_BUTT_DATA *)o->userptr; + params=(long *)rd->texty; + sel=(ms->y-o->locy)/(o->ys/(*(params+1))); + if (sel>=*(params+1)) sel=*(params+1)-1; + *(long *)o->data=sel; + *params=0; + redraw_object(o); + *params=1; + set_change(); + } + } + + } + +static void radio_butts_done(OBJREC *o) + { + TRADIO_BUTT_DATA *rd; + + rd=(TRADIO_BUTT_DATA *)o->userptr; + free(rd->picture); + free(rd->texty); + }; + +void radio_butts_gr(OBJREC *o) + { + o->runs[0]=radio_butts_init; + o->runs[1]=radio_butts_draw; + o->runs[2]=radio_butts_event;; + o->runs[3]=radio_butts_done;; + o->datasize=4; + } + +char ask_test(char *text,char def) + { + char znak; + SEND_LOG("(START CHECK) %s",text,0); + cprintf("\n\r%s (A/N, Cokoliv=%c)\x7",text,def); + znak=getche(); + if (znak>='a' && znak<='z') znak-='a'-'A'; + if (znak!='N' && znak!='A') znak=def; + return znak=='A'; + } + +long get_disk_free(char disk) + { + return 10*1024*1024; +/* struct diskfree_t ds; + if (_dos_getdiskfree(disk,&ds)==0) + return ds.avail_clusters*ds.sectors_per_cluster*ds.bytes_per_sector; + return 0;*/ + } + +void start_check() + { + /* + char *c; + unsigned drv; + long siz; + struct meminfo memory; + get_mem_info(&memory); + concat(c,pathtable[SR_TEMP],TEMP_FILE); +// if (!access(c,F_OK)) +// if (ask_test("Skeldal nebyl sprvn ukonen. Ml bys provest kontrolu disku\n\rMam spustit SCANDISK?",'A')) +// system("SCANDISK /NOSUMMARY"); + if (pathtable[SR_TEMP][1]==':') drv=pathtable[SR_TEMP][0];else + { + _dos_getdrive(&drv);drv+='@'; + } + if (drv>='a' && drv<='z') drv-='a'-'A'; + siz=get_disk_free(drv-'@')/1024; + SEND_LOG("Checking system enviroment - Largest Free Block %u bytes/pages %d",memory.LargestBlockAvail,memory.NumPhysicalPagesFree); + SEND_LOG("Checking system enviroment - Disk space on %c: %d Kb",drv,siz); + c=alloca(1024); + if (siz<1024) + { + sprintf(c,"Na disku %c: nen potebn 1 MB pro ukldn pozic. Hroz e pozice nebude kam ukldat\n\rPesto spustit?",drv); + if (!ask_test(c,'N')) exit(1); + } + else if (siz<50000 && level_preload==1 && memory.LargestBlockAvail<50000000) + { + sprintf(c,"Na disku %c: neni nutnch 50 MB pro odkldn dat. Skeldal bude etit\n\r" + "s pamt a nahrvat jen potebn data. Hra se me rapidn zpomalit!\n\r" + "Mam to udlat?",drv); + if (ask_test(c,'A')) level_preload=0; + } + */ + } +/* +typedef struct dos_extra_block + { + long sector; + word pocet; + word buffer_ofs; + word buffer_seg; + }; + + +typedef struct disk_label + { + word nula; + long serial; + char label[11]; + char type[8]; + }; +*/ +/*static void read_1st_sector(char drive,char *sector) + { + word segment; + word selector; + word exseg; + word exbuf; + void *ptr; + struct dos_extra_block *data; + + RMREGS regs; + + dosalloc(32,&segment,&selector); + dosalloc(2,&exseg,&exbuf); + ptr=(void *)(segment<<4); + data=(void *)(exseg<<4); + data->sector=0; + data->pocet=1; + data->buffer_ofs=0; + data->buffer_seg=segment; + regs.eax=drive; + regs.ecx=0xffff; + regs.ds=exseg; + regs.ebx=0; + rmint(0x25,0,0,®s); + memcpy(sector,ptr,512); + dosfree(selector); + dosfree(exbuf); + } + + */ +/* +long read_serial(char drive) + { + word segment; + word selector; + struct disk_label *p; + RMREGS regs; + long serial; + + dosalloc(32,&segment,&selector); + regs.eax=0x6900; + regs.ebx=drive; + regs.ds=segment; + regs.edx=0; + rmint(0x21,0,0,®s); + p=(void *)(segment<<4); + serial=p->serial; + dosfree(selector); + return serial; + } + +static void crash_event1(THE_TIMER *t) + { + long serial; + int i; + + serial=read_serial(t->userdata[1]); + serial=~serial; + if (serial==t->userdata[0]) return; + outp(0x64,0xfe); + send_message(E_PRGERROR,&i); + exit(0); + } + +static void crash_event2(THE_TIMER *t) + { + long serial; + int i; + + serial=read_serial(t->userdata[1]); + serial=~serial; + if (serial==t->userdata[0]) return; + outp(0x64,0xfe); + send_message(E_PRGERROR,&i); + exit(0); + } + +static void crash_event3(THE_TIMER *t) + { + long serial; + int i; + + serial=read_serial(t->userdata[1]); + serial=~serial; + if (serial==t->userdata[0]) return; + outp(0x64,0xfe); + send_message(E_PRGERROR,&i); + exit(0); + } + + +#pragma aux check_number_1phase parm[]; +void check_number_1phase(char *exename) //check serial number! + { + THE_TIMER *t; + int h; + char buffer[_MAX_PATH]; + unsigned short date,time; + long serial; + + _fullpath(buffer,exename,_MAX_PATH); + t=add_to_timer(TM_HACKER,2000,1,crash_event1); + t->userdata[0]=*(long *)error_hack; + t->userdata[1]=(long)buffer[0]-'@'; + t=add_to_timer(TM_HACKER,3000,1,crash_event2); + t->userdata[0]=*(long *)error_hack; + t->userdata[1]=(long)buffer[0]-'@'; + h=open(exename,O_RDONLY); + _dos_getftime(h,&date,&time); + serial=(date<<16) | time; + t=add_to_timer(TM_HACKER,4000,1,crash_event3); + t->userdata[0]=~serial; + t->userdata[1]=(long)buffer[0]-'@'; + close(h); + } + +*/ +static void skeldal_checkbox_draw(int x1,int y1,int x2,int y2,OBJREC *o) + { + word *obr; + char *data; + int phase; + + y2,x2; + data=(char *)o->data; + obr=ablock(H_CHECKBOX); + if (o->userptr==NULL) + { + o->userptr=NewArr(word,obr[0]*obr[0]+3); + obr=ablock(H_CHECKBOX); + get_picture(x1,y1,obr[0],obr[0],o->userptr); + } + else + put_picture(x1,y1,o->userptr); + phase=(CHECK_BOX_ANIM-(*data>>1))*20; + put_8bit_clipped(obr,GetScreenAdr()+x1+y1*scr_linelen2,phase,obr[0],obr[0]); + } + +static void skeldal_checkbox_event(EVENT_MSG *msg,OBJREC *o) + { + MS_EVENT *ms; + + if (msg->msg==E_MOUSE) + { + ms=get_mouse(msg); + if (ms->event_type & 0x2) + { + char *data=(char *)o->data; + + *data^=1; + set_change(); + } + } + } + +void animate_checkbox(int first_id,int last_id,int step) + { + int i; + + for(i=first_id;i<=last_id;i+=step) + { + char c; + char pos; + + c=f_get_value(0,i); + pos=c>>1; + if (c & 1 && pos0) + { + c-=2; + c_set_value(0,i,c); + } + } + } + +void skeldal_checkbox(OBJREC *o) + { +// o->runs[0]=skeldal_checkbox_init; + o->runs[1]=skeldal_checkbox_draw; + o->runs[2]=skeldal_checkbox_event; + o->datasize=1; + } + +//------------------------------------------ + +static void setup_button_init(OBJREC *o,char **params) + { + void **d; + d=NewArr(void *,2); + d[0]=NewArr(char,strlen(*params)+1); + strcpy(d[0],*params); + d[1]=NULL; + o->userptr=(void *)d; + *(char *)o->data=0; + } + +static void setup_button_draw(int x1,int y1,int x2,int y2,OBJREC *o) + { + char *s; + char data; + void **z; + word *pic; + word *bb; + int x,y; + + z=(void **)o->userptr; + s=z[0]; + bb=ablock(H_SETUPOK); + pic=z[1];if (pic==NULL) + { + pic=NewArr(word,bb[0]*bb[1]+3); + bb=ablock(H_SETUPOK); + get_picture(x1,y1,bb[0],bb[1],pic); + } + data=*(char *)o->data; + if (data) put_picture(x1,y1,bb); else if (z[1]!=NULL) put_picture(x1,y1,pic); + x=(x1+10+x2)>>1;y=(y1+y2)>>1; + set_aligned_position(x,y,1,1,s); + outtext(s); + z[1]=pic; + } + +static void setup_button_event(EVENT_MSG *msg,OBJREC *o) + { + MS_EVENT *ms; + + if (msg->msg==E_MOUSE) + { + ms=get_mouse(msg); + if (ms->event_type & 0x2) + { + *(char *)o->data=1;redraw_object(o); + } + else if (ms->event_type & 0x4) + { + *(char *)o->data=0;redraw_object(o);set_change(); + } + } + else if (msg->msg==E_LOST_FOCUS) + { + *(char *)o->data=0;redraw_object(o); + } + } + +static void setup_button_done(OBJREC *o) + { + void **z; + + z=o->userptr; + free(z[0]); + free(z[1]); + free(z); + o->userptr=NULL; + } + +void setup_ok_button(OBJREC *o) + { + o->runs[0]=setup_button_init; + o->runs[1]=setup_button_draw; + o->runs[2]=setup_button_event; + o->runs[3]=setup_button_done; + o->datasize=1; + } + +//----------------------------------------------------- + +static void skeldal_soupak_init (OBJREC *o,int *params) + { + void **d; + d=NewArr(void *,2); + d[0]=(void *)*params; + d[1]=NULL; + o->userptr=d; + } + +static void skeldal_soupak_draw (int x1,int y1,int x2,int y2,OBJREC *o) + { + void **z; + int rozsah; + int value; + word *pic; + word *back; + int total; + int xpos; + + z=o->userptr; + rozsah=(int)z[0]; + pic=ablock(H_SOUPAK); + total=y2-y1-pic[1]; + value=*(int *)o->data; + xpos=y2-pic[1]-value*total/rozsah; + back=z[1]; + if (back==NULL) + { + back=NewArr(word,(x2-x1+1)*(y2-y1+1)+3); + get_picture(x1,y1,(x2-x1+1),(y2-y1+1),back); + z[1]=back; + pic=ablock(H_SOUPAK); + } + else + put_picture(x1,y1,back); + put_picture(x1,xpos,pic); + } + +static skeldal_soupak_event(EVENT_MSG *msg,OBJREC *o) + { + if (msg->msg==E_MOUSE) + { + MS_EVENT *ms; + int *z; + int rozsah; + int total; + word *pic; + int ypos,newvalue; + + ms=get_mouse(msg); + if (ms->tl1) + { + z=o->userptr;rozsah=z[0]; + pic=ablock(H_SOUPAK); + total=o->ys-pic[1]; + ypos=ms->y-o->locy; + ypos+=pic[1]/2; + newvalue=(o->ys-ypos)*rozsah/total; + if (newvalue<0) newvalue=0; + if (newvalue>rozsah) newvalue=rozsah; + *(int *)o->data=newvalue; + redraw_object(o); + set_change(); + } + } + } + +static void skeldal_soupak_done(OBJREC *o) + { + void **z; + + z=o->userptr; + free(z[1]); + free(z); + o->userptr=NULL; + } + + + +void skeldal_soupak(OBJREC *o) + { + o->runs[0]=skeldal_soupak_init; + o->runs[1]=skeldal_soupak_draw; + o->runs[2]=skeldal_soupak_event; + o->runs[3]=skeldal_soupak_done; + o->datasize=4; + } + + +static char fletna_str[13]; +static char pos=0; + +// C C# D D# E F F# G G# A A# B C +// A B C D E F G H I J K L M +static char smery[4][13]= + { + "CHLJLH", //DGBABG + "BDEDGE", //C#D#ED#F#E + "LHJGHE", + "CIGILI" + }; + +void fletna_pridej_notu(char note) + { + note+=65; + fletna_str[pos]=note; + if (pos==13) memcpy(fletna_str,fletna_str+1,pos); + else pos++; + } + +static void play_wav(int wav,int sector) + { + if (check_snd_effect(SND_GFX)) + { + play_sample_at_sector(wav,sector,sector,0,0); + } +/* else + { + struct t_wave *p; + char *sample; + int siz; + + p=ablock(wav); + sample=(char *)p+sizeof(struct t_wave); + memcpy(&siz,sample,4);sample+=4; + pc_speak_play_sample(sample,siz,(p->freq!=p->bps?2:1),p->freq); + }*/ + } + +static play_random_sound(int sector,int dir,int pos) + { + int seed; + int v; + + seed=rand(); + srand(sector+dir); + while (pos--) + do + { + v=rnd(8); + } + while (v==dir); + play_wav(H_SND_SEVER+v,sector); + srand(seed); + } + +static play_correct_sound(int sector,int dir) + { + play_wav(H_SND_SEVER+dir,sector); + } + +void check_fletna(THE_TIMER *t) + { + char len; + char *s; + int sec; + int dir; + + t; + if (!pos) return; + sec=t->userdata[0]; + dir=t->userdata[1]; + s=smery[dir]; + len=strlen(s); + if (len==pos) + { + if (!strncmp(s,fletna_str,pos) && map_sectors[sec].sector_type==dir+S_FLT_SMER) + play_correct_sound(sec,dir); + else + play_random_sound(sec,dir,pos); + } + else + play_random_sound(sec,dir,pos); + pos=0; + } + +char fletna_get_buffer_pos() + { + return pos; + } + +static char globFletnaStr[256]=""; +static char globNotes[][3]={"C","C#","D","D#","E","F","F#","G","G#","A","A#","H","C"}; + +void fletna_glob_add_note(char note) +{ + if (strlen(globFletnaStr)<250) strcat(globFletnaStr,globNotes[note]); +} + +static char compareMelody(const char *m1,const char *m2) +{ + while (*m1 && *m2) + { + if (!isalpha(*m1) && *m1!='#') m1++; + else if (!isalpha(*m2) && *m2!='#') m2++; + else if (toupper(*m1)!=toupper(*m2)) break; + else + { + m1++; + m2++; + } + + } + if (*m1>*m2) return 1; + if (*m1<*m2) return -1; + return 0; +} + +void check_global_fletna(THE_TIMER *t) + { + int sec; + int dir; + int i; + int other=-1; + + t; + sec=t->userdata[0]; + dir=t->userdata[1]; + if (globFletnaStr[0] && globFletnaStr[strlen(globFletnaStr)-1]==32) + { + globFletnaStr[strlen(globFletnaStr)-1]=0; + } + for (i=MAGLOB_ONFLUTE1;i<=MAGLOB_ONFLUTE8 ;i++) + if (GlobEventList[i].param!=0) + { + { + const char *cmp=level_texts[GlobEventList[i].param]; + if (compareMelody(cmp,globFletnaStr)==0) + { + GlobEvent(i,sec,dir); + globFletnaStr[0]=0; + return; + } + } + } + else if (GlobEventList[i].sector || GlobEventList[i].side) other=i; + if (other!=-1) + GlobEvent(other,sec,dir); + globFletnaStr[0]=0; + } + + +//--------------------------------------- + +char *find_map_path(char *filename) + { + char *p1,*p; + + if (pathtable[SR_MAP2]!=NULL) + { + concat(p1,pathtable[SR_MAP2],filename); + if (!access(p1,0)) goto found; + } + concat(p1,pathtable[SR_MAP],filename); + found: + p=NewArr(char,strlen(p1)+1); + strcpy(p,p1); + return p; + } + +FILE *enc_open(char *filename,ENCFILE *fil) + { + FILE *f,*g; + char *c,*d,*enc,*temp; + int i,j,last=0; + + f=fopen(filename,"r"); + if (f!=NULL) + { + fil->f=f; + fil->to_delete=NULL; + return f; + } + enc=alloca(strlen(filename)+5); + strcpy(enc,filename); + c=strrchr(enc,'.'); + if (c==NULL) c=strchr(enc,0); + strcpy(c,".ENC"); + f=fopen(enc,"rb"); + if (f==NULL) + { + fil->f=NULL; + fil->to_delete=NULL; + return NULL; + } + d=strrchr(enc,'\\');if(d==NULL)d=enc;else d++; + temp=malloc((i=strlen(pathtable[SR_TEMP]))+strlen(d)+1); + strcpy(temp,pathtable[SR_TEMP]); + strcat(temp,d); + d=temp+i; + d=strrchr(d,'.'); + strcpy(d,".dec"); + g=fopen(temp,"wb"); + if (g==NULL) + { + free(temp); + fclose(f); + fil->f=NULL; + fil->to_delete=NULL; + return NULL; + } + i=getc(f); + while (i!=EOF) + { + j=(last+i) & 0xff; + last=j; + putc(j,g); + i=getc(f); + } + fclose(f); + fclose(g); + f=fopen(temp,"r"); + if (f==NULL) + { + free(temp); + fil->f=NULL; + fil->to_delete=NULL; + return NULL; + } + fil->f=f; + fil->to_delete=temp; + return f; + } + +void enc_close(ENCFILE *fil) + { + fclose(fil->f); + if (fil->to_delete!=NULL) remove(fil->to_delete); + free(fil->to_delete); + fil->f=NULL; + fil->to_delete=NULL; + } + + +int load_string_list_ex(TSTR_LIST *list,char *filename) + { + char c[1024],*p; + int i,j,lin=0; + FILE *f; + ENCFILE fl; + + f=enc_open(filename,&fl); + if (*list==NULL) *list=create_list(256); + if (f==NULL) return -1; + do + { + lin++; + do + { + j=fgetc(f); + if (j==';') while ((j=fgetc(f))!='\n' && j!=EOF); + if (j=='\n') lin++; + } + while (j=='\n'); + ungetc(j,f); + j=fscanf(f,"%d",&i); + if (j==EOF) + { + enc_close(&fl); + return -2; + } + if (j!=1) + { + enc_close(&fl); + return lin; + } + if (i==-1) break; + while ((j=fgetc(f))<33 && j!=EOF); + if (j!=EOF) ungetc(j,f); + if (fgets(c,1022,f)==NULL) + { + enc_close(&fl); + return lin; + } + p=strchr(c,'\n');if (p!=NULL) *p=0; + for(p=c;*p;p++) *p=*p=='|'?'\n':*p; + if (str_replace(list,i,c)==NULL) + { + enc_close(&fl); + return -3; + } + } + while (1); + enc_close(&fl); + return 0; + } + +//------------------------------------------------------------ +int smlouvat_nakup(int cena,int ponuka,int posledni,int puvod,int pocet) + { + int min=cena-((cena-puvod)*2*(pocet-1)/(pocet+1)); + int d_ok=posledni=cena) return 0; + if (ponuka<=posledni || ponukar_ok) return 0; + if (p_ok>75) return 2; + if (p_ok>50) return 3; + if (p_ok>25) return 4; + return 5; + } + +int smlouvat_prodej(int cena,int ponuka,int posledni,int puvod,int pocet) + { + int min=cena+((puvod-cena)*2/pocet); + int d_ok=posledni==0?min-cena:(min+posledni)/2-cena; + int p_ok=(min-ponuka)*100/(d_ok+1); + int r_ok=rnd(100); + + if (ponuka==0) return 0; + if (ponuka<=cena) return 0; + if (posledni!=0) if (ponuka>=posledni || ponuka>min) return 1; + if (p_ok>r_ok) return 0; + if (p_ok>75) return 2; + if (p_ok>50) return 3; + if (p_ok>25) return 4; + return 5; + } + +static smlouvat_enter(EVENT_MSG *msg,OBJREC *o) + { + o; + if (msg->msg==E_KEYBOARD) + { + switch( *(char *)msg->data) + { + case 13:goto_control(30);terminate();break; + case 27:goto_control(20);terminate();break; + } + } + } + +int smlouvat(int cena,int puvod,int pocet,int money,char mode) + { + int ponuka=0,posledni=0; + char text[255],*c,buffer[20]; + int y,yu,xu; + int temp1,temp2; + + cena,puvod,pocet,money;text[0]=0;text[1]=0; + add_window(170,130,300,150,H_IDESKA,3,20,20); + define(-1,10,15,1,1,0,label,texty[241]); + set_font(H_FBOLD,RGB555(31,31,31));define(-1,150,15,100,13,0,label,itoa(cena,buffer,10)); + set_font(H_FBOLD,MSG_COLOR1); + define(-1,10,30,1,1,0,label,texty[238]); + define(10,150,30,100,13,0,input_line,8);property(def_border(5,BAR_COLOR),NULL,NULL,0);set_default(""); + on_event(smlouvat_enter); + define(20,20,20,80,20,2,button,texty[239]);property(def_border(5,BAR_COLOR),NULL,NULL,BAR_COLOR);on_change(terminate); + define(30,110,20,80,20,2,button,texty[230]);property(def_border(5,BAR_COLOR),NULL,NULL,BAR_COLOR);on_change(terminate); + do + { + redraw_window(); + schovej_mysku();set_font(H_FBOLD,RGB555(31,31,31)); + c=text;yu=y=waktual->y+50;xu=waktual->x+10; + do {position(xu,y);outtext(c);y+=text_height(c)+1;c=strchr(c,0)+1;} while(*c); + ukaz_mysku(); + showview(xu,yu,280,y-yu); + goto_control(10); + escape(); + temp1=1; + if (o_aktual->id==20) cena=-1; + else + { + get_value(0,10,buffer); + if (buffer[0]==0) c=texty[240]; + else + { + if (sscanf(buffer,"%d",&ponuka)!=1) c=texty[237]; + else + { + if (ponuka>money && mode==1) c=texty[104]; + else + { + if (mode) temp1=smlouvat_nakup(cena,ponuka,posledni,puvod,pocet); + else temp1=smlouvat_prodej(cena,ponuka,posledni,puvod,pocet+1); + posledni=ponuka; + if (rnd(100)<50) c=texty[230+temp1];else c=texty[250+temp1]; + } + } + } + shadow_enabled=0; + } + if (c) zalamovani(c,text,280,&temp2,&temp2); + } + while (temp1!=0 && cena!=-1); + if (temp1==0) cena=ponuka; + close_current(); + shadow_enabled=1; + return cena; + } + +//----------------- JRC LOGO ---------------------------------- + +#define SHOWDELAY 125 +#define SHOWDEND (SHOWDELAY-32) + +typedef struct _hicolpal + { + unsigned blue:5; + unsigned green:5; + unsigned red:5; + }HICOLPAL; + +void show_jrc_logo(char *filename) + { + char *s; + char *pcx;word *pcxw; + char bnk=1; + int xp,yp,i; + word palette[256],*palw; + int cntr,cdiff,cpalf,ccc; + + change_music("?"); + curcolor=0;bar(0,0,639,479); + showview(0,0,0,0);Sleep(1000); + concat(s,pathtable[SR_VIDEO],filename); + if (open_pcx(s,A_8BIT,&pcx)) return; + pcxw=(word *)pcx; + xp=pcxw[0]; + yp=pcxw[1]; + palw=pcxw+3; + memcpy(palette,palw,256*sizeof(word)); + memset(palw,0,256*sizeof(word)); + xp/=2;yp/=2;xp=320-xp;yp=240-yp; + cntr=get_timer_value();ccc=0; + do + { + cdiff=(get_timer_value()-cntr)/2; + if (cdiffr) palw[i]=r;else palw[i]=k; + k=palette[i] & 0x7e0;if (k>g) palw[i]|=g;else palw[i]|=k; + k=palette[i] & 0x1f;if (k>b) palw[i]|=b;else palw[i]|=k; + } + } + else if (ccc!=cdiff) + { + cpalf=SHOWDELAY-cdiff; + if (cpalf<32) + for (i=0;i<256;i++) + { + int r,g,b,k=32-cpalf; + + b=palette[i];g=b>>5;b&=0x1f;r=g>>6;g&=0x1f; + b-=k;r-=k;g-=k; + if (b<0) b=0; + if (r<0) r=0; + if (g<0) g=0; + palw[i]=b | (r<<11) | (g<<6); + } + } + if (!bnk) wait_retrace();put_picture(xp,yp,pcx); + if (bnk) {wait_retrace();showview(xp,yp,pcxw[0],pcxw[1]);} + ccc=cdiff; + mix_back_sound(0); + } + while (cdiff +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "engine1.h" +#include +#include "globals.h" +#include + +#define neprezbrojit() (battle && (battle_mode!=MD_PREZBROJIT || select_player!=human_selected-postavy)) + +#define _SHOP_ST "_SHOPS.TMP" + +#define SV_ITLIST 0x8001 +#define SV_SNDLIST 0x8002 +#define SV_END 0x8000 +#define IT_LIBS 27 +#define IT_LIB_NAME "IKONY%02d.LIB" +#define IT_LIB_SIZE 18 +#define SHOP_NAME "SHOPS.DAT" + + +#define BUYBOX_X 0 +#define BUYBOX_Y 197 + +#define IMAP_SIZE 8 + +#define SHP_ICSIZX 54 +#define SHP_ICSIZY 60 +#define SHP_ICPLCX 30 +#define SHP_ICPLCY 29 + + +THUMAN postavy_2[20]; +int face_arr[IT_FACES]; +static int sound_handle; +int ikon_libs; +int item_count,it_count_orgn; +LETICI_VEC *letici_veci=NULL; + +short *picked_item=NULL; +short water_breath=-1; //vec pro dychani pod vodou +short flute_item=-1; +int item_in_cursor=0; + +void (*inv_redraw)(); + +TSHOP *cur_shop; +TSHOP **shop_list=NULL;int max_shops=0; //shop_list=prima spojeni s obchody +void *shop_hacek=NULL; //hacek za ktery visi cely shop strom (free(shop_hacek) - odalokuje shopy) + //hacek lze ulozit do savegame -> ulozi se cely stav obchodu +long shop_hacek_size=0; //toto je jeho delka + +#define ico_extract(icnnum) (((char*)ablock(ikon_libs+(icnnum)/IT_LIB_SIZE))+IT_ICONE_SIZE*((icnnum)%IT_LIB_SIZE)) + +#define TOP_OFS 17 +#define HUMAN_X 35 +#define HUMAN_Y 348 +#define INV_X 285 +#define INV_Y (TOP_OFS+29) +#define INV_DESC_X 325 +#define INV_DESC_Y (TOP_OFS+50) +#define INV_XS 55 +#define INV_YS 60 +#define INV_NAME_X 129 +#define INV_NAME_Y 349 +#define INV_NAME_COL (RGB555(10,31,31)) +#define INV_DESK 266 +#define INV_INFO_X 298 +#define INV_INFO_Y 343 +#define INV_INFO_XS 300 +#define INV_INFO_YS 20 +#define INV_INFO_XP 12 +#define INV_INFO_YC (INV_INFO_YS+INV_INFO_XP) +#define INV_BRIEF_COL1 (NOSHADOW(0)) +#define INV_BRIEF_COL2 (NOSHADOW(0)) +#define INV_LEVEL_COL1 (NOSHADOW(RGB555(0,0,15))) +#define INV_LEVEL_COL2 (RGB555(31,24,0)) + +unsigned short butt_plus[]={0x0,(RGB555(25,23,16)),(RGB555(18,17,14)),(RGB555(10,10,5)),(RGB555(31,27,14))}; + +#define PO_XS 194 +#define PO_YS 340 +#define PO_XSS (PO_XS>>1) +#define PO_YSS (PO_YS>>1) + +TITEM *glob_items=NULL; +char inv_view_mode=0; + +void redraw_inventory(); +void zkontroluj_postavu(); + +void place_human_item(word *obrazek,int x,int y,int item) + { + word *p; + + p=ablock(item); + put_picture2picture(p,obrazek,PO_XSS-p[0]/2+x,PO_YS-p[1]-y-20); + } + +/* +void init_item_sounds(int *ptr) + { + int i; + char *c; + + for(i=0;i=*s) return; + pal=((word *)(cur+pos))+3; + for (j=0;j<256;j++,pal++) + { + *pal=RGB555(*pal>>10,(*pal>>5)& 0x1F,(*pal & 0x1F)); + } + } + } + +void load_items() + { + char *name; + FILE *f;THANDLE_DATA *h; + int sect,i,hs; + long size; + void *p; + + f=NULL;i=0; + ikon_libs=hl_ptr; + free(glob_items); + do + { + char name[200]; + sprintf(name,IT_LIB_NAME,i++); + if (test_file_exist(SR_ITEMS,name)) + h=def_handle(hl_ptr++,name,items_15to16_correct,SR_ITEMS); + else break; + } + while (1); + name=find_map_path(ITEM_FILE); + f=fopen(name,"rb");free(name); + if (f==NULL) + { + closemode(); + MessageBox(NULL,"Selhalo otevreni souboru ITEMS.DAT. Zkotroluj zda vubec existuje.",NULL,MB_OK|MB_ICONSTOP); + exit(0); + } + do + { + load_section(f,&p,§,&size); + switch (sect) + { + case 1: + case 4: + face_arr[sect-1]=hl_ptr-1; + prepare_graphics(&hl_ptr,(char *)p,size,pcx_fade_decomp,SR_ITEMS); + free(p); + break; + case 2: + case 3: + face_arr[sect-1]=hl_ptr-1; + prepare_graphics(&hl_ptr,(char *)p,size,pcx_fade_decomp,SR_ITEMS); + free(p); + break; + case 5: + face_arr[sect-1]=hl_ptr-1; + prepare_graphics(&hl_ptr,(char *)p,size,NULL,SR_ITEMS); + free(p); + break; + case SV_ITLIST: + glob_items=p; + it_count_orgn=item_count=size/sizeof(TITEM); + break; + case SV_SNDLIST: + hs=hl_ptr; + prepare_graphics(&hl_ptr,(char *)p,size,wav_load,SR_ZVUKY); + sound_handle=hs-1; + break; + default: + free(p); + break; + } + } + while (sect!=SV_END); + fclose(f); + { + TITEM *t; + for(i=0,t=glob_items;idruh==TYP_SPECIALNI) + { + if (t->user_value==TSP_WATER_BREATH) water_breath=i; + else if (t->user_value==TSP_FLUTE) flute_item=i; + } + } + + } + +void init_items() + { + map_items=(short **)getmem(mapsize*4*sizeof(short **)); + memset(map_items,0,mapsize*4*sizeof(short **)); + } + +static short expand_itemlist(void) + { + int nwit=item_count; + + if (item_count>32766) + { + int i,j; + + for(i=it_count_orgn;i32766) + { + nwit=32766; + memmove(glob_items+it_count_orgn,glob_items+it_count_orgn,(item_count-it_count_orgn-1)*sizeof(TITEM)); + item_count=32766; + memcpy(&it[nwit],&glob_items[item],sizeof(TITEM)); + } + else + { + it=(TITEM *)getmem(sizeof(TITEM)*item_count); + memcpy(it,glob_items,sizeof(TITEM)*nwit); + memcpy(&it[nwit],&glob_items[item],sizeof(TITEM)); + free(glob_items); + } + it[nwit].flags|=ITF_DUPLIC; + glob_items=it; + return nwit+1; + }*/ + +short duplic_item(short item) + { + int i; + + if (!item) return item; + item--; + for(i=0;i0) + { + sect=*(int *)c; + c+=sizeof(sect)/sizeof(short);s-=sizeof(sect); + d=c;itmc=1; + while (*d++) itmc++; + map_items[sect]=(short *)getmem(itmc*sizeof(short)); + d=c; + itmc=0; + do + { + map_items[sect][itmc++]=*d; + s-=sizeof(short); + } + while (*d++); + c=d; + } + } + +char possx[]={0,1,1,0}; +char possy[]={1,1,0,0}; + +void draw_placed_items_normal(int celx,int cely,int sect,int side) + { + int i,j,k; + short *c; + short nl=0,vzh; + short cnt; + + + sect<<=2; + cnt=(cely==0)?2:4; + for(i=0;i0) + { + vzh=glob_items[(*c)-1].vzhled; + if (vzh) draw_item(celx,cely,possx[i],possy[i],ablock(vzh+face_arr[0]),k); + } + c++;k++; + } + } + } + +int count_items_total(short *place) + { + int c=0; + + if (place==NULL) return 0; + while (*place++) c++; + return c; + } + +int count_items_visible(short *place) + { + int c=0; + + if (place==NULL) return 0; + while (*place) + { + if (*place>0) c++; + place++; + } + return c; + } + + +int count_items_inside(short *place) + { + int c=1; + + if (place==NULL) return 0; + place++; + while (*place++<0) c++; + return c; + } + +int find_item(short *place,int mask) + { + int lastitem=-1; + int i=0; + + if (place==NULL) return -1; + while (*place) + { + if ((*place & 0xC000)==mask) lastitem=i; + i++;place++; + } + return lastitem; + } + +static int lastsector; + +static char ValidateSector(word sector) + { + int pp=map_sectors[sector].sector_type; + if (pp==S_NORMAL || pp==S_SMER || pp==S_LEAVE || pp==S_FLT_SMER) + { + lastsector=sector; + return 1; + } + return 0; + } + +void push_item(int sect,int pos,short *picked_item) + { + int bc; + int pc; + int tc; + short *p; + + if (map_sectors[sect].sector_type==S_DIRA || ISTELEPORTSECT(sect)) + sect=map_sectors[sect].sector_tag; + if (sect==0 || map_sectors[sect].sector_type==S_VODA) + { + if (game_extras & EX_RECOVER_DESTROYED_ITEMS) + { + labyrinth_find_path(viewsector,65535,SD_PLAY_IMPS,ValidateSector,NULL); + push_item(lastsector,viewdir,picked_item); + return; + } + else + { + free(picked_item); + picked_item=NULL; + return; + } + } + sect=(sect<<2)+pos; + bc=count_items_total(map_items[sect]); + pc=count_items_total(picked_item); + tc=bc+pc; + if (tc==0) return; + tc++; + p=(short *)grealloc(map_items[sect],tc*sizeof(short)); + if (pc) memcpy(p+bc,picked_item,pc*sizeof(short)); + p[tc-1]=0; + map_items[sect]=p; + recheck_button(sect>>2,1); + } + +void pop_item(int sect,int pos,int mask,short **picked_item) + { + int picked; + int bc,tc,pc; + short *s,*t,*b; + + *picked_item=NULL; + sect=(sect<<2)+pos; + picked=find_item(map_items[sect],mask); + if (picked==-1) return; + s=map_items[sect]+picked; + pc=count_items_inside(s); + bc=count_items_total(map_items[sect]); + tc=bc-pc; + *picked_item=(short *)getmem((pc+1)*sizeof(short)); + memcpy(*picked_item,s,pc*sizeof(short));(*picked_item)[pc]=0; + if (tc) b=NewArr(short,tc+1);else b=NULL; + if (picked) memcpy(b,map_items[sect],picked*sizeof(short)); + t=b+picked; + s=s+pc; + while (*s) *t++=*s++; + if (b!=NULL) b[tc]=0; + free(map_items[sect]); + map_items[sect]=b; + recheck_button(sect>>2,1); + } + +void pick_set_cursor(void) + { + if (picked_item==NULL) + item_in_cursor=H_MS_DEFAULT; + else + item_in_cursor=-(glob_items[*picked_item-1].ikona); + mouse_set_default(item_in_cursor); + } + + + + +void do_items_specs(void) + { + int xa,ya; + char destroy=0; + TITEM *p; + GlobEvent(MAGLOB_ONPICKITEM,viewsector,viewdir); + if (picked_item==0) return; + + p=&glob_items[*picked_item-1]; + switch(p->druh) + { + case TYP_RUNA:xa=p->user_value/10;ya=1<<(p->user_value%10); + runes[xa]|=ya; + destroy=1; + play_fx_at(FX_MAGIC); + if (game_extras & EX_AUTOSHOWRUNE) bott_disp_rune(p->user_value,*picked_item-1); + break; + case TYP_PENIZE: + { + //char c[150]; + money+=p->cena; + destroy=1; + //sprintf(c,texty[cislovka(p->cena)+131],p->cena); + //bott_disp_text(c); + play_fx_at(FX_MONEY); + break; + } + case TYP_PRACH: + destroy=1; + bott_disp_text(texty[134]); + break; + case TYP_SVITXT: + destroy=1; + cur_page=count_pages(); + cur_page&=~0x1; + cur_page++; + if (p->popis[0]==0) add_to_book(p->user_value); + else + { + char *s; + s=find_map_path(p->popis); + add_text_to_book(s,p->user_value); + free(s); + } + play_fx_at(FX_BOOK); + if (game_extras & EX_AUTOOPENBOOK) autoopenaction=1; + break; + } + if (destroy) + { + destroy_items(picked_item); + free(picked_item); + picked_item=NULL; + } + } + +static char check_pick(int sect,int id,int idd,int y) + { + short c; + int min=480,d; + short *place=map_items[(sect<<2)+idd]; + int vzl; + + if (place==NULL) return 0; + while (*place) + { + c=*place; + if (c>0) + { + vzl=glob_items[c-1].vzhled; + if (vzl) d=get_item_top(0,id>1,possx[id],possy[id],ablock(vzl+face_arr[0]),count_items_visible(place)-1); + else d=get_item_top(0,id>1,possx[id],possy[id],NULL,count_items_visible(place))-32; + if (dmin; + } + +static get_top_of_next(int sect,int id) //vraci souradnici predmetu na nasledujicim sektoru + { + int cnt,idd; + + sect=map_sectors[sect].step_next[viewdir]; + if (sect==0) return 0; + id=3-id; + idd=id+viewdir & 3;sect<<=2; + cnt=count_items_visible(map_items[sect+idd])-1; + if (cnt<0) cnt=0; + return get_item_top(0,1,possx[id],possy[id],NULL,cnt); + + } + +char pick_item_(int id,int xa,int ya,int xr,int yr) + { + int sect; + int idd; + + xa,ya,xr,yr; + if (id>1) + { + (sect=map_sectors[viewsector].step_next[viewdir]); + if ((map_sides[(viewsector<<2)+viewdir].flags & SD_THING_IMPS) && !(map_sides[(viewsector<<2)+viewdir].oblouk & SD_ITPUSH)) return 0; + } + else sect=viewsector; + idd=(id+viewdir)&0x3; + if (picked_item!=NULL) + { + if (map_sectors[sect].sector_type==S_DIRA) + { + throw_fly(xa,ya,0); + letici_veci->speed=0; + letici_veci->sector=sect; + letici_veci->xpos=-32; + letici_veci->velocity=0; + letici_veci->flags &= ~FLY_NEHMOTNA; + } + else + if (id>1 || ya>=get_top_of_next(sect,id)) + { + if ((game_extras & EX_BAG_EXTENDED) && (GetKeyState(VK_CONTROL) & 0x80) && + (glob_items[*picked_item-1].nosnost>0)) + { + int curinside=count_items_inside(picked_item); + int nosnost=(glob_items[*picked_item-1].nosnost); + short *batoh=(word *)getmem(nosnost*2+20); + short *cur=batoh; + memcpy(cur,picked_item,(curinside+1)*2); + cur+=curinside; + free(picked_item); + picked_item=NULL; + nosnost-=curinside-1; + while (1) + { + pop_item(sect,idd,0,&picked_item); + if (picked_item!=NULL) do_items_specs(); else break; + if (picked_item!=NULL) + { + short *p=picked_item; + int cnt=count_items_total(picked_item); + if (cnt>nosnost) + { + push_item(sect,idd,picked_item); + free(picked_item); + picked_item=NULL; + break; + } + while (*p) + { + *cur++=-abs(*p++); + nosnost--; + } + free(picked_item); + picked_item=NULL; + } + } + *cur=0; + picked_item=batoh; + pick_set_cursor(); + return 1; + } + push_item(sect,idd,picked_item); + free(picked_item); + picked_item=NULL; + pick_set_cursor(); + return 1; + } + return 0; + } + else + { + if (id>1 || check_pick(sect,id,idd,ya)) + { + pop_item(sect,idd,0,&picked_item); + if (picked_item!=NULL) do_items_specs(); + pick_set_cursor(); + } + return (picked_item!=NULL); + } + } + +int celkova_vaha(short *p) + { + int suma=0; + + while (*p) suma+=glob_items[abs(*p++)-1].hmotnost; + return suma; + } + +char put_item_to_inv(THUMAN *p,short *picked_items) + { + int i,pos=0; + int it; + + if (p->inv_size>MAX_INV) p->inv_size=MAX_INV; + if (picked_items==NULL) return 0; + if (isdemon(p)) return 0; + it=*picked_items; + if (it && glob_items[it-1].umisteni==PL_SIP && !neprezbrojit()) + { + int u; + u=glob_items[it-1].user_value;if (!u) u=1; + if (p->sipy+u<100) + { + p->sipy+=u; + return 1; + } + } + for(i=0;picked_items[i];i++); + while (i) + { + for(;posinv_size && p->inv[pos];pos++); + if (pos>=p->inv_size) break; + i--; + it=abs(picked_items[i]); + p->inv[pos]=it; + picked_items[i]=0; + } + return (i==0); + } + +//-----------------------------------Inventory viewer------------------- + +THUMAN *human_selected=postavy; +short vls_min[24]= + {0,0,0,0,1,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0}; +short vls_max[]= + {200,200,200,200,32767,32767,32767,190,199,190,199,99,99,99,99,99,90,90,90,90,99,4}; + +char bag_click(int id,int xa,int ya,int xr,int yr); +char human_click(int id,int xa,int ya,int xr,int yr); +char inv_swap_desk(int id,int xa,int ya,int xr,int yr); +char exit_inv(int id,int xa,int ya,int xr,int yr); +char ring_place(int id,int xa,int ya,int xr,int yr); +char uloz_sip(int id,int xa,int ya,int xr,int yr); + +char info_box_drawed=0; +void *info_box_below=NULL; +void *inv_keyboard(EVENT_MSG *msg,void **usr); + +T_CLK_MAP clk_inv_view[]= + { + {-1,INV_X,INV_Y,INV_X+INV_XS*6,INV_Y+INV_YS*5,bag_click,2,-1}, + {0,236,185,255,204,ring_place,2,-1}, + {1,236,220,255,239,ring_place,2,-1}, + {2,236,255,255,274,ring_place,2,-1}, + {3,236,290,255,309,ring_place,2,-1}, + {0,0,200,29,309,uloz_sip,2,-1}, + {-1,37,34,225,336,human_click,2,-1}, + {-1,45,339,212,358,inv_swap_desk,2,H_MS_DEFAULT}, + {-1,54,378,497,479,start_invetory,2+8,-1}, + {-1,337,0,357,14,go_map,2,H_MS_DEFAULT}, + {-1,87,0,142,14,game_setup,2,H_MS_DEFAULT}, + {-1,30,0,85,14,konec,2,H_MS_DEFAULT}, + {-1,0,0,639,479,exit_inv,8,-1}, + }; + +#define CLK_INV_VIEW 13 + +void prepocitat_postavu(THUMAN *human_selected) + { + short *sr1,*p,*q,i,j,c; + int v; + + if (human_selected->inv_size>MAX_INV) human_selected->inv_size=MAX_INV; + sr1=human_selected->vlastnosti; + p=human_selected->stare_vls; + memcpy(sr1,p,sizeof(human_selected->stare_vls)); + for(i=0;iwearing[i];else c=human_selected->prsteny[i-HUMAN_PLACES]; + if (c) + { + p=sr1; + q=glob_items[c-1].zmeny; + for(j=0;j=VLS_OHEN && j<=VLS_MYSL) + p[0]=(int)floor(((float)p[0]+(float)q[0])/(1.0f+(float)p[0]*(float)q[0]/(90.0*90.0))+0.5); + else + (*p)+=(*q); + } + p++,q++; + } + p=sr1+VLS_DAMAGE; //vypocet damage (bez omezeni) + q=&glob_items[c-1].zmeny[VLS_DAMAGE]; + *(p++)+=*q++; + p=sr1+VLS_KOUZLA; //aplikace kouzel + q=&glob_items[c-1].zmeny[VLS_KOUZLA]; + (*p++)|=*q++; + } + } + p=sr1; + for(j=0;jvls_max[j]) *p=vls_max[j]; + p++; + } + if (human_selected->lives>human_selected->vlastnosti[VLS_MAXHIT]) human_selected->lives=human_selected->vlastnosti[VLS_MAXHIT]; + //if (human_selected->mana>human_selected->vlastnosti[VLS_MAXMANA]) human_selected->mana=human_selected->vlastnosti[VLS_MAXMANA]; + if (human_selected->kondice>human_selected->vlastnosti[VLS_KONDIC]) human_selected->kondice=human_selected->vlastnosti[VLS_KONDIC]; + v=MAX_HLAD(human_selected);human_selected->jidlo=min(human_selected->jidlo,v); + v=MAX_ZIZEN(human_selected);human_selected->voda=min(human_selected->voda,v); + } + + +char exit_inv(int id,int xa,int ya,int xr,int yr) + { + inv_view_mode=0; + if (!battle || battle_mode!=MD_PREZBROJIT || picked_item==NULL) return_game(id,xa,ya,xr,yr); + return 1; + } + + +void definuj_postavy() + { + int i,num1,r,inv=0,z; + char *c,*end,cc; + + c=ablock(H_POSTAVY_DAT); + end=c+get_handle(H_POSTAVY_DAT)->size; + for(i=0;cinv_size=6; + while (cjmeno);r--;break; + case 129:r=sscanf(c,"%hd",&p->female);break; + case 130:r=sscanf(c,"%hd",&p->xicht);break; + case 131:r=sscanf(c,"%hd",&p->level);break; + case 132:r=sscanf(c,"%d",&p->exp);break; + case 133:r=sscanf(c,"%d",&num1); + while(r==1 && num1!=-1) + { + p->inv[inv++]=num1+1; + c=strchr(c,'\n')+1; + r=sscanf(c,"%d",&num1); + } + break; + case 134:r=sscanf(c,"%hd",&p->wearing[PO_BATOH]); + p->inv_size=6+glob_items[p->wearing[PO_BATOH]].nosnost; + p->wearing[PO_BATOH]++; + break; + case 135:r=sscanf(c,"%d",&num1);if (r!=1) break; + c=strchr(c,'\n')+1; + r=sscanf(c,"%hd",&p->wearing[num1]); + p->wearing[num1]++; + break; + case 136:r=sscanf(c,"%d",&num1);if (r!=1) break; + p->sipy=num1; + break; + default:r=sscanf(c,"%hd",&p->stare_vls[num1]);break; + } + if (c>=end) break; + c=strchr(c,'\n')+1; + } + if (r!=1) + { + closemode(); + MessageBox(NULL,"Error in file POSTAVY.DAT. May be missing a parameter in some definition.",NULL,MB_OK|MB_ICONSTOP); + exit(0); + } + c=strchr(c,'\n')+1; + prepocitat_postavu(p); + p->lives=p->vlastnosti[VLS_MAXHIT]; + p->kondice=p->vlastnosti[VLS_KONDIC]; + p->mana=p->vlastnosti[VLS_MAXMANA]; + p->used=1; + p->groupnum=1; + p->jidlo=MAX_HLAD(p); + p->voda=MAX_ZIZEN(p); + p->bonus=0; + p->mana_battery=32767; + } + } + +static void inv_najist(short item) + { + TITEM *it; + int mhlad; + + if (!item) return; + it=glob_items+item-1; + if (it->druh!=TYP_JIDLO) return; + human_selected->jidlo+=it->user_value*HODINA; + mhlad=MAX_HLAD(human_selected); + play_sample_at_channel(H_SND_EAT,1,100); + if (human_selected->jidlo>mhlad) human_selected->jidlo=mhlad; + if (it->magie>0) + thing_cast(it->spell,human_selected-postavy,human_selected->sektor,NULL,1); + bott_draw(1); + redraw_inventory(); + } + +static void inv_napit(short item) + { + TITEM *it; + int mvoda; + + if (!item) return; + it=glob_items+item-1; + if (it->druh!=TYP_VODA) return; + human_selected->voda+=it->user_value*HODINA; + mvoda=MAX_ZIZEN(human_selected); + play_sample_at_channel(H_SND_LEKTVAR,1,100); + if (human_selected->voda>mvoda) human_selected->voda=mvoda; + if (it->magie>0) + thing_cast(it->spell,human_selected-postavy,human_selected->sektor,NULL,1); + bott_draw(1); + redraw_inventory(); + } + +static void inv_quaf(short item) + { + TITEM *it; + + if (!item) return; + it=glob_items+item-1; + if (it->druh!=TYP_LEKTVAR) return; + thing_cast(it->spell,human_selected-postavy,human_selected->sektor,NULL,1); + bott_draw(1); + play_sample_at_channel(H_SND_LEKTVAR,1,100); + redraw_inventory(); + } + +static void inv_use_spec(short **items) + { + short *pp; + short it; + + pp=*items; + if (pp==NULL) return; + it=*pp; + if (!it) return; + it--; + if (it==flute_item) + { + unwire_proc(); + wire_proc(); + bott_draw_fletna(); + if (put_item_to_inv(human_selected,pp)) + { + free(pp); + *items=NULL; + } + poloz_vsechny_predmety(); + pick_set_cursor(); + } + } + +char check_jidlo_voda(THUMAN *p) + { + if (game_extras & EX_NOHUNGRY) return 0; + if (p->used && p->lives) + { + p->jidlo--; + p->voda--; + if (p->jidlo<0) + { + p->jidlo=0; + return 1; + } + if (p->voda<0) + { + p->voda=0; + player_hit(p,1,0); + return 1; + } + } + return 0; + } + +char check_map_specials(THUMAN *p) + { + char c=0; + switch(mglob.map_effector) + { + case ME_NORMAL:break; + case ME_SOPKA:if (~p->vlastnosti[VLS_KOUZLA] & SPL_FIRE_RES) player_hit(p,10,0),c=1;break; + case ME_LEDOV:if (~p->vlastnosti[VLS_KOUZLA] & SPL_ICE_RES) player_hit(p,10,0),c=1;break; + } + if (c) bott_draw(0); + return c; + } + +void pomala_regenerace_postavy(THUMAN *p) + { + int mreg,mmax; + check_map_specials(p); + if (check_jidlo_voda(p)) return; + if (p->utek) + { + p->utek=0; + if (p->kondice>0) p->kondice-=1; + return; + } + p->kondice+=(p->vlastnosti[VLS_VPREG]+9)/10; + if (p->kondice>p->vlastnosti[VLS_KONDIC]) p->kondice=p->vlastnosti[VLS_KONDIC]; + mreg=(p->vlastnosti[VLS_MPREG]+9)/10; + mmax=p->vlastnosti[VLS_MAXMANA]; + if (p->mana+mreg>mmax) mreg=mmax-p->mana; + if (mreg>0) p->mana+=mreg; + } + + +char sleep_regenerace(THUMAN *p) + { + int mreg,mmax; + if (p->used && p->lives) + { + if (check_jidlo_voda(p)) return 1; + p->kondice+=p->vlastnosti[VLS_VPREG]; + p->lives+=p->vlastnosti[VLS_HPREG]; + if (p->kondice>p->vlastnosti[VLS_KONDIC]) p->kondice=p->vlastnosti[VLS_KONDIC]; + if (p->lives>p->vlastnosti[VLS_MAXHIT]) p->lives=p->vlastnosti[VLS_MAXHIT]; + mreg=p->vlastnosti[VLS_MPREG]; + mmax=p->vlastnosti[VLS_MAXMANA]; + if (p->mana+mreg>mmax) mreg=mmax-p->mana; + if (mreg>0) p->mana+=mreg; + } + return 0; + } + + +void real_regeneration() + { + int i; + THUMAN *p; + + for(i=0;iused && p->lives) + pomala_regenerace_postavy(p); + } + send_message(E_KOUZLO_KOLO); + sleep_ticks+=MAX_SLEEP/30; + if (sleep_ticks>MAX_SLEEP) sleep_ticks=MAX_SLEEP; + tick_tack(1); + TimerEvents(viewsector,viewdir,game_time); + SEND_LOG("(GAME) Tick Tack, Game time: %d",game_time,0); + GlobEvent(MAGLOB_ONROUND,viewsector,viewdir); + bott_draw(0); + } + +void init_inventory(void) + { + definuj_postavy(); + } + +void display_items_in_inv(THUMAN *h) + { + int i,x,y,xr,yr,it; + short *p; + + put_picture(266,TOP_OFS,ablock(H_IDESKA)); + p=ablock(H_IMRIZ1); + p[1]=INV_YS*((h->inv_size-1)/6)+58; + put_picture(INV_X,INV_Y,p); + xr=INV_X;x=0; + yr=INV_Y;y=0; + for(i=0;iinv_size;i++) + { + if ((it=h->inv[i])!=0) + { + int ikn; + + ikn=glob_items[it-1].ikona; + put_picture(xr,yr,ico_extract(ikn)); + } + xr+=INV_XS; + x++;if (x>=6) + { + xr=INV_X;yr+=INV_YS;x=0; + } + } + } + +void display_rings() + { + word pozice[][2]= + { + {245,194},{245,229},{245,264},{245,299} + }; + int i; + + for(i=0;i<4;i++) + { + int ikn; + + ikn=human_selected->prsteny[i]; + if (ikn) + { + word *w; + ikn=glob_items[ikn-1].ikona; + w=(word *)ico_extract(ikn); + put_picture(pozice[i][0]-w[0]/2,pozice[i][1]-w[1]/2,w); + } + } + } + +void *build_items_wearing(THUMAN *h) + { + int i,vzhled,it; + word *p,hx,hy; + word *ob; + size_t siz; + char *pp; + + p=ablock(H_CHARS+h-postavy); + hx=p[0]; + hy=p[1]; + ob=getmem(siz=(PO_XS*PO_YS+PIC_FADE_PAL_SIZE)); + memset(ob,0,siz); + memcpy(ob,p,PIC_FADE_PAL_SIZE); + ob[0]=PO_XS; + ob[1]=PO_YS; + put_picture2picture(p,ob,PO_XSS-(hx/2),PO_YS-hy-20); + for(i=1;iwearing[i])!=0) + { + TITEM *itt; + + itt=&glob_items[it-1]; + vzhled=itt->vzhled; + if (h->female==1) vzhled+=face_arr[2];else vzhled+=face_arr[1]; + if (i==PO_RUKA_L) place_human_item(ob,itt->polohy[1][0],itt->polohy[1][1],vzhled); + else place_human_item(ob,itt->polohy[0][0],itt->polohy[0][1],vzhled); + } + pp=(char *)ob; + if (h->vlastnosti[VLS_KOUZLA] & SPL_STONED) + { + int i; + for (i=0;i<(PIC_FADE_PAL_SIZE>>1);++i) if (i>3) + { + unsigned short col=ob[i]; + int bw=(GET_R_COLOR(col)+GET_G_COLOR(col)+GET_B_COLOR(col))/3; + if (bw>255) bw=255; + ob[i]=RGB(bw,bw,bw); + } + } + else + { + pp+=PIC_FADE_PAL_SIZE; + if (h->vlastnosti[VLS_KOUZLA] & SPL_INVIS) + for(i=0;iwearing[PO_BATOH]; + if (it) + { + TITEM *itt; + word *w;int vzhled; + + itt=&glob_items[it-1]; + vzhled=itt->vzhled; + if (h->female==1) vzhled+=face_arr[2];else vzhled+=face_arr[1]; + w=ablock(vzhled); + enemy_draw(w,GetScreenAdr()+itt->polohy[0][0]+HUMAN_X+PO_XSS-w[0]/2+scr_linelen2*(HUMAN_Y-itt->polohy[0][1]-20),6,320,HUMAN_Y,640*65536); + } + } + + +void write_human_big_name(char *c) + { + int xs,ys; + + set_font(H_FBOLD,INV_NAME_COL); + xs=text_width(c)>>1; + ys=text_height(c)>>1; + position(INV_NAME_X-xs,INV_NAME_Y-ys); + outtext(c); + } + + + +#define pvls(x) (offsetof(struct thuman,vlastnosti[x])) +#define ptpw(x) (offsetof(struct thuman,bonus_zbrani[x])) +static void percent_bar(int x,int y,int xs,int ys,int val,int max,char *popis) + { + CTL3D clt; + char s[25]; + + memcpy(&clt,def_border(3,0),sizeof(clt)); + bar(x,y,x+xs*val/max,ys+y); + show_textured_button(x-2,y-2,xs+5,ys+5,0,&clt); + set_aligned_position(x,y-5,0,2,popis); + outtext(popis); + sprintf(s,"%d/%d",val/360,max/360); + set_aligned_position(x+xs/2,y+ys/2,1,1,s); + outtext(s); + } + +typedef struct t_inv_script + { + short col,line; + char *text; + short parm1,parm2; + char lenght; + char align; + }; + +#define INFO_AP -1 +#define INFO_EXP -2 +#define LINE_STEP 6 +#define COL_STEP 8 + +static struct t_inv_script script[]= + { + {15,12,"%d",pvls(VLS_SILA),0,2+128,2}, + {15,14,"%d",pvls(VLS_SMAGIE),0,2+128,2}, + {15,16,"%d",pvls(VLS_POHYB),0,2+128,2}, + {15,18,"%d",pvls(VLS_OBRAT),0,2+128,2}, + {15,5,"%d/%d",offsetof(THUMAN,lives),pvls(VLS_MAXHIT),2,2}, + {15,7,"%d/%d",offsetof(THUMAN,mana),pvls(VLS_MAXMANA),2,2}, + {15,9,"%d/%d",offsetof(THUMAN,kondice),pvls(VLS_KONDIC),2,2}, + {15,20,"%d",offsetof(THUMAN,bonus),0,2,2}, + {15,25,"%d",ptpw(TPW_MEC),0,2,2}, + {15,27,"%d",ptpw(TPW_SEKERA),0,2,2}, + {15,29,"%d",ptpw(TPW_KLADIVO),0,2,2}, + {15,31,"%d",ptpw(TPW_HUL),0,2,2}, + {15,33,"%d",ptpw(TPW_DYKA),0,2,2}, + {15,35,"%d",ptpw(TPW_STRELNA),0,2,2}, + {15,37,"%d",ptpw(TPW_OST),0,2,2}, + {0,0,NULL,0,31,1,0}, + {0,2,NULL,0,30,1,0}, + {15,0,"%d",offsetof(THUMAN,level),0,2,2}, + {30,2,"%d [%d]",offsetof(THUMAN,exp),INFO_EXP,4,2}, + {0,5,NULL,0,14,1,0}, + {0,7,NULL,0,16,1,0}, + {0,9,NULL,0,15,1,0}, + {0,12,NULL,0,10,128,0}, + {0,14,NULL,0,11,128,0}, + {0,16,NULL,0,12,128,0}, + {0,18,NULL,0,13,128,0}, + {0,20,NULL,0,19,0,0}, + {0,23,NULL,0,90,1,0}, + {0,25,NULL,0,91,1,0}, + {0,27,NULL,0,92,1,0}, + {0,29,NULL,0,93,1,0}, + {0,31,NULL,0,94,1,0}, + {0,33,NULL,0,95,1,0}, + {0,35,NULL,0,96,1,0}, + {0,37,NULL,0,97,1,0}, + {30,5,"%d-%d",pvls(VLS_UTOK_L),pvls(VLS_UTOK_H),2,2}, + {30,7,"%d-%d",pvls(VLS_OBRAN_L),pvls(VLS_OBRAN_H),2,2}, + {30,9,"%d",INFO_AP,0,2,2}, + {17,5,NULL,0,18,1,0}, + {17,7,NULL,0,17,1,0}, + {17,9,NULL,0,20,1,0}, + {30,14,"%d",pvls(VLS_OHEN),0,2,2}, + {30,16,"%d",pvls(VLS_VODA),0,2,2}, + {30,18,"%d",pvls(VLS_ZEME),0,2,2}, + {30,20,"%d",pvls(VLS_VZDUCH),0,2,2}, + {30,22,"%d",pvls(VLS_MYSL),0,2,2}, + {17,12,NULL,0,21,1,0}, + {17,14,NULL,0,22,1,0}, + {17,16,NULL,0,23,1,0}, + {17,18,NULL,0,24,1,0}, + {17,20,NULL,0,25,1,0}, + {17,22,NULL,0,26,1,0}, + }; + +static int calc_value(int parm,int lenght) + { + long l; + if (parm>=0) l=*(long *)(((char *)human_selected)+parm); + else + switch (parm) + { + case INFO_EXP: + l=(human_selected->levellevel-1]-human_selected->exp):0); + break; + case INFO_AP: + l=get_ap(human_selected->vlastnosti); + break; + } + switch(lenght) + { + case 1:l=(long)((signed char)l);break; + default: + case 2:l=(long)((short)l);break; + case 4:l=(long)l;break; + } + return l; + } + +void inv_display_vlastnosti() + { + char b; + int i; + + b=human_selected->bonus!=0; + put_picture(INV_DESK,TOP_OFS,ablock(H_SVITEK)); + for(i=0;icol*COL_STEP;y=INV_DESC_Y+scr->line*LINE_STEP; + s=scr->text; + p1=scr->parm1; + p2=scr->parm2; + p1=calc_value(p1,scr->lenght & 0x7f); + if (s==NULL) s=texty[scr->parm2];else p2=calc_value(p2,scr->lenght); + sprintf(buffer,s,p1,p2); + if (scr->lenght & 0x80 && human_selected->bonus) + set_font(H_FONT7,scr->text==NULL?INV_LEVEL_COL1:INV_LEVEL_COL2); + else set_font(H_FONT7,NOSHADOW(0)); + set_aligned_position(x,y,scr->align,0,buffer); + outtext(buffer); + } + set_font(H_FONT7,NOSHADOW(0)); + curcolor=(RGB555(18,17,14)); + percent_bar(INV_DESC_X+140,INV_DESC_Y+170,90,10,human_selected->jidlo,MAX_HLAD(human_selected),texty[69]); + curcolor=(RGB555(14,17,18)); + percent_bar(INV_DESC_X+140,INV_DESC_Y+210,90,10,human_selected->voda,MAX_ZIZEN(human_selected),texty[70]); + if (human_selected->bonus) + for(i=0;i<4;i++) if (calc_value(script[i].parm1,2)<100) + { + int x,y; + x=INV_DESC_X+script[i].col*COL_STEP;y=INV_DESC_Y+script[i].line*LINE_STEP; + set_font(H_FSYMB,RGB555(31,31,31)); + memcpy(charcolors,butt_plus,sizeof(charcolors)); + position(x+1,y);outtext("+"); + } + } + +typedef struct t_info + { + short line,col; + char *format; + short parm1,parm2; + char bonus; + }T_INFO; + + +char muze_nosit(short item) + { + short *p,i,*q,*z; + + p=human_selected->vlastnosti; + q=glob_items[item-1].podminky; + z=glob_items[item-1].zmeny; + for(i=0;i<4;i++) + { + if (*p<*q) return 0; + if (*p+*z<*q) return 0; + q++;z++;p++; + } + return 1; + } + +void hide_inv_info_box() + { + info_box_drawed=0; + if (info_box_below!=NULL) + { + schovej_mysku(); + put_picture(INV_INFO_X-12,INV_INFO_Y-12,info_box_below); + free(info_box_below); + info_box_below=NULL; + ukaz_mysku(); + showview(INV_INFO_X-VEL_RAMEC,INV_INFO_Y-VEL_RAMEC,INV_INFO_XS+2*VEL_RAMEC+2,INV_INFO_YC+2*VEL_RAMEC+2); + } + } + +void inv_info_box(char *text1,char *text2,char *text3,char asterix) + { + int x,y,ys; + static last_info_ys=0; + ys=INV_INFO_YS; + if (text3!=NULL) ys+=INV_INFO_XP; + if (info_box_below!=NULL && last_info_ys!=ys) + { + put_picture(INV_INFO_X-12,INV_INFO_Y-12,info_box_below); + free(info_box_below); + info_box_below=NULL; + } + last_info_ys=ys; + info_box_drawed=1; + if (info_box_below==NULL) + { + info_box_below=getmem((INV_INFO_XS+28)*(ys+28)*2+6); + get_picture(INV_INFO_X-12,INV_INFO_Y-12,INV_INFO_XS+28,ys+28,info_box_below); + } + x=INV_INFO_X; + y=INV_INFO_Y; + create_frame(x,y,INV_INFO_XS,ys,1); + set_font(H_FBOLD,asterix?(NOSHADOW(RGB555(31,0,0))):NOSHADOW(0)); + position(x,y); + outtext(text1); + position(x,y+12); + outtext(text2); + position(x,y+24); + if (text3!=NULL) outtext(text3); + } + + +static char *get_item_req(char *s,int itn) + { + TITEM *it; + int i; + char *c=s; + + s[0]=0; + itn--;if (itn<0) return NULL; + it=glob_items+itn; + for(i=0;i<4;i++) + if (it->podminky[i]) + { + sprintf(c,texty[200+i],it->podminky[i]); + c=strchr(c,0); + if (i!=3)*c++=32; + } + *c=0; + if (s[0]) return s;else return NULL; + } + +void inv_informuj() + { + int i; + char s[80]; + + if (picked_item==NULL) return; + i=*picked_item; + inv_info_box(glob_items[i-1].jmeno,glob_items[i-1].popis,get_item_req(s,i),!muze_nosit(i)); + } + +void write_pocet_sipu() + { + char s[10]; + if (human_selected->sipy) + { + set_font(H_FBOLD,RGB555(31,31,31)); + sprintf(s,"%d",human_selected->sipy); + set_aligned_position(19,301,1,1,s); + outtext(s); + } + } + + +void redraw_inventory() + { + update_mysky(); + schovej_mysku(); + curcolor=0; + bar(0,16,30,16+360); + bar(620,16,640,16+360); + if (inv_view_mode==0 && ~human_selected->stare_vls[VLS_KOUZLA] & SPL_DEMON && ~human_selected->vlastnosti[VLS_KOUZLA] & SPL_STONED) display_items_in_inv(human_selected); + else inv_display_vlastnosti(); + display_items_wearing(human_selected); + write_human_big_name(human_selected->jmeno); + write_pocet_sipu(); + display_rings(); + other_draw(); + info_box_drawed=0; + free(info_box_below); + info_box_below=NULL; + ms_last_event.event_type=0x1;send_message(E_MOUSE,&ms_last_event); + ukaz_mysku(); + showview(0,0,0,0); + } + +static void add_vls(int plus,int vls,short *change1,short *change2,float factor) + { + int oldv,newv; + + oldv=(int)(vls*factor); + vls+=plus; + newv=(int)(vls*factor); + if (change1!=NULL) + { + change1[0]+=newv-oldv; + if (change2!=NULL) change2[0]+=newv-oldv; + } + return; + } + +int advance_vls(int id) + { + int i=0; + short *vls=human_selected->stare_vls; + switch (id) + { + case 0:if (vls[VLS_SILA]<100) //max 100 + { + add_vls(1,vls[VLS_SILA],vls+VLS_MAXHIT,&human_selected->lives,1.5f); + add_vls(1,vls[VLS_SILA],vls+VLS_HPREG,NULL,0.08f); + vls[VLS_SILA]++; + i=1; + } + break; + case 1:if (vls[VLS_SMAGIE]<100) //max 100 + { + add_vls(1,vls[VLS_SMAGIE],vls+VLS_MAXMANA,&human_selected->mana,2); + add_vls(1,vls[VLS_SMAGIE],vls+VLS_MPREG,NULL,0.1f); + vls[VLS_SMAGIE]++; + i=1; + } + break; + case 2:if (vls[VLS_POHYB]<100) //max 100 + { + add_vls(1,vls[VLS_POHYB],vls+VLS_MAXHIT,&human_selected->lives,0.5); + add_vls(1,vls[VLS_POHYB],vls+VLS_KONDIC,&human_selected->kondice,0.25); + vls[VLS_POHYB]++; + i=1; + } + break; + case 3:if (vls[VLS_OBRAT]<100) //max 100 + { + add_vls(1,vls[VLS_OBRAT],vls+VLS_KONDIC,&human_selected->kondice,0.5); + add_vls(1,vls[VLS_OBRAT],vls+VLS_VPREG,NULL,0.1f); + vls[VLS_OBRAT]++; + i=1; + } + break; + } + return i; + } + +static void timed_redraw(THE_TIMER *t) + { + t; + bott_draw(1); + inv_redraw(); + } + +char vls_click(int id,int xa,int ya,int xr,int yr) + { + int xs,ys,i; + + if (!human_selected->bonus) return 0; + set_font(H_FSYMB,0); + xs=text_width("+"); + ys=text_height("+"); + for(id=0;id<4;id++) + { + int xe,ye; + float mh,mv; + xr=INV_DESC_X+COL_STEP*script[id].col+1; + yr=INV_DESC_Y+LINE_STEP*script[id].line; + xe=xr+xs;ye=yr+ys; + if (xa>=xr && xa=yr && yajidlo/MAX_HLAD(human_selected); + mv=(float)human_selected->voda/MAX_ZIZEN(human_selected); + i=advance_vls(id); + if (i>0) + { + schovej_mysku(); + set_font(H_FSYMB,0x0); + memcpy(charcolors,butt_plus,sizeof(butt_plus)); + charcolors[1]=butt_plus[3]; + charcolors[3]=butt_plus[1]; + position(xr,yr);outtext("+"); + ukaz_mysku(); + showview(xr,yr,xs,ys); + } + human_selected->bonus-=i; + prepocitat_postavu(human_selected); + human_selected->jidlo=(int)(mh*MAX_HLAD(human_selected)); + human_selected->voda=(int)(mv*MAX_ZIZEN(human_selected)); + add_to_timer(-1,6,1,timed_redraw); + } + } + return 1; + } + + + +void inv_item_info_box(EVENT_MSG *msg,void **data) + { + MS_EVENT *ms; + char podm; + int pos; + static int lastpos=-1; + int xr,yr; + + data; + if (msg->msg==E_MOUSE) + { + ms=get_mouse(msg); + if (picked_item!=NULL) + { + if (ms->y>378 && info_box_drawed) hide_inv_info_box(); + else if (ms->y<=378 && !info_box_drawed) + { + schovej_mysku(); + inv_informuj(); + ukaz_mysku(); + showview(INV_INFO_X-VEL_RAMEC,INV_INFO_Y-VEL_RAMEC,INV_INFO_XS+2*VEL_RAMEC+2,INV_INFO_YC+2*VEL_RAMEC+2); + } + lastpos=-1; + } + else + { + if (inv_view_mode) return; + podm=(ms->x>=clk_inv_view[0].xlu && + ms->x<=clk_inv_view[0].xrb && + ms->y>=clk_inv_view[0].ylu && + ms->y<=clk_inv_view[0].yrb); + xr=ms->x-clk_inv_view[0].xlu; + yr=ms->y-clk_inv_view[0].ylu; + if (podm) pos=(xr/INV_XS)+6*(yr/INV_YS);else pos=-1; + if (pos>=human_selected->inv_size) podm=0; + if (podm && (!info_box_drawed || pos!=lastpos)) + { + int i=human_selected->inv[pos]; + if (i) + { + char s[80]; + schovej_mysku(); + inv_info_box(glob_items[i-1].jmeno,glob_items[i-1].popis,get_item_req(s,i),!muze_nosit(i)); + showview(INV_INFO_X-VEL_RAMEC,INV_INFO_Y-VEL_RAMEC,INV_INFO_XS+2*VEL_RAMEC+2,INV_INFO_YC+2*VEL_RAMEC+2); + ukaz_mysku(); + } + else if (info_box_drawed) hide_inv_info_box(); + } + else if (!podm && info_box_drawed) hide_inv_info_box(); + lastpos=pos; + } + } + } + +void unwire_inv_mode() + { + send_message(E_DONE,E_KEYBOARD,inv_keyboard); + send_message(E_DONE,E_MOUSE,inv_item_info_box); + build_all_players(); + } + +char vejdou_se(int pocet) + { + int i=human_selected->inv_size-1; + + while (i>=0) if (!human_selected->inv[i--]) pocet--; + return pocet>0; + } + +char uloz_sip(int id,int xa,int ya,int xr,int yr) + { + id;xa;ya;xr;yr; + + if (isdemon(human_selected)) return 0; + if (neprezbrojit()) return 0; + if (picked_item!=NULL && picked_item[1]==0 && glob_items[picked_item[0]-1].umisteni==PL_SIP) + { + int pocet=glob_items[picked_item[0]-1].user_value; + if (pocet==0) pocet=1; + if (human_selected->sipy+pocet>99) return 1; + human_selected->sipy+=pocet; + free(picked_item); + picked_item=NULL; + } + else + if (picked_item==NULL && human_selected->sipy) + { + short x[2]; + int i; + + for(i=0;isipy--; + break; + } + } + pick_set_cursor(); + inv_redraw(); + return 1; + } + +static char MakeItemCombinations(short *itm1, short *itm2) +{ + short i1=*itm1-1,i2=*itm2-1; + char *fname; + int src1; + int src2; + int trg1; + int trg2; + int cnt; + char succ=0; + + FILE *table; + + concat(fname,pathtable[SR_MAP],"COMBITEM.DAT"); + table=fopen(fname,"r"); + if (table==0 && pathtable[SR_MAP2][0]) + { + concat(fname,pathtable[SR_MAP2],fname); + table=fopen(table,"r"); + } + if (table==0) return 0; + cnt=fscanf(table,"%d %d -> %d %d",&src1,&src2,&trg1,&trg2); + while(cnt>=3) + { + if (src1==i1 && src2==i2) + { + if (cnt==3) + { + *itm2=trg1+1; + *itm1=0; + } + else + { + *itm1=trg1+1; + *itm2=trg2+1; + } + succ=1; + break; + } + if (src1==i2 && src2==i1) + { + if (cnt==3) + { + *itm2=trg1+1; + *itm1=0; + } + else + { + *itm2=trg1+1; + *itm1=trg2+1; + } + succ=1; + break; + } + if (fscanf(table," ;")==-1) break; + cnt=fscanf(table,"%d %d -> %d %d",&src1,&src2,&trg1,&trg2); + } + fclose(table); + return succ; +} + +char bag_click(int id,int xa,int ya,int xr,int yr) + { + short p,*pk; + + if (inv_view_mode || human_selected->stare_vls[VLS_KOUZLA] & SPL_DEMON || human_selected->vlastnosti[VLS_KOUZLA] & SPL_STONED) return vls_click(id,xa,ya,xr,yr); + xa;ya; + id=(xr/INV_XS)+6*(yr/INV_YS); + if (id>=human_selected->inv_size) return 0; + pk=picked_item; + if (pk!=NULL) + { + if (picked_item[1]!=0 && vejdou_se(count_items_total(picked_item))) return 0; + if (picked_item[1]!=0 || human_selected->inv[id]==0 || !MakeItemCombinations(picked_item,human_selected->inv+id)) + while (*pk) + { + p=human_selected->inv[id]; + human_selected->inv[id]=abs(*pk); + *pk=p;pk++; + if (*pk) while (human_selected->inv[id]) if ((++id)>=human_selected->inv_size) id=0; + } + } + else + { + picked_item=getmem(2*sizeof(short)); + picked_item[0]=human_selected->inv[id]; + picked_item[1]=0; + human_selected->inv[id]=0; + } + if (!picked_item[0]) + { + free(picked_item); + picked_item=NULL; + } + pick_set_cursor(); + play_sample_at_channel(H_SND_PUTINV,0,100); + inv_redraw(); + return 1; + } + +char item_pointed(int k,int x,int y,short item,short kind) + { + int x1,y1,x2,y2,xs,ys,xsiz,ysiz,i; + short *p; + char *c,cc; + + if (!item) return 0; + i=glob_items[item-1].vzhled; + p=ablock(i+face_arr[1+kind]); + xs=glob_items[item-1].polohy[k][0]+HUMAN_X+PO_XSS; + ys=HUMAN_Y-glob_items[item-1].polohy[k][1]-20; + xsiz=p[0]>>1; + ysiz=p[1]; + x1=xs-xsiz;y1=ys-ysiz; + x2=xs+xsiz;y2=ys; + if (x>=x1 && x<=x2 && y>=y1 && y<=y2) + { + xs=x-x1; + ys=y-y1; + c=(char *)p;c+=PIC_FADE_PAL_SIZE+xs+ys*p[0]; + cc=*c; + } + else cc=0; + return cc!=0; + } + +char inv_swap_desk(int id,int xa,int ya,int xr,int yr) + { + id,xa,ya,xr,yr; + inv_view_mode=!inv_view_mode; + inv_redraw(); + return 1; + } + +char ring_place(int id,int xa,int ya,int xr,int yr) + { + short ring; + + xa,ya,xr,yr; + if (neprezbrojit()) return 0; + if (isdemon(human_selected)) return 0; + if (human_selected->vlastnosti[VLS_KOUZLA] & SPL_STONED) return 0; + ring=human_selected->prsteny[id]; + if (picked_item==NULL) + if (ring) + { + picked_item=(short *)getmem(2*sizeof(short)); + picked_item[0]=ring; + picked_item[1]=0; + human_selected->prsteny[id]=0; + } + else return 0; + else + if (picked_item[1]==0) + { + int i; + + i=picked_item[0]-1; + if (glob_items[i].umisteni!=PL_PRSTEN) return 1; + human_selected->prsteny[id]=picked_item[0]; + *picked_item=ring; + if (!ring) + { + free(picked_item);picked_item=0; + } + } + prepocitat_postavu(human_selected); + zkontroluj_postavu(); + pick_set_cursor(); + inv_redraw(); + return 1; + } + + +void vymen_batohy() + { + short *old,*c; + int i; + + c=old=(short *)getmem(sizeof(short)*40); + memset(old,0,sizeof(short)*40); + *c++=human_selected->wearing[PO_BATOH]; + for(i=6;iinv_size;i++) + { + *c=-human_selected->inv[i]; + if (*c) c++; + } + for(i=6;iinv[i]=0; + if (picked_item!=NULL) + { + int it; + + c=picked_item; + it=human_selected->wearing[PO_BATOH]=*c++; + i=6; + while (*c && iinv[i++]=-*c++; + human_selected->inv_size=glob_items[it-1].nosnost+6; + } + else + { + human_selected->inv_size=6; + human_selected->wearing[PO_BATOH]=0; + } + if (old[0]) picked_item=old; + else + { + free(old); + picked_item=NULL; + } + prepocitat_postavu(human_selected); + zkontroluj_postavu(); + pick_set_cursor(); + play_sample_at_channel(H_SND_WEAR,1,100); + inv_redraw(); + } + +void remove_item(THUMAN *p,int what) + { + if (p->wearing[what]) + { + int i; + short z[2]; + + z[0]=p->wearing[what]; + z[1]=0; + if (glob_items[z[0]-1].flags & ITF_NOREMOVE) destroy_items(z); + else + { + for(i=0;iinv_size && p->inv[i];i++); + if (i!=p->inv_size) p->inv[i]=p->wearing[what]; + else push_item(p->sektor,p->direction,z); + } + p->wearing[what]=0; + } + } + +int calculate_weight(THUMAN *p) +{ + int suma=0; + int i; + for (i=0;iinv_size;i++) if (p->inv[i]) + suma+=glob_items[p->inv[i]-1].hmotnost; + suma=suma*3/2; + for (i=0;iwearing[i]) + suma+=glob_items[p->wearing[i]-1].hmotnost; + for (i=0;iprsteny[i]) + suma+=glob_items[p->prsteny[i]-1].hmotnost; + return suma; +} + + +int weigth_defect(THUMAN *p) +{ + int wh,wf; + wh=calculate_weight(p); + if (wh>p->vlastnosti[VLS_SILA]*20) + wf=(wh-p->vlastnosti[VLS_SILA]*20)/200; + else + wf=0; + return wf; +} + +static char check_double_wield(int newplace,short item) + { + short *p,i,*q1,*q2; + short *z1,*z2; + short opplace=newplace==PO_RUKA_L?PO_RUKA_R:PO_RUKA_L; + short item2=human_selected->wearing[opplace]; + + if (!item || !item2) return 0; + if (glob_items[item-1].druh!=TYP_UTOC || glob_items[item2-1].druh!=TYP_UTOC ) return 0; + p=human_selected->vlastnosti; + q1=glob_items[item-1].podminky; + q2=glob_items[item2-1].podminky; + z1=glob_items[item-1].zmeny; + z2=glob_items[item2-1].zmeny; + for(i=0;i<4;i++) + { + int chk=(*q1+*q2)*3/4; + if (*pwearing; + for(i=0;iwearing[PO_RUKA_R])) + remove_item(human_selected,PO_RUKA_L); + } + + + +char human_click(int id,int xa,int ya,int xr,int yr) + { + short itsave=0; + short place=-1; + short um=0; + + + xr;yr;id; + if (battle && (battle_mode!=MD_PREZBROJIT || select_player!=human_selected-postavy) || human_selected->vlastnosti[VLS_KOUZLA] & SPL_STONED) return 0; + if (isdemon(human_selected)) return 0; + if (picked_item!=NULL) + if (muze_nosit(*picked_item)) + if (glob_items[(*picked_item)-1].umisteni==PL_BATOH) + { + vymen_batohy(); + return 0; + } + else if (picked_item[1]!=0) return 0; + else + { + um=place=glob_items[picked_item[0]-1].umisteni; + if (!place) + { + switch (glob_items[picked_item[0]-1].druh) + { + case TYP_LEKTVAR:inv_quaf(*picked_item);destroy_items(picked_item);free(picked_item);picked_item=NULL;pick_set_cursor();break; + case TYP_JIDLO:inv_najist(*picked_item);destroy_items(picked_item);free(picked_item);picked_item=NULL;pick_set_cursor();break; + case TYP_VODA:inv_napit(*picked_item);destroy_items(picked_item);free(picked_item);picked_item=NULL;pick_set_cursor();break; + case TYP_SPECIALNI:inv_use_spec(&picked_item);break; + } + inv_redraw(); + return 1; + } + if (place==PL_RUKA) + if (xr<94) place=PO_RUKA_R;else place=PO_RUKA_L; + else if (place==PL_OBOUR) place=PO_RUKA_R; + else place--; + if (place>=HUMAN_PLACES) return 0; + itsave=human_selected->wearing[place]; + } + else return 0; + else + { + int i=HUMAN_PLACES-1; + while (i>=0) + { + if (item_pointed(i==PO_RUKA_L,xa,ya,human_selected->wearing[i],human_selected->female)) break; + i--; + } + if (i<0) return 0; + if (i==PO_BATOH) vymen_batohy(); + else + { + picked_item=getmem(2*sizeof(short)); + picked_item[0]=human_selected->wearing[i]; + picked_item[1]=0; + human_selected->wearing[i]=0; + } + } + if (um) + { + switch (um) + { + case PL_KUTNA:remove_item(human_selected,PO_HLAVA); + remove_item(human_selected,PO_TELO_D); + remove_item(human_selected,PO_TELO_H); + break; + case PL_OBOUR:remove_item(human_selected,PO_RUKA_L); + break; + case PL_TELO_H: + case PL_TELO_D: + case PL_HLAVA:remove_item(human_selected,PO_KUTNA); + break; + case PL_RUKA :if (place==PO_RUKA_L) + if (human_selected->wearing[PO_RUKA_R] && glob_items[human_selected->wearing[PO_RUKA_R]-1].umisteni==PL_OBOUR) + remove_item(human_selected,PO_RUKA_R); + if (check_double_wield(place,*picked_item)) + remove_item(human_selected,place==PO_RUKA_L?PO_RUKA_R:PO_RUKA_L); + break; + } + human_selected->wearing[place]=*picked_item; + if (itsave) *picked_item=itsave; + else + { + free(picked_item);picked_item=NULL; + } + } + if (picked_item!=NULL && glob_items[*picked_item-1].flags & ITF_NOREMOVE) + { + destroy_items(picked_item); + free(picked_item); + picked_item=NULL; + } + play_sample_at_channel(H_SND_WEAR,1,100); + prepocitat_postavu(human_selected); + zkontroluj_postavu(); + pick_set_cursor(); + inv_redraw(); + return 1; + } + + +void *inv_keyboard(EVENT_MSG *msg,void **usr) + { + char c; + + usr; + if (msg->msg==E_KEYBOARD) + { + c=(*(int *)msg->data)>>8; + switch (c) + { + case 0x17: + case 1:unwire_inv_mode(); + wire_proc(); + inv_view_mode=0; + break; + case 28: + case 15: + case 50: + if (GlobEvent(MAGLOB_BEFOREMAPOPEN,viewsector,viewdir)) + { + unwire_inv_mode(); + show_automap(1); + } + break; + } + } + return &inv_keyboard; + } + + +void wire_inv_mode(THUMAN *select) + { + mute_all_tracks(0); + send_message(E_ADD,E_KEYBOARD,inv_keyboard); + change_click_map(clk_inv_view,CLK_INV_VIEW); + send_message(E_ADD,E_MOUSE,inv_item_info_box); + human_selected=select; + if (human_selected->bonus!=0 && picked_item==NULL) inv_view_mode=1; + cur_mode=MD_INV; + build_all_players(); + redraw_inventory(); + unwire_proc=unwire_inv_mode; + inv_redraw=redraw_inventory; + } + +static LETICI_VEC *fly_map=NULL; +static int fly_map_size=0; //velikost mapy +static int fly_count; //vyuziti mapy + +void draw_fly_items(int celx,int cely,int sector,int side) + { + LETICI_VEC *p; + int xpos,ypos; + short *pic,picnum;char turn,smr; + TITEM *it; + int i; + + p=fly_map; + if (map_coord[sector].flags & 2) + { + i=fly_count; + while (i--) + if (p->sector==sector && (p->items!=NULL || p->item!=0)) + { + switch(smr=(p->smer-side)&0x3) + { + case 0: xpos=p->ypos;ypos=p->xpos;turn=(celx*128+xpos)<0;break; + case 1: xpos=p->xpos;ypos=-p->ypos;turn=1;break; + case 2: xpos=-p->ypos;ypos=-p->xpos;turn=(celx*128+xpos)<0;break; + case 3: xpos=-p->xpos;ypos=p->ypos;turn=0;break; + } + xpos+=64; + ypos+=64; + if (p->items==NULL) it=glob_items+p->item-1;else it=&glob_items[*(p->items)-1]; + if (p->flags & FLY_DESTROY_SEQ) smr=3; + else if (smr==3) smr=1; + picnum=it->v_letu[(smr<<2)+p->anim_pos]; + if (!picnum) + if (it->vzhled) + picnum=it->vzhled+face_arr[0]; + else + picnum=0; + else picnum+=face_arr[3]; + if (picnum) + { + pic=ablock(picnum); + draw_placed_texture(pic,celx,cely,xpos,ypos,p->zpos,turn); + } + p++; + } + else p++; + } + } + +void build_fly_map() + { + LETICI_VEC *p,*p2; + static int counter=0; + + fly_count=0; + for(p=letici_veci;p!=NULL;p=p->next) if (!(p->flags & (FLY_BURNT|FLY_UNUSED))) fly_count++; + if (fly_count>fly_map_size || !counter) + { + free(fly_map);fly_map=NewArr(LETICI_VEC,fly_count); + if (!counter) + SEND_LOG("(FLY) Fly_map was reduced - capacity: %d flies in game / was: %d",fly_count,fly_map_size); + else + SEND_LOG("(FLY) Fly_map was expanded - capacity: %d flies in game ",fly_count,fly_map_size); + counter=1000; + fly_map_size=fly_count; + } + else counter--; + for(p=letici_veci,p2=fly_map;p!=NULL;p=p->next) if (!(p->flags & (FLY_BURNT|FLY_UNUSED))) + { + map_coord[p->sector].flags|=2; + p->anim_pos++;p->anim_pos&=3; + memcpy(p2,p,sizeof(LETICI_VEC)); + if (p->flags & FLY_DESTROY_SEQ && p->anim_pos==3) + { + stop_fly(p,1); + } + p2++; + } + else + p->flags|=FLY_UNUSED; + } + +void destroy_fly_map() + { + int i; + LETICI_VEC *f; + + for(i=0,f=fly_map;isector].flags &=~MC_FLY; + fly_count=0; + } + + + +void add_fly(LETICI_VEC *p) + { + + p->next=letici_veci; + letici_veci=p; + } + + +LETICI_VEC *throw_fly(int x,int y, char rovne) + { + LETICI_VEC *p; + int m; + + p=create_fly(); + p->zpos=128-y*128/360; + p->ypos=(x>320)?32:-32; + p->sector=viewsector; + p->smer=viewdir; + p->items=picked_item; + p->counter=0; + p->hit_bonus=0; + p->damage=0; + m=abs(celkova_vaha(picked_item)); + if (mglob.map_effector==ME_PVODA) m+=50; + p->flags=(rovne?FLY_NEHMOTNA:0) | (glob_items[*picked_item-1].flags & ITF_DESTROY?FLY_DESTROY:0); + if (m) p->speed=1000/(m)+1;else p->speed=24; + if (p->speed>56) p->speed=56; + p->xpos=p->speed+1; + p->velocity=-(360-y)/72; + if (rovne) p->velocity=0; + if (select_player==-1 || !battle) p->owner=postavy-human_selected+1; + else p->owner=select_player+1; + p->hit_bonus=0; + add_fly(p); + picked_item=NULL; + if (!battle) pick_set_cursor(); + return p; + } + +void build_all_players() + { + int i; + + for(i=0;imsg==E_MOUSE) + { + MS_EVENT *ms; + int x,y; + char cc=1; + static last_pos=-1; + + ms=get_mouse(msg); + x=ms->x-(BUYBOX_X+SHP_ICPLCX); + y=ms->y-(BUYBOX_Y+SHP_ICPLCY); + if (picked_item==NULL && x>0 && y>0 && x<(4*SHP_ICSIZX) && y<(2*SHP_ICSIZY)) + { + int i,j; + x/=SHP_ICSIZX; + y/=SHP_ICSIZY; + i=4*y+x; + if (i<8 && (j=shp_item_map[i])!=0 && i!=last_pos) + { + char c[80]; + char s[80]; + int cena=cur_shop->list[shp_item_pos[i]].cena; + + j--; + schovej_mysku(); + sprintf(c,"%s (%d)",glob_items[j].jmeno,cena+cur_shop->koef*cena/100); + inv_info_box(c,glob_items[j].popis,get_item_req(s,j+1),!muze_nosit(j+1)); + ukaz_mysku(); + showview(INV_INFO_X-VEL_RAMEC,INV_INFO_Y-VEL_RAMEC,INV_INFO_XS+2*VEL_RAMEC+2,INV_INFO_YC+2*VEL_RAMEC+2); + last_pos=i; + cc=0; + } + else cc=i!=last_pos; + } + if (cc) + { + inv_item_info_box(msg,unused); + last_pos=-1; + } + } + } +static void rebuild_shops(void) + { + char *c=(char *)shop_hacek; + int i; + + SEND_LOG("(SHOP) Rebuilding shops....",0,0); + if (shop_list!=NULL) free(shop_list); + shop_list=NewArr(TSHOP *,max_shops); + c+=4; + for(i=0;ilist=(TPRODUCT *)c; + c+=p->products*sizeof(TPRODUCT); + SEND_LOG("(SHOP) Shop found: '%s'",p->keeper,0); + } + } + +void load_shops(void) + { + char *c; + int *d; + if (!test_file_exist(SR_MAP,SHOP_NAME)) + { + shop_hacek=NULL; + shop_list=NULL; + return; + } + shop_hacek=afile(SHOP_NAME,SR_MAP,&shop_hacek_size); + d=shop_hacek;c=shop_hacek; + max_shops=*d; + if (!max_shops) + { + free(shop_hacek); + shop_hacek=NULL; + shop_list=NULL; + return; + } + rebuild_shops(); + } + +static void rebuild_keepers_items() + { + int i; + TPRODUCT *p; + int remain; + char c; + + memset(shp_item_map,0,sizeof(shp_item_map)); + memset(shp_item_pos,0,sizeof(shp_item_map)); + do + { + remain=cur_shop->list_size-top_item; + p=cur_shop->list+top_item; + for(i=0;i<8 && remain>0;remain--,p++) + if (p->trade_flags & SHP_SELL && p->pocet) + { + shp_item_pos[i]=p-cur_shop->list; + shp_item_map[i++]=p->item+1; + } + c=(i<8 && top_item); + if (c) top_item--; + } + while (c); + } + +static int make_offer(int i) + { + int j; + i--; + for(j=0;jlist_size;j++) + { + TPRODUCT *p=cur_shop->list+j; + if (p->item==i && p->trade_flags & SHP_BUY) return p->cena-(p->cena*cur_shop->koef/100); + } + return 0; + } + +static int get_sell_price(int i) //cislo predmetu + { + int j; + i--; + for(j=0;jlist_size;j++) + { + TPRODUCT *p=cur_shop->list+j; + if (p->item==i && p->trade_flags & SHP_SELL && p->pocet>0) return p->cena+(p->cena*cur_shop->koef/100); + } + return 0; + } + +static TPRODUCT *find_sell_product(int i) //cislo predmetu + { + int j; + i--; + for(j=0;jlist_size;j++) + { + TPRODUCT *p=cur_shop->list+j; + if (p->item==i) return p; + } + return NULL; + } + + +static void sell_item(int i) + { + int j; + i--; + for(j=0;jlist_size;j++) + { + TPRODUCT *p=cur_shop->list+j; + if (p->item==i) + { + p->pocet--; + return; + } + } + } + +static void buy_item(int i) + { + int j; + i--; + for(j=0;jlist_size;j++) + { + TPRODUCT *p=cur_shop->list+j; + if (p->item==i) + { + p->pocet++; + return; + } + } + } + +static void display_keepers_items() + { + int x,y,i; + put_picture(BUYBOX_X,BUYBOX_Y,ablock(H_SHOP_PIC)); + i=0; + for(y=0;y<2*SHP_ICSIZY;y+=SHP_ICSIZY) + for(x=0;x<4*SHP_ICSIZX;x+=SHP_ICSIZX) + if (shp_item_map[i]) + { + int ikn; + + ikn=glob_items[shp_item_map[i++]-1].ikona; + put_picture(BUYBOX_X+SHP_ICPLCX+x,BUYBOX_Y+SHP_ICPLCY+y,ico_extract(ikn)); + } + else + i++; + set_font(H_FBOLD,INV_NAME_COL); + set_aligned_position(135+BUYBOX_X,17+BUYBOX_Y,1,1,cur_shop->keeper); + outtext(cur_shop->keeper); + } + +static void redraw_shop() + { + update_mysky(); + schovej_mysku(); + curcolor=0; + display_items_in_inv(human_selected); + display_keepers_items(); + //write_shopkeeper_name(cur_shop->keeper); + other_draw(); + info_box_drawed=0; + if (info_box_below!=NULL) free(info_box_below); + info_box_below=NULL; + ms_last_event.event_type=0x1;send_message(E_MOUSE,&ms_last_event); + ukaz_mysku(); + showview(0,0,0,0); + } + + + +static void block_next() + { + TPRODUCT *p=cur_shop->list+top_item; + int remain=cur_shop->list_size-top_item; + int i,j; + + if (remain<8) return; + j=top_item; + for(i=0;i<8 && remain>0;j++,remain--,p++) if (p->pocet && p->trade_flags & SHP_SELL) i++; + if (i!=8 || !remain) return; + top_item=j; + } + +static void block_back() + { + TPRODUCT *p=cur_shop->list+top_item; + int i,j; + + + if (top_item<8) top_item=0; + else + { + j=top_item; + for(i=0;i<8 && j>0;j--,p--) if (p->pocet && p->trade_flags & SHP_SELL) i++; + if (i==8) top_item=j; else top_item=0; + } + return; + } + +static void redraw_keepers_items() + { + word *w; + schovej_mysku(); + w=ablock(H_SHOP_PIC); + display_keepers_items(); + ukaz_mysku(); + showview(BUYBOX_X,BUYBOX_Y,w[0],w[1]); + } + +static char shop_keeper_click(int id, int xa, int ya,int xr,int yr) + { + id;xa;ya; + if (picked_item==NULL) + { + int i,j; + xr=(xa-BUYBOX_X-SHP_ICPLCX); + yr=(ya-BUYBOX_Y-SHP_ICPLCY); + if (xr<0 || yr<0) return 0; + xr/=SHP_ICSIZX; + yr/=SHP_ICSIZY; + i=yr*4+xr; + if (i<8 && i>=0 && (j=shp_item_map[i])!=0) + { + picked_item=NewArr(short,2); + picked_item[0]=shp_item_map[i]; + picked_item[1]=0; + shp_item_map[i]=0; + cur_owner=-1; + schovej_mysku(); + pick_set_cursor(); + redraw_keepers_items(); + ukaz_mysku(); + update_mysky(); + if ((GetKeyState(VK_CONTROL) & 0x80) && (game_extras & EX_FAST_TRADE) && get_sell_price(*picked_item)<=money) + { + play_sample_at_channel(H_SND_OBCHOD,1,100); + money-=get_sell_price(*picked_item); + sell_item(*picked_item); + if (put_item_to_inv(human_selected,picked_item)) + { + picked_item=NULL; + pick_set_cursor(); + } + rebuild_keepers_items(); + cur_owner=picked_item!=NULL; + redraw_shop(); + } + return 1; + } + } + else + if (cur_owner==-1) + { + free(picked_item); + picked_item=NULL; + rebuild_keepers_items(); + schovej_mysku(); + pick_set_cursor(); + redraw_keepers_items(); + ukaz_mysku(); + update_mysky(); + cur_owner=0; + return 1; + } + if (cur_owner!=-1 && picked_item!=NULL) + { + int price,z; + char c[200]; + mouse_set_cursor(H_MS_DEFAULT); + if (picked_item[1]!=0) + { + message(1,0,0,"",texty[100],texty[80]); + wire_shop(); + } + else + { + price=make_offer(z=picked_item[0]); + if (!price) + { + sprintf(c,texty[103],glob_items[z-1].jmeno); + message(1,0,0,"",c,texty[80]); + wire_shop(); + } + else + { + int p;TPRODUCT *pp; + + pp=find_sell_product(z); + sprintf(c,texty[102],price); + p=message(3,0,1,texty[118],c,texty[77],texty[230],texty[78]); + if (p==2) price=-1; + if (p==1) price=smlouvat(price,pp->cena,pp->pocet,money,0); + if (price>=0) + { + play_sample_at_channel(H_SND_OBCHOD,1,100); + buy_item(z); + free(picked_item);picked_item=NULL; + money+=price; + rebuild_keepers_items(); + } + wire_shop(); + } + } + pick_set_cursor(); + update_mysky(); + return 1; + } + return 0; + } + + +static char shop_bag_click(int id,int xa,int ya,int xr,int yr) + { + char s[200],p; + int price,z; + TPRODUCT *pp; + if (cur_owner>-1) + { + id=bag_click(id,xa,ya,xr,yr); + cur_owner=picked_item!=NULL; + if (picked_item!=NULL && picked_item[1]==0 && (game_extras & EX_FAST_TRADE) && (GetKeyState(VK_CONTROL) & 0x80)) + { + short z; + price=make_offer(z=picked_item[0]); + if (price) + { + play_sample_at_channel(H_SND_OBCHOD,1,100); + buy_item(z); + free(picked_item);picked_item=NULL; + money+=price; + rebuild_keepers_items(); + pick_set_cursor(); + redraw_shop(); + } + } + return id; + } + if (picked_item==NULL) return 0; + z=picked_item[0]; + price=get_sell_price(z); + pp=find_sell_product(z); + if (pp==NULL) return 0; + mouse_set_cursor(H_MS_DEFAULT); + if (!price) return 0; + if (price>money) + { + p=message(2,0,0,"",texty[104],texty[230],texty[78]); + if (!p) price=smlouvat(price,pp->cena,pp->pocet,money,1);else price=-1; + } + else + { + sprintf(s,texty[101],price); + p=message(3,0,1,texty[118],s,texty[77],texty[230],texty[78]); + if (p==1) price=smlouvat(price,pp->cena,pp->pocet,money,1);else + if (p==2) price=-1; + } + if (price>=0) + { + play_sample_at_channel(H_SND_OBCHOD,1,100); + money-=price; + sell_item(z); + rebuild_keepers_items(); + id=bag_click(id,xa,ya,xr,yr); + cur_owner=picked_item!=NULL; + } + else + { + shop_keeper_click(0,0,0,0,0); + } + wire_shop(); + return 1; + } + +static char shop_block_click(int id, int xa, int ya,int xr,int yr) + { + xa,ya,xr,yr; + if (id==1) block_back();else block_next(); + rebuild_keepers_items(); + redraw_keepers_items(); + return 1; + } + + +static int old_inv_view_mode; + +void unwire_shop() + { + send_message(E_DONE,E_MOUSE,shop_mouse_event); + norefresh=0; + wire_proc=wire_shop; + inv_view_mode=old_inv_view_mode; + } + +void wire_shop() + { + long size; + static TSHOP *last_shop=NULL; + static void *pic=NULL; + mute_all_tracks(0); + old_inv_view_mode=inv_view_mode; + inv_view_mode=0; + inv_redraw=redraw_shop; + schovej_mysku(); + if (last_shop!=cur_shop) + { + free(pic);pic=afile(cur_shop->picture,SR_DIALOGS,&size); + last_shop=cur_shop; + } + if (cur_shop->picture[0]) put_picture(5,SCREEN_OFFLINE,pic); + send_message(E_ADD,E_MOUSE,shop_mouse_event); + unwire_proc=unwire_shop; + change_click_map(clk_shop,CLK_SHOP); + if (shop_sector==viewsector) redraw_shop();else _exit_shop(0,0,0,0,0); + ukaz_mysku(); + update_mysky(); + } + +void enter_shop(int shopid) + { + int i; + + SEND_LOG("(SHOP) Entering shop...",0,0); + for(i=0;ishop_id==shopid) break; + if (i==max_shops) return; + unwire_proc(); + cur_shop=shop_list[i]; + curcolor=0; + bar(0,0,639,479); + rebuild_keepers_items(); + bott_draw(1); + shop_sector=viewsector; + wire_shop(); + cancel_render=1; + cancel_pass=1; + norefresh=1; + cur_mode=MD_SHOP; + } + + word *xs; + +char shop_change_player(int id, int xa, int ya,int xr,int yr) + { + word *xs; + int i; + + id;xa;ya;yr; + xs=ablock(H_OKNO); + i=xr/xs[0]; + if (iused && p->sektor==viewsector) + if (ms_last_event.event_type & 0x2) + { + int j=select_player; + select_player=i; + human_selected=p; + if (i==j && cur_owner>-1) + { + unwire_proc(); + wire_inv_mode(p); + } + else + { + bott_draw(1); + redraw_shop(); + } + } + else if (picked_item!=NULL && cur_owner>-1) + { + if (put_item_to_inv(p,picked_item)) + { + free(picked_item);picked_item=NULL; + pick_set_cursor(); + redraw_shop(); + } + } + else if (picked_item==NULL) _exit_shop(id,xa,ya,xr,yr); + + return 1; + } + return 0; + } + +char _exit_shop(int id, int xa, int ya,int xr,int yr) + { + xr,yr,xa,ya,id; + SEND_LOG("(SHOP) Exiting shop...",0,0); + if (cur_owner==-1) + { + free(picked_item); + picked_item=NULL; + pick_set_cursor(); + } + unwire_proc(); + wire_main_functs(); + return 1; + } + + +static void reroll_shop(TSHOP *p) + { + int i,j,r; + int poc_spec=0; + TPRODUCT *pr; + + SEND_LOG("(SHOP) Shops reroll: '%s' ",p->keeper,0); + pr=p->list; + for(i=0;ilist_size;i++,pr++) + { + if (pr->trade_flags & SHP_AUTOADD && pr->pocetmax_pocet) pr->pocet++; + if (pr->trade_flags & SHP_SPECIAL) + { + poc_spec++;if (pr->pocet>0) pr->pocet=0; + } + } + pr=p->list; + for(i=0;ispec_max;i++) + { + int i=0; + r=rnd(poc_spec)+1; + for(j=0;i +/* + + Popis jazyka pro psani textu do knihy + + + [cislo] + + .... text + .... + + [/cislo] + + + Tagy + +

paragraph +
break line + +


horizontal rule + page end + + + + ----------------------------- + + Vnitrni zapis + + Escape sekvence + + ESC s - mezera n bodu + ESC p obrazek na souradnicich x a y + ESC e - konec stranky (jako prvni v textu) + ESC h - horizontalni rule (jako prvni v textu) + ESC l - konec radky (skip je pocet vynechanych bodu) + + Zapis cisla - to je hexa cislo od 1-255 pokud se nevejde do rozsahu je po 256 + pridana dalsi hodnota, tj 255 se zapise jako 255,1, + 350 se zapise jako 255,96, + +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include "globals.h" + +#define XMAX 254 +#define YMAX 390 +#define XLEFT 34 +#define YLEFT 50 +#define XRIGHT 354 + +#define PARAGRAPH "P" +#define BREAKLINE "BR" +#define IMAGE "IMG" +#define HOR_RULE "HR" +#define CENTER1 "CENTER" +#define CENTER2 "/CENTER" +#define DISTEND1 "DISTEND" +#define DISTEND2 "/DISTEND" +#define ALIGN "ALIGN" +#define PIC_LINE "LINE" +#define PIC_LSIZ "LSIZE" +#define SRC "SRC" + +#define ALEFT "LEFT" +#define ARIGHT "RIGHT" +#define ACENTER "CENTER" + +#define ANUM_LEFT 1 +#define ANUM_RIGHT 2 +#define ANUM_CENTER 0 + +#define END_PAGE 'e' +#define SPACE 's' +#define PICTURE 'p' +#define HRUL 'h' +#define END_LINE 'l' + +#define BOOK_FILE "_BOOK.TMP" + +static int center=0; +static int distend=0; +static TSTR_LIST all_text=NULL; +static char read_buff[256]; +static char write_buff[256]; +static int buff_pos=0; +static int buff_end=0; +static int total_width=XMAX; +static int left_skip=0; +static int linepos=0,last_skip=1; +static int picture_len=0; +static char winconv=0; +static int relpos=0; + +static char xlat_table[128]="___________________________________________________________________________________"; + +static int insert_num(char *text,int pos,int num) + { + char c=0x80; + do + { + c=num & 0x3f;num>>=6; + if (num) c|=0x80; + c|=0x40; + text[pos++]=c; + } + while (num); + return pos; + } + + +static int read_num(char *text,int *pos) + { + int num=0,shift=0; + char c; + + do + { + c=text[pos[0]++]; + num|=(c & 0x3f)<YMAX) + { + char s[3]; + s[0]=27; + s[1]=END_PAGE; + s[2]=0; + str_add(&all_text,s); + linepos=0; + picture_len=-1; + } + last_skip=step; + } + + +static int insert_end_line_and_save(int p,int ys) + { + int size; + while (read_buff[buff_pos]==' ' && buff_pos0) picture_len-=ys; + if (picture_len<=0 && total_width!=XMAX) + { + picture_len=0; + total_width=XMAX; + left_skip=0; + } + return p; + } + +static int insert_left_skip(int p,int skip) + { + skip+=left_skip; + if (skip) + { + write_buff[p++]=27; + write_buff[p++]=SPACE; + p=insert_num(write_buff,p,skip); + } + return p; + } + +static void save_line_oboustrane() + { + char space[]=" "; + int xs,ys,ss,mez,mm=0,mc=0; + int i,p; + + for(i=0,xs=0,mez=0,ys=0;iys) ys=p; + } + } + ss=total_width-xs; + p=0; + if (!ys) ys=last_skip; + next_line(ys); + p=insert_left_skip(p,0); + for(i=0,mc=0;iys) ys=p; + } + p=0; + if (!ys) ys=last_skip; + next_line(ys); + ss=total_width-xs; + p=insert_left_skip(p,ss/2); + memcpy(write_buff+p,read_buff,buff_pos); + p+=buff_pos; + write_buff[p]=0; + insert_end_line_and_save(p,ys); + } + +static void save_line_left() + { + int p,z; + int ys; + + p=0; + p=insert_left_skip(p,0);z=p; + if (buff_pos) memcpy(write_buff+p,read_buff,buff_pos); + p+=buff_pos; + write_buff[p]=0; + ys=text_height(write_buff+z); + if (!ys) ys=last_skip; + next_line(ys); + insert_end_line_and_save(p,ys); + } + + +static void save_buffer() + { + while (buff_end>buff_pos && read_buff[buff_end]==32) buff_end--; + if (center) save_line_center(); + else if (buff_pos==buff_end || !distend) save_line_left(); else save_line_oboustrane(); + } + +static void break_line() + { + buff_pos=buff_end; + save_buffer(); + } + +static char read_set(FILE *txt,char *var,char *set) + { + int c; + char *cc; + + fscanf(txt,"%[^=]%c",var,&c); + do + c=fgetc(txt); + while (c<33); + if (c=='"') fscanf(txt,"%[^\"]%c%c",set,&c,&c); + else if (c=='\'') fscanf(txt,"%[^']%c%c",set,&c,&c); + else + { + ungetc(c,txt); + fscanf(txt,"%[^> ]%c",set,&c); + } + while(c<33 && c!=EOF) c=fgetc(txt); + if (c!='>') ungetc(c,txt); + cc=strchr(var,0); + while (cc!=var) + { + cc--; + if (*cc>32) + { + cc++; + break; + } + } + *cc=0; + strupr(set); + strupr(var); + return c; + } + +static int get_data_handle(char *filename,void *dec) + { + int i; + + i=find_handle(filename,dec); + if (i==-1) + { + i=end_ptr++; + def_handle(i,filename,dec,SR_DIALOGS); + } + return i; + } + +static void insert_picture(char *filename,int align,int line,int lsize) + { + int x, y; + short *psiz; + char *c=write_buff; + + psiz=ablock(get_data_handle(filename,pcx_8bit_decomp)); + switch (align) + { + case ANUM_CENTER: + x=(XMAX-psiz[0])/2; + y=linepos; + linepos+=psiz[1]; + *c++=27; + *c++=END_LINE; + c+=insert_num(c,0,psiz[1]+last_skip); + break; + case ANUM_LEFT: x=0; + y=linepos; + left_skip=psiz[0]+5; + total_width=XMAX-left_skip; + break; + case ANUM_RIGHT: total_width=(x=XMAX-psiz[0])-5; + left_skip=0; + y=linepos; + break; + } + if (!lsize) lsize=psiz[1]-line; + picture_len=lsize; + *c++=27; + *c++=PICTURE; + while (*filename) *c++=*filename++; + *c++=':'; + c+=insert_num(c,0,x); + c+=insert_num(c,0,y); + c+=insert_num(c,0,line); + c+=insert_num(c,0,lsize); + *c++=0; + str_add(&all_text,write_buff); + } + +static char read_tag(FILE *txt) + { + char c,var[256],set[256]; + int i; + + i=fscanf(txt,"%[^> ] %c",var,&c); + while(c<33 && i!=EOF) c=i=fgetc(txt); + if (c!='>') ungetc(c,txt); + strupr(var); + if (!strcmp(var,PARAGRAPH)) + { + break_line(); + break_line(); + return 1; + } + if (!strcmp(var,BREAKLINE)) + { + break_line(); + return 1; + } + if (!strcmp(var,IMAGE)) + { + char pic_name[50]=" "; + char alig=0; + int line=0,lsize=0; + + while (c!='>') + { + c=read_set(txt,var,set); + if (!strcmp(var,SRC)) strncpy(pic_name,set,49); + else if (!strcmp(var,ALIGN)) + { + if (!strcmp(set,ALEFT)) alig=1; + else if (!strcmp(set,ARIGHT)) alig=2; + else if (!strcmp(set,ACENTER)) alig=0; + } + else if (!strcmp(var,PIC_LINE)) sscanf(set,"%d",&line); + else if (!strcmp(var,PIC_LSIZ)) sscanf(set,"%d",&lsize); + } + if (pic_name[0]!=0) + insert_picture(pic_name,alig,line,lsize); + return 0; + } + if (!strcmp(var,CENTER1)) center++; + else if (!strcmp(var,CENTER2)) + { + if (center>0) center--; + } + else if (!strcmp(var,DISTEND1)) distend++; + else if (!strcmp(var,DISTEND2)) + { + if (distend>0) distend--; + } + return 0; + } + + +static char skip_section(FILE *txt) + { + int c; + char end=1; + + c=fgetc(txt); + while (c!=']' && c!=EOF) + { + c=fgetc(txt); + end=0; + } + if (c==EOF) end=1; + return end; + } + +void prekodovat(char *c) + { + while (*c) + { + if (*c>137) *c=xlat_table[*c-138]; + c++; + } + } + +static void read_text(FILE *txt) + { + int i; + int xs; + char ss[2]=" "; + char wsp=1; + + buff_pos=0; + buff_end=0; + xs=0; + do + { + i=fgetc(txt); + if (i==EOF) break; + if (i<32) i=32; + if (i=='<') + { + if (read_tag(txt)) + { + xs=0; + wsp=1; + } + continue; + } + if (i=='[') + { + if (skip_section(txt)) break; + continue; + } + if (i==32) + { + if (wsp) continue; + buff_pos=buff_end; + wsp=1; + } + else wsp=0; + if (i=='&') i=fgetc(txt); + if (winconv && i>137) i=xlat_table[i-138]; + ss[0]=i; + xs+=text_width(ss); + read_buff[buff_end++]=i; + if (xs>total_width && !wsp) + { + save_buffer(); + read_buff[buff_end]=0; + xs=text_width(read_buff); + } + } + while (1); + } + +void seek_section(FILE *txt,int sect_number) + { + int c=0,i; + + winconv=0; + do + { + while (c!='[' && c!=EOF) c=fgetc(txt); + if (c=='[') + { + i=-2; + fscanf(txt,"%d",&i); + if (i==sect_number) + { + c=fgetc(txt); + while(c!=']') + { + if (c=='W' || c=='w') winconv=1; + if (c=='K' || c=='k') winconv=0; + c=fgetc(txt); + } + return; + } + } + c=0; + } + while (i!=EOF); + closemode(); + { + char buff[256]; + sprintf(buff,"Nemohu najit odstavec s cislem %d.",sect_number); + MessageBox(NULL,buff,NULL,MB_OK|MB_ICONSTOP); + } + exit(1); + } + +void add_text_to_book(char *filename,int odst) + { + FILE *txt; + ENCFILE fl; + + set_font(H_FKNIHA,NOSHADOW(0)); + if (all_text==NULL) all_text=create_list(256); + txt=enc_open(filename,&fl); + if (txt==NULL) return; + seek_section(txt,odst); + read_text(txt); + next_line(1000); + enc_close(&fl); + } + +static char *displ_picture(char *c) + { + char *d; + int x,y,hn,z,ln,sl; + short *sh; + + d=write_buff; + while (*c!=':') *d++=*c++; + *d++=0;c++; + hn=get_data_handle(write_buff,pcx_8bit_decomp); + x=read_num(c,(z=0,&z));c+=z; + y=read_num(c,(z=0,&z));c+=z; + ln=read_num(c,(z=0,&z));c+=z; + sl=read_num(c,(z=0,&z));c+=z; + sh=ablock(hn); + if (sh[1]+y>YMAX) return c; + y+=YLEFT; + x+=relpos; + put_8bit_clipped(sh,GetScreenAdr()+x+scr_linelen2*y,ln,sh[0],sl); + return c; + } + +void write_book(int page) + { + int i=0,y=0,z,zz,ps,pg; + char *c; + char space[]=" "; + + pg=page; + if (all_text==NULL) return; + set_font(H_FKNIHA,NOSHADOW(0)); + relpos=XLEFT; + zz=str_count(all_text); + if (--page) + for(i=0;izz) break; + c=all_text[i]; + if (c==NULL) break; + if (c[0]==27 && c[1]==END_PAGE) break; + while (*c) + { + z=0; + if (*c==27) + { + c++; + switch (*c++) + { + case SPACE: + rel_position_x(read_num(c,&z)); + c+=z; + break; + case END_LINE: + y+=read_num(c,&z); + position(relpos,YLEFT+y); + c+=z; + break; + case PICTURE: + c=displ_picture(c); + break; + } + } + else + { + space[0]=*c++; + outtext(space); + } + } + i++; + } + while (1); + i++;y=0; + relpos=XRIGHT; + if (ps==0) + { + char s[20]; + sprintf(s,texty[135],pg); + set_aligned_position(XLEFT,YLEFT+YMAX,0,0,s); + outtext(s); + } + if (ps==1) + { + char s[20]; + sprintf(s,texty[136],pg+1); + set_aligned_position(XRIGHT+XMAX,YLEFT+YMAX,2,0,s); + outtext(s); + } + } + } + +int count_pages() + { + int i,cn,z; + char *c; + + if (all_text==NULL) return 0; + z=str_count(all_text); + for(i=0,cn=0;i +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include "engine1.h" +#include "globals.h" + + +#define S_jmeno 128 +#define S_kouzlo 129 +#define S_zivel 131 +#define S_level 133 +#define S_mge 134 +#define S_hpnorm_min 135 +#define S_hpnorm_max 136 +#define S_hpzivl_min 137 +#define S_hpzivl_max 138 +#define S_vlastnost 139 +#define S_vls_kolik 140 +#define S_trvani 141 +#define S_cil 142 +#define S_throw_item 142 +#define S_create_item 143 +#define S_backfire 144 +#define S_povaha 145 +#define S_special 146 +#define S_pvls 147 +#define S_animace 148 +#define S_zvuk 149 +#define S_wait 150 +#define S_set 151 +#define S_reset 152 +#define S_drain_min 153 +#define S_drain_max 154 +#define S_accnum 155 +#define S_kondice 156 +#define S_mana 157 +#define S_create_weapon 158 +#define S_mana_clip 159 +#define S_mana_steal 160 +#define S_rand_min 161 +#define S_rand_max 162 +#define S_location_sector 163 +#define S_location_map 164 +#define S_location_dir 165 +#define S_location_x 166 +#define S_location_y 167 + +#define C_kouzelnik 0 +#define C_postava 1 +#define C_policko 2 +#define C_druzina 2 +#define C_policko_pred 3 +#define C_mrtva_postava 4 +#define C_postava_jinde 5 +#define C_nahodna_postava 6 +#define C_jiny_cil 7 + +#define SP_AUTOMAP4 1 +#define SP_AUTOMAP8 2 +#define SP_AUTOMAP15 3 +#define SP_PRIPOJENI1 4 +#define SP_PRIPOJENI3 5 +#define SP_PRIPOJENIA 6 +#define SP_CHVENI 7 +#define SP_DEFAULT_EFFEKT 8 +#define SP_TRUE_SEEING 9 +#define SP_SCORE 10 +#define SP_HALUCINACE 11 +#define SP_TELEPORT 12 +#define SP_SUMMON 13 +#define SP_HLUBINA1 14 +#define SP_HLUBINA2 15 +#define SP_MANABAT 16 +#define SP_VAHY 17 +#define SP_RYCHLOST 18 +#define SP_VIR 19 +#define SP_DEMON1 20 +#define SP_DEMON2 21 +#define SP_DEMON3 22 +#define SP_VZPLANUTI1 23 +#define SP_VZPLANUTI2 24 +#define SP_VZPLANUTI3 25 +#define SP_PHASEDOOR 26 +#define SP_TELEPORT_SECT 27 +#define SP_OPEN_TELEPORT 28 + +#define SS_invis 1 +#define SS_oko 2 +#define SS_tvar 4 + +#define FLG_TRUESEEING 0x10000 //zapnuty TRUESEEING +#define FLG_HLUBINA1 0x20000 //zapnuta HLUBINA pro vsechny +#define FLG_HLUBINA2 0x40000 //zapnuta HLUBINA pro potvory +#define FLG_SCORE 0x80000 //zapnute ukazovani score nad potvorama. +#define FLG_HALUCINACE 0x100000 // zapne halucinaci + +#define GET_WORD(c) *(word *)c;c+=2 + +#define MAX_SPELLS 500 + +char running_anm=0; + +char hlubina_level=0; + +word *anim_render_buffer; + +short teleport_target=0; //cil teleportace + +typedef struct tteleportlocation +{ + short loc_x; + short loc_y; + const char *map; + word sector; + word dir; +}TTELEPLOCATION; + +static TTELEPLOCATION TelepLocation; + +typedef struct tkouzlo + { + word num,um,mge; + word pc; + short owner,accnum; //accnum = akumulacni cislo, owner = kdo kouzlo seslal + int start; + short cil; //kladna cisla jsou postavy zaporna potvory (0 je bez urceni postavy) + char povaha; + word backfire; //backfire / 1 = demon , 0 = bez demona + word wait; //wait - cekani pocet animaci + word delay; //delay - cekani pocet kol + char traceon; //jinak noanim - neprehravaji se animace a zvuky + char spellname[28]; + word teleport_target; + }TKOUZLO; + +TKOUZLO *spell_table[MAX_SPELLS]; +short *vls_table[MAX_SPELLS]; //nove vlastnosti postav + //pokud je cislo vetsi nez 0x7f00 pak dolni byte uvadi percentualni pomer +static long _flag_map[MAX_SPELLS]; //tabulka nastavenych priznaku pro kouzlo. + //prvnich 16 bitu je pro postavu + //hornich 16 bitu je globalne + +short parm1,parm2; +char twins; + +static short rand_value; + +static word *paleta; + +void show_full_lfb12e(void *target,void *buff,void *paleta); +//#pragma aux show_full_lfb12e parm[edi][esi][ebx] modify [eax ecx] +void show_delta_lfb12e(void *target,void *buff,void *paleta); +//#pragma aux show_delta_lfb12e parm[edi][esi][ebx] modify [eax ecx] +char mob_check_next_sector(int sect,int dir,char alone,char passable); + +void call_spell(int i); +int calculatePhaseDoor(int sector, int dir, int um); + + +static void animace_kouzla(int act,void *data, int ssize) + { + switch (act) + { + case MGIF_LZW: + case MGIF_COPY:show_full_lfb12e(anim_render_buffer,data,paleta);break; + case MGIF_DELTA:show_delta_lfb12e(anim_render_buffer,data,paleta);break; + case MGIF_PAL:paleta=data;*paleta|=0x8000;break; + } + } + + + +static void play_anim(va_list args) //tasked animation +//#pragma aux play_anim parm [] + { + int block=va_arg(args,int); +#define ANIM_SIZE (320*180*2) + void *anm; + long *l,c; + + if (running_anm) + { + SEND_LOG("(ERROR)(ANIM) Animation's mutex is already in use!",0,0); + return; + } + SEND_LOG("(ANIM) Running animation number %xh",block,0); + anim_render_buffer=getmem(ANIM_SIZE); + mgif_install_proc(animace_kouzla); + running_anm=1; + l=(void *)anim_render_buffer; + c=ANIM_SIZE/4;do *l++=0x80008000; while (--c); + alock(block); + anm=open_mgif(ablock(block)); + c=0; + SEND_LOG("(ANIM) Buffer is now ready...",0,0); + while (anm!=NULL) + { + task_wait_event(E_KOUZLO_ANM); + c++; + SEND_LOG("(ANIM) Rendering frame %d in animation %xh",c,block); + anm=mgif_play(anm); + neco_v_pohybu=1; + } + task_wait_event(E_KOUZLO_ANM); + close_mgif(); + running_anm=0; + free(anim_render_buffer); + SEND_LOG("(ANIM) Closing animation %xh",block,0); + aunlock(block); + } + +void play_big_mgif_animation(int block) + { + add_task(2048,play_anim,block); + task_sleep(NULL); + } + +int get_spell_mana(int num) + { + TKOUZLO *p; + + p=(TKOUZLO *)ablock(H_KOUZLA); + return p[num].mge; + } + +int get_spell_um(int num) + { + TKOUZLO *p; + + p=(TKOUZLO *)ablock(H_KOUZLA); + return p[num].um; + } + + +int get_spell_used(int num) + { + TKOUZLO *p; + + p=(TKOUZLO *)ablock(H_KOUZLA); + return (p[num].start!=0); + } + +char get_spell_track(int num) + { + TKOUZLO *p; + + p=(TKOUZLO *)ablock(H_KOUZLA); + return (p[num].traceon & 1); + } + +char get_spell_teleport(int num) + { + TKOUZLO *p; + + p=(TKOUZLO *)ablock(H_KOUZLA); + return (p[num].traceon & 2); + } + + +int get_spell_color(THUMAN *p,int num) + { + TKOUZLO *z; + + z=(TKOUZLO *)ablock(H_KOUZLA); + z+=num; + if (!z->start) return 1; + if (z->mge>p->mana) return 1; + if (z->um<=p->vlastnosti[VLS_SMAGIE]) return 0; + if (z->um<=(p->vlastnosti[VLS_SMAGIE]*2)) return 2; + return 1; + } + +char get_rune_enable(THUMAN *p,int strnum) + { + int i; + for(i=0;i<3;i++) if (get_spell_color(p,strnum+i)!=1) return 1; + return 0; + } + +char *get_rune_name(int strnum) + { + TKOUZLO *z; + z=(TKOUZLO *)ablock(H_KOUZLA); + z+=strnum; + return z->spellname; + } + +void spell_anim(char *name) + { + int i; + i=find_handle(name,NULL); + if (i==-1) i=end_ptr++; + def_handle(i,name,NULL,SR_ITEMS); + add_task(8196,play_anim,i); + } + +void spell_sound(char *name) + { + int i; + i=find_handle(name,wav_load); + if (i==-1) i=end_ptr++; + def_handle(i,name,wav_load,SR_ZVUKY); + play_sample_at_channel(i,0,100); + } + +void get_sector_dir(int cil,word *sector,char *dir) + { + if (cil>0) + { + cil--; + if (postavy[cil].used) *sector=postavy[cil].sektor,*dir=postavy[cil].direction; + } + else if (cil<0) + { + cil=-cil-1; + *sector=mobs[cil].sector; + *dir=mobs[cil].dir; + } + } + +static void spell_vzplanuti3(int ss,int hit,int zivel) + { + if (map_coord[ss].flags & MC_PLAYER) + { + THUMAN *h;int i; + + for(i=0,h=postavy;iused && h->lives && h->sektor==ss) + { + int ochrana=mgochrana(h->vlastnosti[VLS_OHEN+zivel]); + player_hit(h,hit*ochrana/100,1); + } + } + if (mob_map[ss]) + { + int i=mob_map[ss]; + while(i) + { + TMOB *m=mobs+i-1; + int ochrana=mgochrana(m->vlastnosti[VLS_OHEN+zivel]); + vybrana_zbran=-1; + mob_hit(m,hit*ochrana/100); + i=m->next; + } + } + + } + +static void spell_vzplanuti2(THE_TIMER *tt) + { + int ss,ss1,ss2,i,dp,dl,du; + int zivel; + + i=tt->userdata[2];if (i<1) i++; + du=tt->userdata[1] & 0xff; + ss=tt->userdata[0]; + zivel=tt->userdata[1] >> 8; + if (map_sides[(ss<<2)+du].flags & SD_PLAY_IMPS) return; + ss1=ss2=ss=map_sectors[ss].step_next[du]; + if (ss==0) return; + dp=du+1&3; + dl=du+3&3; + do + { + if (ss1!=0) + { + add_spectxtr(ss1,H_ARMAGED,H_ARMA_CNT,1,0); + spell_vzplanuti3(ss1,tt->userdata[3],zivel); + } + if (ss2!=ss1 && ss2!=0) + { + add_spectxtr(ss2,H_ARMAGED,H_ARMA_CNT,1,0); + spell_vzplanuti3(ss2,tt->userdata[3],zivel); + } + if (~map_sides[(ss1<<2)+dp].flags & SD_PLAY_IMPS) ss1=map_sectors[ss1].step_next[dp]; + if (~map_sides[(ss2<<2)+dl].flags & SD_PLAY_IMPS) ss2=map_sectors[ss2].step_next[dl]; + } + while(--i); + if (tt->userdata[2]) tt->userdata[2]++; + //tt->userdata[3]=tt->userdata[3]*2/3; + tt->userdata[0]=ss; + } + +static void spell_vzplanuti(int cil,int count,int hit,char mode,char zivel) + { + THE_TIMER *tt; + int sector,smer; + int i,o,d; + if (cil<0) + { + TMOB *m=&mobs[-cil-1]; + sector=m->sector; + smer=m->dir; + } + else if (cil>0) + { + THUMAN *h=postavy+cil-1; + sector=h->sektor; + smer=h->direction; + } + if (mode) {o=smer;d=smer+1;}else o=0,d=4; + for(i=o;i1) tt=add_to_timer(TM_VZPLANUTI,25,count-1,spell_vzplanuti2); + else tt=&tts; + tt->userdata[0]=sector; + tt->userdata[1]=i+(zivel<<8); + tt->userdata[2]=!mode; + tt->userdata[3]=hit; + spell_vzplanuti2(tt); + } + neco_v_pohybu=1; + } + +void spell_create(int cil,int what) + { + word sector=0; + char dir; + short p[2]; + + get_sector_dir(cil,§or,&dir); + p[0]=what+1; p[1]=0; + push_item(sector,dir,p); + } + +void spell_create_weapon(int cil,int what) + { + THUMAN *h=postavy+cil-1; + short lr,pr; + + lr=h->wearing[PO_RUKA_L]; + pr=h->wearing[PO_RUKA_R]; + if (lr && glob_items[lr-1].umisteni==PL_OBOUR) pr=lr; + else if (pr && glob_items[pr-1].umisteni==PL_OBOUR) lr=pr; + if (lr && pr) + { + char s[256]; + + sprintf(s,texty[86],h->jmeno); + bott_disp_text(s); + return; + } + if (!pr) h->wearing[PO_RUKA_R]=what+1; + else if (!lr) h->wearing[PO_RUKA_L]=what+1; + prepocitat_postavu(h); + } + +void spell_throw(int cil,int what) + { + word sector=0; + char dir; + LETICI_VEC *fly; + + get_sector_dir(cil,§or,&dir); + fly=create_fly(); + fly->item=what+1; + fly->items=NULL; + fly->xpos=-63; + fly->ypos=0; + fly->zpos=80; + fly->speed=32; + fly->velocity=0; + fly->flags=FLY_NEHMOTNA | FLY_DESTROY; + fly->sector=sector; + fly->smer=dir; + fly->owner=cil; + fly->hit_bonus=0; + fly->damage=0; + fly->lives=glob_items[what].user_value; + fly->counter = 0; + add_fly(fly); + } + + +void zmen_vlastnost(int num,int cil,int what,int how) + { + if (!how) return; + if (cil<0) + { + cil=-cil-1; + if (mobs[cil].vlastnosti[what]+how<0) how=-mobs[cil].vlastnosti[what]; + vls_table[num][what]-=how; + mobs[cil].vlastnosti[what]+=how; + } + else if(cil>0) + { + THUMAN *p; + + vls_table[num][what]-=how; + cil--; + p=&postavy[cil]; + postavy[cil].stare_vls[what]+=how; + prepocitat_postavu(&postavy[cil]); + if (p->lives>p->vlastnosti[VLS_MAXHIT]) p->lives=p->vlastnosti[VLS_MAXHIT]; + //if (p->mana>p->vlastnosti[VLS_MAXMANA]) p->lives=p->vlastnosti[VLS_MAXMANA]; + if (p->kondice>p->vlastnosti[VLS_KONDIC]) p->lives=p->vlastnosti[VLS_KONDIC]; + } + } + +void zmen_vlastnost_percent(int num,int cil,int what,int how) + { + int x; + int c; + if (cil<0) + { + c=-cil-1; + x=mobs[c].vlastnosti[what]; + } + else + { + c=cil-1; + x=postavy[c].vlastnosti[what]; + } + x=x*abs(how)/100;if (how<0) x=-x; + zmen_vlastnost(num,cil,what,x); + } + +char hod_na_uspech(int cil,TKOUZLO *k) + { + if (!k->povaha) return 1; + if (cil) + { + int z,zv; + short *p; + + if (cil<0) + { + cil=-cil-1; + p=mobs[cil].vlastnosti+VLS_OHEN; + } + else if(cil>0) + { + cil--; + p=postavy[cil].vlastnosti+VLS_OHEN; + } + zv=mgochrana(p[k->pc]); + z=rnd(100); + return (z<=zv); + } + return 0; + } + +void spell_end_global() + { + long l=0; + int i; + for(i=0;isektor=q->sektor; + p->direction=q->direction; + p->groupnum=q->groupnum; + p->demon_save=q; + } + +static void zmena_z_demona(int hrac) + { + THUMAN *q=postavy+hrac; + THUMAN *p=q->demon_save; + + p->sektor=q->sektor; + p->direction=q->direction; + p->groupnum=q->groupnum; + *q=*p; + free(p); + } + +static void zmena_demona(int hrac,int demon,char smer) + { + THUMAN *p=postavy+hrac; + + if (postavy[hrac].stare_vls[VLS_KOUZLA] & SPL_DEMON && smer!=0) return; + if (~postavy[hrac].stare_vls[VLS_KOUZLA] & SPL_DEMON && smer==0) return; + if (smer!=0) zmena_na_demona(hrac,demon);else zmena_z_demona(hrac); + if (smer!=0) + { + p->lives=p->vlastnosti[VLS_MAXHIT]; + p->kondice=p->vlastnosti[VLS_KONDIC]; + p->mana=p->vlastnosti[VLS_MAXMANA]; + p->jidlo=MAX_HLAD(p); + p->voda=MAX_ZIZEN(p); + } + reg_grafiku_postav(); + } + +static void unaffect_after_demon(int cil) + { + int i; + char a; + TKOUZLO *spl; + + SEND_LOG("(SPELLS) Unaffecting after demon...",0,0); + do + { + a=0; + for(i=0;spl=spell_table[i],icil==cil && spl->backfire==1) + { + if (spl->wait) + { + spl->wait=0;call_spell(i); + a=1; + } + if (spl->cil>0) + { + spl->delay=0;call_spell(i); + a=1; + } + } + } + while(a); + } + +void spell_end(int num,int ccil,int owner) + { + int i,l; + int cil=ccil; + for(i=0;i0) + { + cil--; + if (_flag_map[num] & SPL_DEMON) + { + unaffect_after_demon(ccil); + zmena_demona(cil,owner,0); + _flag_map[num]&=~SPL_DEMON; + SEND_LOG("(SPELLS) Spell 'Demon' has ended...",0,0); + } + postavy[cil].stare_vls[VLS_KOUZLA]&=~_flag_map[num]; + if (cil>=0 && cilcil==ccil && ccil>0 && spell_table[i]->owner>=0) + { + postavy[cil].spell=1; + bott_draw(0); + break; + }; + l=_flag_map[num]; + _flag_map[num]=0; + if (l>0xffff) spell_end_global(); + SEND_LOG("(SPELLS) Spell ID %d ends.",num,0); + } + +static void spell_demon(int num,TKOUZLO *spl,int cil,int demon) + { + cil--; + if (postavy[cil].stare_vls[VLS_KOUZLA] & SPL_DEMON) return; + spl->owner=demon; + zmena_demona(cil,demon,1); + postavy[cil].stare_vls[VLS_KOUZLA]|=SPL_DEMON; + _flag_map[num]|=SPL_DEMON; + bott_draw(1); + } + +void spell_hit(int cil,int min,int max,int owner) + { + if (cil) + if (cil<0) + { + TMOB *m; + cil=-cil-1; + m=&mobs[cil]; + select_player=owner; + vybrana_zbran=-1; + mob_hit(m,min+rnd(max-min)); + } + else if(cil>0) + { + THUMAN *h; + int vysl; + + cil--; + h=&postavy[cil]; + vysl=min+rnd(max-min); + if (vysl<0) + { + h->lives-=vysl,h->lives=min(h->lives,h->vlastnosti[VLS_MAXHIT]); + if (h->groupnum==0) h->groupnum=cur_group; + } + else player_hit(h,vysl,1); + + bott_draw(0); + } + } + +void spell_hit_zivel(int cil,int min,int max,int owner,int zivel) + { + int ochrana; + if (cil) + if (cil<0) + { + TMOB *m; + cil=-cil-1; + m=&mobs[cil]; + select_player=owner; + ochrana=mgochrana(m->vlastnosti[VLS_OHEN+zivel]); + vybrana_zbran=-1; + mob_hit(m,(min+rnd(max-min))*ochrana/100); + } + else if(cil>0) + { + THUMAN *h; + + cil--; + h=&postavy[cil]; + ochrana=mgochrana(h->vlastnosti[VLS_OHEN+zivel]); + player_hit(h,(min+rnd(max-min))*ochrana/100,0); + bott_draw(0); + } + } + + +void set_flag(int num,int cil,int flag,int what) + { + if (cil>0) + { + cil--; + if (what) + { + postavy[cil].stare_vls[VLS_KOUZLA]|=flag; + _flag_map[num]|=flag; + } + else + { + postavy[cil].stare_vls[VLS_KOUZLA]&=~flag; + _flag_map[num]&=~flag; + } + zneplatnit_block(cil+H_CHARS); + prepocitat_postavu(postavy+cil); + } + if (cil<0) + { + cil=-cil-1; + if (what) + { + mobs[cil].vlastnosti[VLS_KOUZLA]|=flag; + _flag_map[num]|=flag; + } + else + { + mobs[cil].vlastnosti[VLS_KOUZLA]&=~flag; + _flag_map[num]&=~flag; + } + } + } + +void spell_automap(int kolik,int cil) + { + int x1,y1; + int xx,yy; + int i,layer; + THUMAN *p; + + if (cil<=0) return; + cil--; + p=&postavy[cil]; + x1=map_coord[p->sektor].x; + y1=map_coord[p->sektor].y; + layer=map_coord[p->sektor].layer; + for(i=1;isektor; + if (map_coord[from_sect].flags & MC_NOSUMMON) + { + char *s; + + s=(char *)alloca(strlen(texty[87])+30); + sprintf(s,texty[87],p->jmeno); + bott_disp_text(s); + return; + } + p->sektor=postavy[owner].sektor; + kolik--; + for(i=0;igroupnum && postavy[i].sektor==from_sect) + { + postavy[i].sektor=viewsector; + kolik--; + } + for(i=0;isektor=viewsector; + kolik--; + } + add_spectxtr(viewsector,H_TELEP_PCX,14,1,0); + auto_group(); + for(i=0;ijmeno); + bott_disp_text(s); + } + bott_draw(0); + build_player_map(); + } + +void spell_teleport(int cil,int owner, int teleport_target) + { + if (teleport_target==-1) + { + int sektor; + int dir; + int um; + + if (cil>0) {sektor=postavy[cil-1].sektor;dir=postavy[cil-1].direction;} + else if (cil<0) {sektor=mobs[-cil-1].sector;dir=mobs[-cil-1].dir;} + if (owner>=0) um=postavy[owner].vlastnosti[VLS_SMAGIE]; + teleport_target=calculatePhaseDoor(sektor,dir,um); + } + if (map_coord[teleport_target].flags & MC_NOSUMMON) + { + if (owner>=0) bott_disp_text(texty[88]); + return; + } + if (cil>0) + { + if (mob_map[teleport_target]) + { + if (owner>=0) bott_disp_text(texty[85]); + return; + } + destroy_player_map(); + cil--; + postavy_teleport_effect(teleport_target,postavy[cil].direction,1<=0) + zmen_skupinu(postavy+owner); + } + else if (cil<0) + { + if (map_coord[teleport_target].flags & MC_PLAYER) + { + if (owner>=0) bott_disp_text(texty[85]); + return; + } + cil=-cil-1; + play_sample_at_sector(H_SND_TELEPOUT,viewsector,mobs[cil].sector,0,0); + add_spectxtr(mobs[cil].sector,H_TELEP_PCX,14,1,0); + mobs[cil].sector=teleport_target; + play_sample_at_sector(H_SND_TELEPOUT,viewsector,teleport_target,0,0); + add_spectxtr(teleport_target,H_TELEP_PCX,14,1,0); + mobs[cil].next=0; + refresh_mob_map(); + } + //schovej_mysku(); + } + +void spell_teleport_sector(int cil,int owner) +{ + if (cil<0) + { + if (owner>=0) bott_disp_text(texty[85]); + return; + } + if (cil>0) + { + cil--; + if (TelepLocation.map) + { + destroy_player_map(); + if (stricmp(TelepLocation.map,level_fname)!=0) + { + int sector=postavy[cil].sektor; + int i; + + if (cil!=owner) return; + postavy_teleport_effect(0,0,0,1); + strncpy(loadlevel.name,TelepLocation.map,12); + loadlevel.name[12]=0; + loadlevel.start_pos=TelepLocation.sector; + loadlevel.dir=TelepLocation.dir; + send_message(E_CLOSE_MAP); + save_map=1; + + for(i=0;i=0) + zmen_skupinu(postavy+owner); + } + } + else + { + int sector=postavy[cil].sektor; + int dir=postavy[cil].direction; + int x=map_coord[sector].x; + int y=map_coord[sector].y; + int stpx=0,stpy=0,diffx=0,diffy=0; + switch (dir) + { + case 0: stpy=-1;diffx=1;break; + case 1: stpx=1;diffy=1;break; + case 2: stpy=1;diffx=-1;break; + case 3: stpx=-1;diffy=-1;break; + }; + { + int newx=x+TelepLocation.loc_x*stpx+TelepLocation.loc_y*diffx; + int newy=y+TelepLocation.loc_x*stpx+TelepLocation.loc_y*diffy; + int i; + int dist; + int nearest=0; + int nearestdst=0x7FFFFFFF; + + for (i=1;i=0) bott_disp_text(texty[88]); + return; + } + destroy_player_map(); + postavy_teleport_effect(sector,postavy[cil].direction,1<=0) + zmen_skupinu(postavy+owner); + } + } + +} + +static void spell_summon(int cil) + { + short sector,i,rn,rno,slc; + char stdir,p; + + if (cil>0) sector=postavy[cil-1].sektor; + if (cil<0) sector=mobs[-cil-1].sector; + for(i=0;ivlajky & MOB_LIVE && ~m->vlajky & MOB_RELOAD) break; + } + if (i==MAX_MOBS) return; + slc=i; + rno=rn=rnd(256)+1; + do + { + for(i=0;istay_strategy & (MOB_WATCH|MOB_WALK)) == (MOB_WATCH|MOB_WALK) && + (m->vlajky & MOB_LIVE) && (~m->vlajky & MOB_PASSABLE) && (~m->vlajky & MOB_MOBILE)) + { + rn--;if (!rn) break; + } + } + } + while (i==MAX_MOBS && rn!=rno); + if (i==MAX_MOBS) return; + memcpy(mobs+slc,mobs+i,sizeof(TMOB)); + p=map_coord[sector].flags & MC_PLAYER; + if (!p) + { + int m; + m=mob_map[sector]-1; + p=mobs[m].stay_strategy & MOB_BIG || mobs[m].next; + } + if (p) + { + int i; + stdir=rnd(4); + + for(i=0;i<4;i++,stdir=stdir+1&3) + if (!mob_check_next_sector(sector,stdir,mobs[slc].stay_strategy,0)) break; + if (i==4) + { + mobs[slc].vlajky&=~MOB_LIVE; + return; + } + sector=map_sectors[sector].step_next[stdir]; + } + mobs[slc].sector=sector; + if (cil>0) mobs[slc].dir=postavy[cil-1].direction+2&3; + if (cil<0) mobs[slc].dir=mobs[-cil-1].dir; + refresh_mob_map(); + } + +static void spell_manabat(int cil) + { + if (cil>0) + { + cil--; + if (postavy[cil].mana_battery>postavy[cil].mana) postavy[cil].mana_battery=postavy[cil].mana; + else postavy[cil].mana=postavy[cil].mana_battery; + } + } + +static void spell_vahy_osudu(int zivel,char povaha) + { + int i; + int min; + THUMAN *h; + TMOB *m; + + min=32767; + for(i=0,h=postavy;iused && h->lives && min>h->lives) min=h->lives; + for(i=0,m=mobs;ivlajky & MOB_LIVE && m->vlajky & MOB_IN_BATTLE && m->liveslives; + for(i=0,h=postavy;iused && h->lives) + { + int obr=mgochrana(h->vlastnosti[VLS_OHEN+zivel]); + if (!povaha || rnd(100)<=obr) + { + h->lives=min; + display_spell_in_icone(H_SPELLDEF,1<vlajky & MOB_LIVE && m->vlajky & MOB_IN_BATTLE && m->livesvlastnosti[VLS_OHEN+zivel]); + if (!povaha || rnd(100)<=obr) + m->lives=min; + } + bott_draw(1); + } + +static void spell_open_teleport(int cil, int owner) +{ + int sector; + int dir; + if (cil<0) {sector=mobs[-cil-1].sector;dir=mobs[-cil-1].dir;} + else if (cil>0) {sector=postavy[cil-1].sektor;dir=postavy[cil-1].direction;} + else return; + + if (map_sectors[sector].step_next[dir] && (~map_sides[sector*4+dir].flags & SD_THING_IMPS)) + sector=map_sectors[sector].step_next[dir]; + + if (map_coord[sector].flags & MC_NOSUMMON) + { + if (owner>=0) bott_disp_text(texty[88]); + return; + } + + if (mob_map[sector]) + { + if (owner>=0) bott_disp_text(texty[85]); + return; + } + + + if (map_sectors[sector].sector_type>=S_USERTELEPORT && + map_sectors[sector].sector_type<=S_USERTELEPORT_END) + { + int i; + int otherside; + map_sectors[sector].sector_type-=S_USERTELEPORT ; + otherside=map_sectors[sector].sector_tag; + for (i=0;i<4;i++) {map_sides[sector*4+i].flags&=~SD_SEC_VIS;map_sides[sector*4+i].sec_anim=0;map_sides[sector*4+i].sec=0;} + map_sectors[sector].sector_tag=0; + add_spectxtr(sector,H_TELEP_PCX,14,1,0); + play_sample_at_sector(H_SND_TELEPOUT,viewsector,sector,0,0); + if (otherside!=sector && otherside) + { + map_sectors[otherside].sector_type-=S_USERTELEPORT ; + for (i=0;i<4;i++) {map_sides[otherside*4+i].flags&=~SD_SEC_VIS;map_sides[otherside*4+i].sec_anim=0;map_sides[otherside*4+i].sec=0;} + map_sectors[otherside].sector_tag=0; + add_spectxtr(otherside,H_TELEP_PCX,14,1,0); + play_sample_at_sector(H_SND_TELEPOUT,viewsector,otherside,0,0); + } + } + else + { + int type=map_sectors[sector].sector_type; + int i; + char allowed=1; + if (type!=S_NORMAL && (type=S_VODA)) allowed=0; + if (allowed && map_sectors[sector].sector_tag!=0) allowed=0; + if (allowed) + for (i=0;i<4;i++) + if (map_sides[sector*4+i].sec) allowed=0; + if (allowed) + { + TSTENA *st,*stt; + int templateSect=0; + int i,j; + for (i=0;templateSect==0 && i=0) bott_disp_text(texty[85]); + return; + } + map_sectors[sector].sector_type+=S_USERTELEPORT; + st=map_sides+4*sector; + stt=map_sides+4*templateSect; + for (i=0;i<4;i++) + { + st->flags|=SD_SEC_VIS|SD_SEC_ANIM; + st->sec_anim=stt->sec_anim; + st->sec=stt->sec; + st++; + } + for (i=0;i=S_USERTELEPORT && map_sectors[i].sector_type<=S_USERTELEPORT_END) + if (map_sectors[i].sector_tag==i) break; + if (i!=mapsize) + { + map_sectors[sector].sector_tag=i; + map_sectors[sector].side_tag=map_sectors[i].side_tag; + map_sectors[i].sector_tag=sector; + map_sectors[i].side_tag=(dir+2)&3; + } + else + { + map_sectors[sector].sector_tag=sector; + map_sectors[sector].side_tag=(dir+2)&3; + } + add_spectxtr(sector,H_TELEP_PCX,14,1,0); + play_sample_at_sector(H_SND_TELEPOUT,viewsector,sector,0,0); + } + else + if (owner>=0) bott_disp_text(texty[85]); + } +} + +static void spell_rychlost(int num,int cil) + { + short *c; + if (cil>0) c=postavy[cil-1].vlastnosti; + else c=mobs[-cil-1].vlastnosti; + if (c[VLS_POHYB]<15) zmen_vlastnost(num,cil,VLS_POHYB,15-c[VLS_POHYB]); + } + +void spell_special(int num,TKOUZLO *spl,int spc) + { + switch (spc) + { + case SP_AUTOMAP4:spell_automap(4,spl->cil);break; + case SP_AUTOMAP8:spell_automap(8,spl->cil);break; + case SP_AUTOMAP15:spell_automap(15,spl->cil);break; + case SP_PRIPOJENI1:spell_pripojeni(1,spl->cil,spl->owner);break; + case SP_PRIPOJENI3:spell_pripojeni(3,spl->cil,spl->owner);break; + case SP_PRIPOJENIA:spell_pripojenia(spl->owner);break; + case SP_CHVENI:chveni(100);break; + case SP_DEFAULT_EFFEKT: + if (spl->cil>0)display_spell_in_icone(H_SPELLDEF,1<<(spl->cil-1));break; + case SP_TRUE_SEEING: true_seeing=1;_flag_map[num]|=FLG_TRUESEEING;break; + case SP_SCORE:show_lives=1;_flag_map[num]|=FLG_SCORE;break; + case SP_HALUCINACE:set_halucination=1;_flag_map[num]|=FLG_HALUCINACE; + hal_sector=rnd(mapsize-1)+1;hal_dir=rnd(4); + break; + case SP_TELEPORT:if (hod_na_uspech(spl->cil,spl)) spell_teleport(spl->cil,spl->owner,spl->teleport_target);break; + case SP_PHASEDOOR:if (hod_na_uspech(spl->cil,spl)) spell_teleport(spl->cil,spl->owner,-1);break; + case SP_SUMMON: spell_summon(spl->cil); + case SP_HLUBINA1:if (hlubina_level==0) hlubina_level=1;_flag_map[num]|=FLG_HLUBINA1; + break; + case SP_HLUBINA2:hlubina_level=2;_flag_map[num]|=FLG_HLUBINA2; + break; + case SP_MANABAT:spell_manabat(spl->cil); + break; + case SP_VAHY:spell_vahy_osudu(spl->pc,spl->povaha);break; + case SP_RYCHLOST:spell_rychlost(num,spl->cil);break; + case SP_DEMON1:spell_demon(num,spl,spl->cil,0);break; + case SP_DEMON2:spell_demon(num,spl,spl->cil,1);break; + case SP_DEMON3:spell_demon(num,spl,spl->cil,2);break; + case SP_VZPLANUTI1:spell_vzplanuti(spl->cil,1,rand_value,1,spl->pc);break; + case SP_VZPLANUTI2:spell_vzplanuti(spl->cil,5,rand_value,1,spl->pc);break; + case SP_VZPLANUTI3:spell_vzplanuti(spl->cil,5,rand_value,0,spl->pc);break; + case SP_TELEPORT_SECT: if (hod_na_uspech(spl->cil,spl)) spell_teleport_sector(spl->cil,spl->owner);break; + case SP_OPEN_TELEPORT: spell_open_teleport(spl->cil,spl->owner);break; + } + } + +void spell_drain(TKOUZLO *p,int cil,int min,int max) + { + int drw; + int sect,dir; + + drw=min+rnd(max-min); + if (cil>0) + { + cil--; + sect=postavy[cil].sektor; + dir=postavy[cil].direction; + if (map_sides[(sect<<2)+dir].flags & SD_PLAY_IMPS) + { + postavy[cil].lives-=drw; + player_check_death(&postavy[cil],0); + } + else + { + int chaos;int potvora,ochrana; + TMOB *m; + + potvora=vyber_potvoru(sect,dir,&chaos); + if (potvora==-1) return; + m=mobs+potvora; + ochrana=mgochrana(m->vlastnosti[VLS_OHEN+p->pc]); + drw=ochrana*drw/100; + vybrana_zbran=-1; + mob_hit(m,drw); + battle=1; + postavy[cil].lives+=drw/4; + if (postavy[cil].lives>postavy[cil].vlastnosti[VLS_MAXHIT]) + postavy[cil].lives=postavy[cil].vlastnosti[VLS_MAXHIT]; + } + } + } + +static void set_kondice_mana(int kolik,TKOUZLO *p,int what,char clip) + { + int cil=p->cil; + if (cil>0) + { + THUMAN *p; + cil--; + p=postavy+cil; + if (what==S_kondice) + { + p->kondice+=kolik; + if (p->kondice<0) p->kondice=0; + if (clip) + if (p->kondice>p->vlastnosti[VLS_KONDIC]) p->kondice=p->vlastnosti[VLS_KONDIC]; + } + if (what==S_mana) + { + p->mana+=kolik; + if (p->mana<0) p->mana=0; + if (clip) + if (p->mana>p->vlastnosti[VLS_MAXMANA]) p->mana=p->vlastnosti[VLS_MAXMANA]; + } + } + } + +static void spell_mana_steal(int kolik,int cil,int owner) + { + if (cil>0) + { + THUMAN *h=postavy+cil-1; + h->mana-=h->vlastnosti[VLS_MAXMANA]*kolik/100; + if (h->mana<0) h->mana=0; + } + if (cil<0) + { + if (owner>=0) + { + THUMAN *h=postavy+owner; + if (h->manavlastnosti[VLS_MAXMANA]) h->mana+=h->vlastnosti[VLS_MAXMANA]*kolik/100; + } + } + } + +static void calc_rand_value(int val1,int val2) + { + rand_value=val1+rnd(val2-val1+1); + } + +void call_spell(int i) + { + TKOUZLO *p; + char *c; + int z; + char ext=0; + int cil; + + SEND_LOG("(SPELLS) Calculating spell ID: %d",i,0); + p=spell_table[i]; + if (p==NULL) return; + cil=p->cil; + if (cil>0) + { + cil--; + if (postavy[cil].stare_vls[VLS_KOUZLA] & SPL_DEMON && ~_flag_map[i] & SPL_DEMON && p->backfire==0) + { + p->wait=1; + return; + } + } + if (p->delay) return; + if (p->wait) return; + c=(char *)ablock(H_KOUZLA); + c+=p->start; + twins=0; + do + switch (twins=twins==3?0:twins,*c++) + { + case S_zivel:p->pc=GET_WORD(c); + if (p->owner>=0 && !GlobEvent(MAGLOB_ONFIREMAGIC+p->pc,postavy[p->owner].sektor,postavy[p->owner].direction)) + { + spell_end(i,p->cil,p->owner); + return; + } + break; + case S_hpnorm_min:parm1=GET_WORD(c);twins|=1;if (twins==3) spell_hit(p->cil,parm1,parm2,p->owner);break; + case S_hpnorm_max:parm2=GET_WORD(c);twins|=2;if (twins==3) spell_hit(p->cil,parm1,parm2,p->owner);break; + case S_hpzivl_min:parm1=GET_WORD(c);twins|=1;if (twins==3) spell_hit_zivel(p->cil,parm1,parm2,p->owner,p->pc);break; + case S_hpzivl_max:parm2=GET_WORD(c);twins|=2;if (twins==3) spell_hit_zivel(p->cil,parm1,parm2,p->owner,p->pc);break; + case S_vlastnost:parm1=GET_WORD(c);twins|=1; + if (twins==3) if (hod_na_uspech(p->cil,p)) zmen_vlastnost(i,p->cil,parm1,parm2);break; + case S_vls_kolik:parm2=GET_WORD(c);twins|=2; + if (twins==3) if (hod_na_uspech(p->cil,p)) zmen_vlastnost(i,p->cil,parm1,parm2);break; + case S_trvani:p->delay=GET_WORD(c);p->wait=0;ext=1;break; + case S_throw_item:z=GET_WORD(c);spell_throw(p->cil,z);break; + case S_create_item:z=GET_WORD(c);spell_create(p->cil,z);break; + case S_create_weapon:z=GET_WORD(c);spell_create_weapon(p->cil,z);break; + case S_animace:if (p->owner>=0 && !p->traceon)spell_anim(c);c=strchr(c,0);c++;break; + case S_zvuk:if (p->owner>=0 && !p->traceon)spell_sound(c);c=strchr(c,0);c++;break; + case S_wait:p->wait=GET_WORD(c);if (p->owner>=0) ext=1;break; + case 0xff:spell_end(i,p->cil,p->owner);return; + case S_pvls:parm2=GET_WORD(c);twins|=2; + if (twins==3) if (hod_na_uspech(p->cil,p)) zmen_vlastnost_percent(i,p->cil,parm1,parm2);break; + case S_set:parm2=GET_WORD(c);if (hod_na_uspech(p->cil,p)) set_flag(i,p->cil,parm2,1);break; + case S_reset:parm2=GET_WORD(c);if (hod_na_uspech(p->cil,p)) set_flag(i,p->cil,parm2,0);break; + case S_special:parm2=GET_WORD(c);spell_special(i,p,parm2);break; + case S_drain_min:parm1=GET_WORD(c);twins|=1;if (twins==3) spell_drain(p,p->cil,parm1,parm2);break; + case S_drain_max:parm2=GET_WORD(c);twins|=2;if (twins==3) spell_drain(p,p->cil,parm1,parm2);break; + case S_rand_min:parm1=GET_WORD(c);twins|=1;if (twins==3) calc_rand_value(parm1,parm2);break; + case S_rand_max:parm2=GET_WORD(c);twins|=2;if (twins==3) calc_rand_value(parm1,parm2);break; + case S_mana:parm1=GET_WORD(c);set_kondice_mana(parm1,p,S_mana,0);break; + case S_kondice:parm1=GET_WORD(c);set_kondice_mana(parm1,p,S_kondice,1);break; + case S_mana_clip:parm1=GET_WORD(c);set_kondice_mana(parm1,p,S_mana,1);break; + case S_mana_steal:parm1=GET_WORD(c);spell_mana_steal(parm1,p->cil,p->owner);break; + case S_location_sector: parm1=GET_WORD(c); + TelepLocation.sector=parm1; + TelepLocation.loc_x=0; + TelepLocation.loc_y=0; + break; + case S_location_map: TelepLocation.map=c;c=strchr(c,0);c++;break; + case S_location_dir: parm1=GET_WORD(c);TelepLocation.dir=parm1;break; + case S_location_x: TelepLocation.loc_x=GET_WORD(c);TelepLocation.map=0;break; + case S_location_y: TelepLocation.loc_y=GET_WORD(c);TelepLocation.map=0;break; + default: + { + char *d="Chyba v popisu kouzel: Program narazil na neznamou instrukci %d (%02X) pri zpracovani kouzla s cislem %d. Kouzlo bylo ukoneno"; + c=alloca(strlen(d)+20); + sprintf(c,d,*(c-1),*(c-1),p->num); + bott_disp_text(c); + spell_end(i,p->cil,p->owner); + return; + } + + + } + while(!ext); + p->start=c-(char *)ablock(H_KOUZLA); + } + +int add_spell(int num,int cil,int owner,char noanim) + { + int i,nl=-1; + TKOUZLO *p; + TKOUZLO *q; + int accnum; + char time_acc=1; + + SEND_LOG("(SPELLS) Casting spell number %d",num,0); + alock(H_KOUZLA); + q=(TKOUZLO *)ablock(H_KOUZLA)+num; + accnum=q->accnum; + if (accnum<0) + { + time_acc=0; + accnum=abs(accnum); + } + if (!accnum) accnum=-1; + for(i=0;iaccnum)!=accnum || spell_table[i]->cil!=cil);i++) + if (spell_table[i]==NULL) nl=i; + if (i==MAX_SPELLS) i=nl; + if (i==-1) + { + SEND_LOG("(ERROR) Too many spells in game!",0,0); + return -1; + } + if (spell_table[i]!=NULL) + { + if (!time_acc) return -1; + spell_end(i,spell_table[i]->cil,spell_table[i]->owner); + } + SEND_LOG("(SPELLS) Current spell number %d was assigned to ID number : %d",num,i); + p=New(TKOUZLO); + vls_table[i]=NewArr(short,24); + memset(vls_table[i],0,2*24); + memcpy(p,q,sizeof(TKOUZLO)); + p->cil=cil; + p->num=num; + p->owner=owner; + p->traceon=noanim; + p->teleport_target=teleport_target; + if (cil>0) p->backfire=(postavy[cil-1].stare_vls[VLS_KOUZLA] & SPL_DEMON)!=0; + aunlock(H_KOUZLA); + spell_table[i]=p; + if (cil>0 && owner>=0) postavy[cil-1].spell=1; + call_spell(i); + return i; + } + +void kouzla_kola(EVENT_MSG *msg,void **unused) + { + unused; + if (msg->msg==E_KOUZLO_KOLO) + { + int i; + + for(i=0;idelay) + { + neco_v_pohybu=1; + if (!(--spell_table[i]->delay)) call_spell(i); + } + } + } + +void kouzla_anm(EVENT_MSG *msg,void **unused) + { + unused; + if (msg->msg==E_KOUZLO_ANM) + { + int i; + + for(i=0;iwait) + { + neco_v_pohybu=1; + if (!(--spell_table[i]->wait)) call_spell(i); + } + } + } + + +char add_group_spell(int num,int sector,int owner,int mode,char noanim) + { + char c=1; + if (mob_map[sector]) + { + int m; + m=mob_map[sector]; + add_spell(num,-m,owner,noanim); + c=0; + if (mobs[m-1].next) add_spell(num,-mobs[m-1].next,owner,noanim); + } + if (map_coord[sector].flags & MC_PLAYER) + { + int i,j; + if (mode==C_nahodna_postava) + { + i=0;j=rnd(POCET_POSTAV)+1; + do + { + if (i>=POCET_POSTAV) i=0; + if (postavy[i].sektor==sector) j--; + if (j) i++; + } + while (j); + add_spell(num,i+1,owner,noanim); + } + else + { + for(i=0;icil==C_kouzelnik) return 1; + if (k->cil==C_postava) return 2; + if (k->cil==C_mrtva_postava) return 3; + if (k->cil==C_postava_jinde) return 4; + return 0; + } + +static word last_sector; + +static char get_valid_sector(word sector) + { + + last_sector=sector; + return 1; + } + + +void cast(int num,THUMAN *p,int owner, char backfire) + { + int i,um,cil,num2; + TKOUZLO *k; + + if (num>511) + { + cil=num>>9; + num2=num & 511; + } + else + { + cil=0; + num2=num; + } + + + SEND_LOG("(SPELLS) Cast num %d cil %d",num2,cil); + k=((TKOUZLO *)ablock(H_KOUZLA))+num2; + SEND_LOG("(SPELLS) Cast spell name %s",k->spellname,0); + + if (cil>0 && k->cil!=C_postava_jinde) + { + THUMAN *h1=postavy+cil-1; + char s[256]; + if ((abs(map_coord[h1->sektor].x-map_coord[p->sektor].x)>5) || + (abs(map_coord[h1->sektor].y-map_coord[p->sektor].y)>5) ) + { + sprintf(s,texty[37+(h1->female==1)],h1->jmeno,p->jmeno); + bott_disp_text(s); + return; + } + } + if (battle && k->traceon & 1 && trace_path(p->sektor,p->direction)==-255) return; + if (!backfire && p->manamge) return; + if (p->vlastnosti[VLS_KOUZLA] & SPL_INVIS) + { + p->stare_vls[VLS_KOUZLA]&=~SPL_INVIS; + prepocitat_postavu(p); + build_all_players(); + } + if (!backfire && (um=p->vlastnosti[VLS_SMAGIE])um) + { + int per1,per2; + if (um*2um) return; + per1=(um-k->um/2)*128/k->um; + per2=rnd(64); + if ((per1/2+32)backfire || (game_extras & EX_RANDOM_BACKFIRES)!=0)) + { + p->mana-=k->mge; + if ((game_extras & EX_RANDOM_BACKFIRES)!=0) + { + labyrinth_find_path(p->sektor,65535,SD_PLAY_IMPS,get_valid_sector,NULL); + teleport_target=last_sector; + cast(rand()*105/RAND_MAX+(cil*512),p,p-postavy,1); + return; + } + cast(k->backfire+(cil<<9),p,owner,1); + return; + } + if(per1mana-=k->mge/2; + return; + } + per1=(64-per1)/2; + per2=rnd(64); + if(per1>per2) p->stare_vls[VLS_SMAGIE]++; + } + + if (!GlobEvent(MAGLOB_BEFOREMAGIC,p->sektor,p->direction)) return; + if (!GlobEvents(MAGLOB_ONSPELLID1,MAGLOB_ONSPELLID9,p->sektor,p->direction,num2)) return; + + if (cil && (k->cil==C_postava || k->cil==C_mrtva_postava || k->cil==C_postava_jinde)) i=add_spell(num2,cil,owner,0); + else + { + if (k->cil==C_policko) if (add_group_spell(num2,p->sektor,owner,C_policko,0)) goto end; + if (k->cil==C_kouzelnik) add_spell(num2,p-postavy+1,owner,0); + if (k->cil==C_policko_pred || k->cil==C_nahodna_postava) + { + int s; + s=p->sektor; + if (!(map_sides[(s<<2)+p->direction].flags & SD_PLAY_IMPS) && !backfire) + s=map_sectors[s].step_next[p->direction]; + if (add_group_spell(num2,s,owner,k->cil,0)) goto end; + } + } + if (!backfire) p->mana-=k->mge; + p->exp+=k->mge; + check_player_new_level(p); + if (p->mana>p->mana_battery) + { + if (p->mana_battery>=0)p->mana=p->mana_battery; + else SEND_LOG("(ERROR) Mana battery error on character %d",p-postavy,0); + p->mana_battery=32767; + } +end: + GlobEvent(MAGLOB_AFTERMAGIC,p->sektor,p->direction); + } + +void mob_cast(int num,TMOB *m,int mob_num) + { + TKOUZLO *k; + + SEND_LOG("(SPELLS) Enemy tries to cast the spell (mob: %d, spell: %d",mob_num,num); + k=((TKOUZLO *)ablock(H_KOUZLA))+num; + switch (k->cil) + { + case C_postava: + case C_kouzelnik:add_spell(num,-(mob_num+1),-1,1);break; + case C_policko:add_group_spell(num,m->sector,-1,C_policko,1);break; + case C_policko_pred: + case C_nahodna_postava: + { + int s; + s=m->sector; + if (!(map_sides[(s<<2)+m->dir].flags & SD_PLAY_IMPS)) + s=map_sectors[s].step_next[m->dir]; + add_group_spell(num,s,-1,k->cil,1); + } + break; + } + } + +static int calculatePhaseDoor(int sector, int dir, int um) +{ + int x=map_coord[sector].x; + int y=map_coord[sector].y; + int stpx=0,stpy=0,diffx=0,diffy=0; + switch (dir) + { + case 0: stpy=-1;diffx=1;break; + case 1: stpx=1;diffy=1;break; + case 2: stpy=1;diffx=1;break; + case 3: stpx=-1;diffy=1;break; + }; + { + int dist=1+rand()*(um/4)/RAND_MAX; + int difs=rand()*2*dist/RAND_MAX-dist; + int newx=x+dist*stpx+difs*diffx; + int newy=y+dist*stpy+difs*diffy; + int i; + int nearest=0; + int nearestdst=0x7FFFFFFF; + + for (i=1;isektor,h->direction,h->vlastnosti[VLS_SMAGIE]); + } + switch (k->cil) + { + case C_nahodna_postava: + case C_postava: + case C_kouzelnik:if (postavy[postava].lives) add_spell(num,postava+1,postava,noanim);break; + case C_mrtva_postava:if (!postavy[postava].lives) add_spell(num,postava+1,postava,noanim);break; + case C_policko:add_group_spell(num,sector,postava,k->cil,noanim);break; + case C_policko_pred: + { + int s; + s=sector; + if (~map_sides[(s<<2)+h->direction].flags & SD_PLAY_IMPS) + s=map_sectors[s].step_next[h->direction]; + add_group_spell(num,s,postava,k->cil,noanim); + } + break; + case C_jiny_cil:if (victim!=NULL) add_spell(num,-(victim-mobs+1),postava,noanim);break; + } + } + +void area_cast(int num,int sector,int owner,char noanim) + { + SEND_LOG("(SPELLS) Area casts the spell (sector: %d, spell: %d)",sector,num); + add_group_spell(num,sector,owner,C_policko,noanim); + } + + + +void kouzla_init() + { + SEND_LOG("(SPELLS) Init...",0,0); + send_message(E_ADD,E_KOUZLO_ANM,kouzla_anm); + send_message(E_ADD,E_KOUZLO_KOLO,kouzla_kola); + memset(spell_table,0,sizeof(spell_table)); + memset(vls_table,0,sizeof(vls_table)); + memset(_flag_map,0,sizeof(_flag_map)); + true_seeing=0; + hlubina_level=0; + show_lives=0; + set_halucination=0; + } + +void reinit_kouzla_full() + { + int i; + + SEND_LOG("(SPELLS) Reinit...",0,0); + for(i=0;iwait) + { + spell_table[i]->wait=0;call_spell(i); + a=1; + } + if (spell_table[i]->cil<0) + { + spell_table[i]->delay=0;call_spell(i); + a=1; + } + } + + } + while(a); + } + + +int save_spells(FILE *f) + { + char res=0; + + int i,s; + + SEND_LOG("(SPELLS) Saving spell table...",0,0); + for(i=0,s=0;iwait) + { + spell_table[i]->wait=0;call_spell(i); + a=1; + } + if (spell_table[i]->cil>0) + { + spell_table[i]->delay=0;call_spell(i); + a=1; + } + } + + } + while(a); + SEND_LOG("(WIZARD) Unaffect... done",0,0); + } + +void unaffect_demon(int cil) + { + int i; + TKOUZLO *spl; + char a; + + + cil++; + SEND_LOG("(SPELLS) Demon returns to astral spaces...",0,0); + for(i=0;spl=spell_table[i],icil==cil) + { + while (spell_table[i]!=NULL) + { + if (spell_table[i]->wait) + { + spell_table[i]->wait=0;call_spell(i); + a=1; + } + if (spell_table[i]->cil>0) + { + spell_table[i]->delay=0;call_spell(i); + a=1; + } + } + } + } + + diff --git a/GAME/MACROS.C b/GAME/MACROS.C new file mode 100644 index 0000000..f313144 --- /dev/null +++ b/GAME/MACROS.C @@ -0,0 +1,794 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "engine1.h" +#include +#include "globals.h" +#include "specproc.h" + +int **macros=NULL; +void *macro_block; +int macro_block_size; +long sound_side_flags=0; //kopie flagu steny pro zvuk +static char codelock_memory[16][8]; +static short rand_value; +static int program_counter=0; +static char trig_group; + +SGlobalEventDef GlobEventList[MAGLOB_NEXTID]; + +void propadnout(int sector); + +#define TRIG_GROUP 1 +#define TRIG_SECTOR 2 + +char get_player_triggered(int p) + { + return (trig_group & (1<=0) trig_group=(char)load; + return trig_group; + } + +void load_macros(int size,void *data) + { + int *r; + + if (macros!=NULL) free(macros); + macros=(int **)getmem(mapsize*sizeof(int *)*4); + memset(macros,0,mapsize*sizeof(char *)*4); + memset(codelock_memory,0,sizeof(codelock_memory)); + r=data; + while (*r) + { + macros[*r]=r+1; + r++; + while(*r) r=(int *)((char *)r+*r+4); + r++; + } + macro_block=data; + macro_block_size=size; + } + +void macro_disp_text(int text,char glob) + { + if (glob) bott_disp_text(texty[text]); + else bott_disp_text(level_texts[text]); + } + +void macro_fireball(TMA_FIREBALL *z,int sector,int dir) + { + LETICI_VEC *fly; + TITEM *it; + + fly=create_fly(); + it=glob_items+z->item-1; + fly->items=NULL; + fly->item=z->item; + fly->xpos=z->xpos; + fly->ypos=z->ypos*128/500-64; + fly->zpos=z->zpos*128/320; + fly->speed=z->speed; + fly->velocity=0; + fly->flags=FLY_IN_FLY | (!it->hmotnost?FLY_NEHMOTNA:0) | (it->flags & ITF_DESTROY?FLY_DESTROY:0)|FLY_NEDULEZITA; + fly->sector=sector; + fly->smer=(dir+2)&3; + fly->owner=0; + fly->hit_bonus=0; + fly->damage=0; + fly->counter=0; + if (fly->flags & FLY_DESTROY)fly->lives=it->user_value; + add_fly(fly); + } + +void macro_sound(TMA_SOUND *p,int psect,int pdir,int sect,int dir) + { + char up=4; + if (sound_side_flags & SD_PRIM_FORV) up=2; + if (~(p->bit16) & up) + if (psect) + play_effekt(map_coord[sect].x,map_coord[sect].y,map_coord[psect].x,map_coord[psect].y,dir,pdir,p); + else + play_effekt(0,0,0,0,-1,-1,p); + } + +void macro_send_act(TMA_SEND_ACTION *p) + { + delay_action(p->s_action,p->sector,p->side,p->change_bits<<24,0,p->delay); + } + +void macro_load_another_map(TMA_LOADLEV *z) + { + int i,j=0; + + if (battle) return; + group_all(); + for(i=0;istart_pos; + } + +void macro_drop_item(int sector,int smer,short item) + { + short itms[2]; + itms[0]=item+1; + itms[1]=0; + push_item(sector,(smer+rnd(2))&0x3,itms); + } + +static void macro_create_item(short item) + { + if (picked_item!=NULL) poloz_vsechny_predmety(); + picked_item=NewArr(short,2); + picked_item[0]=item+1; + picked_item[1]=0; + pick_set_cursor(); + } + + +static char decode_lock(char znak,char *string,char codenum) + { + char *memory; + char *endm; + char *ends; + int i; + + memory=codelock_memory[codenum]; + memmove(memory,memory+1,7); + endm=memory+7; + *endm=znak; + if (!*string) return 1; + ends=string; + for(i=0;i<8;i++,ends++) if (!*ends) break; + ends--; + while (ends>=string) + { + if (*ends!=*endm) break; + ends--;endm--; + } + if (endssector==sector && d->side==dir) + { + if (p==NULL) d_action=d->next;else p->next=d->next; + free(d); + return; + } + p=d; + d=d->next; + } + } + +char if_lock(int side,int key_id,int level,TMA_LOCK *lk) + { + int c; + + level; + if (picked_item==NULL) + { + call_macro(side,MC_LOCKINFO); + return 1; + } + c=picked_item[0]-1; + c=glob_items[c].keynum; + if (c==-1 && level!=-1) + { + int i,j=0,min=-1; + THUMAN *h=postavy; + int thlev; + char s[100]; + + for(i=0;iused && h->groupnum==cur_group && h->vlastnosti[VLS_OBRAT]>min) + {min=h->vlastnosti[VLS_OBRAT];j=i;}; + h=postavy+j; + if (level==0) level=100; + if (level>=min) + if (rnd(100)<=level-min) + { + sprintf(s,texty[158+h->female],h->jmeno); + bott_disp_text(s); + destroy_items(picked_item); + free(picked_item); + picked_item=NULL;pick_set_cursor(); + return 1; + } + thlev=rnd(min); + if (thlev>level) + { + sprintf(s,texty[154+h->female],h->jmeno); + bott_disp_text(s); + //if (abs(level-thlev)<10 && h->vlastnosti[VLS_THIEF]<100) + // { + //h->vlastnosti[VLS_THIEF]++; + //h->stare_vls[VLS_THIEF]++; + //} + lk->thieflevel=1; + return 0; + } + sprintf(s,texty[156+h->female],h->jmeno); + bott_disp_text(s); + return 1; + } + if (c!=key_id || !c) + { + call_macro(side,MC_TOUCHFAIL); + return 1; + } + return 0; + } + +void xchg_block(void *b1,void *b2,int leng) +//#pragma aux xchg_block parm[edi][esi][ecx]= +{ +__asm + { + mov edi,b1 + mov esi,b2 + mov ecx,leng + lp1: mov al,[edi] + mov ah,[esi] + mov [edi],ah + mov [esi],al + inc edi + inc esi + dec ecx + jnz lp1 + } +} + +static void propadnout(int sector) + { + short *i,c,m1,m2; + + for(c=0;c<4;c++) + { + pop_item(sector,c,0,&i); + while(i!=NULL) + { + push_item(sector,c,i); + pop_item(sector,c,0,&i); + } + } + if (mob_map[sector]) + { + m1=mob_map[sector]-1; + m2=mobs[m1].next-1; + mob_map[sector]=0; + if (map_sectors[sector].sector_type==S_DIRA) + { + mobs[m1].sector=map_sectors[sector].sector_tag; + if (m2>=0) mobs[m2].sector=mobs[m1].sector; + } + mob_map[mobs[m1].sector]=m1+1; + } + postavy_propadnout(sector); + } + +static void swap_sectors(TMA_SWAPS *sws) + { + TSECTOR *ss1=&map_sectors[sws->sector1],*ss2=&map_sectors[sws->sector2]; + TSTENA *sd1=&map_sides[sws->sector1<<2],*sd2=&map_sides[sws->sector2<<2]; + char c=4; + char st1=ss2->sector_type,st2=ss1->sector_type; + + for(c=0;c<4;c++) xchg_block(sd1+c,sd2+c,sizeof(TSTENA)); + xchg_block(ss1,ss2,sizeof(TSECTOR)); + if (st1==S_DIRA || st1==S_VODA) propadnout(sws->sector1); + if (st2==S_DIRA || st2==S_VODA) propadnout(sws->sector2); + recheck_button(sws->sector1,0); + recheck_button(sws->sector2,0); + } + +static void hit_1_player(int postava,TMA_WOUND *w,int chaos) + { + int mode=w->pflags>>1; + int zivel=mode-2; + int dostal; + THUMAN *h=postavy+postava; + + if (mode==0) + { + dostal=w->minor+rnd(w->major-w->minor+1); + } + else if (mode==1) + { + short vls[24]; + + memset(vls,0,sizeof(vls)); + vls[VLS_UTOK_L]=w->minor; + vls[VLS_UTOK_H]=w->major; + dostal=vypocet_zasahu(vls,h->vlastnosti,chaos,0,0); + } + else + { + short vls[24]; + + memset(vls,0,sizeof(vls)); + vls[VLS_MGSIL_L]=w->minor; + vls[VLS_MGSIL_H]=w->major; + vls[VLS_MGZIVEL]=zivel; + dostal=vypocet_zasahu(vls,h->vlastnosti,chaos,0,0); + } + player_hit(h,dostal,0); + } + +static void hit_player(TMA_WOUND *w,int sector) + { + int i,pocet,r; + + for(i=0,pocet=0;ipflags & 1) + { + r=rnd(pocet)+1; + for(i=0;i0;i++) if (get_player_triggered(i)) r--; + i--; + hit_1_player(i,w,pocet); + } + else + for(i=0;i=0) + { + m2=mobs[m1].next-1; + if (~mobs[m1].vlajky & MOB_MOBILE && (m2<0 || ~mobs[m2].vlajky & MOB_MOBILE)) monster_test=1; + } + return !monster_test; + } + +static char monster_in_room(int sector) + { + monster_test=0; + is_monster(sector); + if (!monster_test) labyrinth_find_path(sector,65535,SD_MONST_IMPS,is_monster,NULL); + return monster_test; + } + +static int if_jump(TMA_TWOP *i,int side,int abs_pos) + { + TSTENA *sd=map_sides+side; + int go,test,flag; + char ok=0; + + test=abs(i->parm1)-1; + go=i->parm2; + flag=sd->flags; + if (test<32) ok=(flag & (1<>2);break; + } + if (i->parm1<0) ok=!ok; + if (ok) return go+abs_pos;else return -1; + } + +static int if_have_item(TMA_TWOP *i,int abs_pos) + { + int go,test,ip; + char ok=0; + + test=abs(i->parm1); + go=i->parm2; + for(ip=0;ipparm1<0) ok=!ok; + if (ok) return go+abs_pos;else return -1; + } + +static int ma_randjmp(TMA_TWOP *i,int abs_pos) + { + int go,test; + char ok=0; + + test=i->parm1; + go=i->parm2; + if (rand_value==-1) rand_value=rnd(100); + ok=rand_valueparm1)-1; + go=i->parm2; + ok=(test==act); + if (i->parm1<0) ok=!ok; + if (ok) return go+abs_pos;else return -1; + } + + +static int ma_if_flag(TMA_TWOP *i,int abs_pos) + { + int go,test; + char ok=0; + + test=abs(i->parm1)-1; + go=i->parm2; + ok=test_flag(test); + if (i->parm1<0) ok=!ok; + if (ok) return go+abs_pos;else return -1; + } + +static int ma_picki(TMA_TWOP *i,int abs_pos) + { + int go,test; + char ok=0; + + test=abs(i->parm1); + go=i->parm2; + if (picked_item!=NULL) ok=picked_item[0]==test;else ok=0; + if (i->parm1<0) ok=!ok; + if (ok) return go+abs_pos;else return -1; + } + +static void ma_wbook(TMA_LOADLEV *l) + { + char *s; + s=find_map_path(l->name); + add_text_to_book(s,l->start_pos); + play_fx_at(FX_BOOK); + free(s); + } + +static void ma_send_experience(long what) + { + int maxl,i; + THUMAN *h; + + for(i=0,maxl=0,h=postavy;iused && maxllevel) maxl=h->level; + for(i=0,h=postavy;iused && h->lives) + { + h->exp+=what*h->level/maxl; + check_player_new_level(h); + } + bott_draw(0); + } + +static void ma_move_group(int where,int turn,char effect) + { + if (!save_load_trigger(-1)) return; + if (!effect) + { + int i; + THUMAN *h=postavy; + for(i=0;isektor=where,h->direction=turn; + viewsector=where; + viewdir=turn; + } + else + { + THUMAN *h=postavy; + int i; + int sctr; + char kdo=0; + for(i=0;i=0) trig_group|=1<used && h->groupnum==cur_group) trig_group|=1<>=2; + for(i=0,h=postavy;iused && h->sektor==side) trig_group|=1<twop.parm2-q->twop.parm1+1); + x+=q->twop.parm1; + x=create_item_money(x)-1; + if (x) macro_drop_item(sect,side,x); + } + +void macro_change_music(int textindex) +{ + char *trackdef=level_texts[textindex]; + char *nextTrack; + + create_playlist(trackdef); + play_next_music(&nextTrack); + change_music(nextTrack); +} + +void macro_register_global_event(TMULTI_ACTION *q) +{ + GlobEventList[q->globe.event].cancel=q->globe.cancel; + GlobEventList[q->globe.event].sector=q->globe.sector; + GlobEventList[q->globe.event].side=q->globe.side; + GlobEventList[q->globe.event].param=q->globe.param; + if (q->globe.event>=MAGLOB_ONTIMER1 && q->globe.event<=MAGLOB_ONTIMER4) + { + if (GlobEventList[q->globe.event].param>0) + GlobEventList[q->globe.event].param+=game_time; + else + { + long den=24*60*6; + long cas=((-GlobEventList[q->globe.event].param/100)*60+(-GlobEventList[q->globe.event].param%100))*6; + long curtm=game_time % den; + if (cas<=curtm) cas+=den; + GlobEventList[q->globe.event].param=game_time-curtm+cas; + } + } +} + +void call_macro_ex(int side,int flags, int runatside); + +void call_macro(int side,int flags) +{ + call_macro_ex(side,flags,side); +} + + + +void call_macro_ex(int side,int flags, int runatside) + { + TMULTI_ACTION *z,*p; + int *r; + int mcsiz; + int c; + short saved_trigger; + short ls=last_send_action; + short save_rand; + + if (side>=mapsize*4) return; + if (runatside>=mapsize*4) return; + save_rand=rand_value;rand_value=-1; + r=macros[runatside]; + program_counter=0; + if (r==NULL) return; + SEND_LOG("(MULTIACTIONS) Start: Side %.1f Call %X",(float)(runatside/4)+((float)(runatside & 3)/10),flags); + saved_trigger=save_load_trigger(-1); + if (flags & (MC_PASSSUC | MC_PASSFAIL | MC_EXIT)) build_trig_group(TRIG_GROUP,0);else build_trig_group(TRIG_SECTOR,side); + while ((mcsiz=*r)!=0) + { + r++; + zde: + z=(TMULTI_ACTION *)r; + if (z->general.flags & flags) + { + c=-1; + switch (z->general.action) + { + case MA_GEN:break; + case MA_SOUND:macro_sound(&z->sound,side>>2,side & 3,viewsector,viewdir);break; + case MA_TEXTG:macro_disp_text(z->text.textindex,1);break; + case MA_TEXTL:macro_disp_text(z->text.textindex,0);break; + case MA_SENDA:macro_send_act(&z->send_a);break; + case MA_FIREB:macro_fireball(&z->fireball,side>>2,side & 3);break; + case MA_DESTI:if (picked_item!=NULL) + { + destroy_items(picked_item); + free(picked_item); + picked_item=NULL; + pick_set_cursor(); + } + break; + case MA_LOADL:macro_load_another_map(&z->loadlev);break; + case MA_DROPI:macro_drop_item(side>>2,side & 0x3,z->dropi.item);break; + case MA_CREAT:macro_create_item(z->dropi.item);break; + case MA_DIALG:start_dialog(z->text.textindex,-1);break; + case MA_SSHOP:enter_shop(z->text.textindex);break; + case MA_CLOCK:z->general.cancel=decode_lock(z->clock.znak,z->clock.string,z->clock.codenum);break; + case MA_CACTN:cancel_action(z->cactn.sector,z->cactn.dir);break; + case MA_LOCK :z->general.cancel=if_lock(side,z->lock.key_id,z->lock.thieflevel,&z->lock);break; + case MA_SWAPS:swap_sectors(&z->swaps);break; + case MA_WOUND:hit_player(&z->wound,side>>2);break; + case MA_IFJMP:c=if_jump(&z->twop,side,program_counter);break; + case MA_STORY:write_story_text(level_texts[z->text.textindex]);break; + case MA_HAVIT:c=if_have_item(&z->twop,program_counter);break; + case MA_SNDEX:ma_send_experience(z->twop.parm1);break; + case MA_IFACT:c=ma_test_action(&z->twop,ls,program_counter);break; + case MA_CALLS:if (call_map_event(z->twop.parm1,side>>2,side & 3,z->twop.parm2,flags)) call_macro(side,MC_SPEC_SUCC);break; + case MA_MOVEG:ma_move_group(z->twop.parm1,z->twop.parm2 & 3,z->twop.parm2>>7);break; + case MA_PLAYA:ma_play_anim(z->loadlev.name,z->loadlev.dir);break; + case MA_ISFLG:c=ma_if_flag(&z->twop,program_counter);break; + case MA_CHFLG:change_flag(z->twop.parm1,(char)z->twop.parm2);break; + case MA_CUNIQ:macro_drop_item(side>>2,side & 0x3,create_unique_item(&z->uniq.item)-1);break; + case MA_MONEY:ma_drop_money(side>>2,side & 0x3,z);break; + case MA_GUNIQ:macro_create_item(create_unique_item(&z->uniq.item)-1);break; + case MA_PICKI:c=ma_picki(&z->twop,program_counter);break; + case MA_WBOOK:ma_wbook(&z->loadlev);break; + case MA_RANDJ:c=ma_randjmp(&z->twop,program_counter);break; + case MA_ENDGM:unwire_proc();send_message(E_CLOSE_MAP,(void *)255);break; + case MA_GOMOB:ma_control_mob(z->twop.parm1,z->twop.parm2);break; + case MA_SHRMA:call_macro_ex(side,flags,z->twop.parm1*4+z->twop.parm2);break; + case MA_MUSIC:macro_change_music(z->text.textindex);break; + case MA_GLOBE:macro_register_global_event(z);break; + } + if (c!=-1) p=go_macro(runatside,c);else p=NULL; + if (p!=NULL) {r=(int *)p;program_counter=c;mcsiz=r[-1];goto zde;} + if (z->general.once) + { + z->general.action=0; + z->general.once=0; + if (z->general.cancel) + { + z->general.cancel=0; + goto end; + } + } + if (z->general.cancel) return; + } + r=(int *)((char *)r+mcsiz); + program_counter++; + } + end: + rand_value=save_rand; + save_load_trigger(saved_trigger); + SEND_LOG("(MULTIACTIONS) End: Side %.1f Call %X",(float)(runatside/4)+((float)(runatside & 3)/10),flags); + } + +static char lock_saved=255; +static char lock_empty=254; + + +char save_codelocks(FILE *fsta) + { + char *c; + int i; + + c=(char *)&codelock_memory; + i=sizeof(codelock_memory); + while(*c==0 && i) c++,i--; + if (!i) + { + SEND_LOG("(SAVELOAD) Codelocks wasn't used in this map... not saved",0,0); + return !fwrite(&lock_empty,sizeof(lock_empty),1,fsta); + } + SEND_LOG("(SAVELOAD) Storing code-locks...",0,0); + if (!fwrite(&lock_saved,sizeof(lock_saved),1,fsta)) return 1; + return !fwrite(codelock_memory,sizeof(codelock_memory),1,fsta); + } + + +char load_codelocks(FILE *fsta) + { + char c; + + if (!fread(&c,sizeof(lock_empty),1,fsta)) return 1; + if (c!=lock_saved) + { + if (c!=lock_empty) + { + fseek(fsta,-1,SEEK_CUR); //uprav pripadne stare verze savegamu ktere nemaji codelocky + SEND_LOG("(ERROR) Invalid value for codelocks... may be it's old version of savegame",0,0); + } + memset(codelock_memory,0,sizeof(codelock_memory)); + return 0; + } + SEND_LOG("(SAVELOAD) Restoring code-locks for this map...",0,0); + return !fread(codelock_memory,sizeof(codelock_memory),1,fsta); + } + diff --git a/GAME/MENU.C b/GAME/MENU.C new file mode 100644 index 0000000..df89ec7 --- /dev/null +++ b/GAME/MENU.C @@ -0,0 +1,599 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include "engine1.h" +#include +#include "globals.h" + + +#define MUSIC "TRACK06.MUS" + +#define H_ANIM_ORIGN (H_MENUS_FREE+0) +#define H_ANIM (H_MENUS_FREE+1) +#define H_MENU_BAR (H_MENUS_FREE+31) +#define H_MENU_MASK (H_MENUS_FREE+32) +#define H_MENU_ANIM (H_MENUS_FREE+33) +#define H_PICTURE (H_MENUS_FREE+39) + +#define SELECT 1 +#define UNSELECT -1 + +#define SPEED 3 +int speedscroll=3; +char low_mem=0; +static volatile char load_ok=0; + +static cur_pos[]={0,0,0,0,0}; +static cur_dir[]={UNSELECT,UNSELECT,UNSELECT,UNSELECT,UNSELECT}; + +static titlefont=H_FBIG; + +#define TITLE_HEAD 1 +#define TITLE_NAME 2 +#define TITLE_TEXT 3 +#define TITLE_CENTER 0 +#define TITLE_KONEC 4 + +static title_mode=0; +static title_line=0; + +#define CLK_MAIN_MENU 4 + +static char vymacknout(int id,int xa,int ya,int xr,int yr) + { + + for(id=0;id<5;id++) cur_dir[id]=UNSELECT; + xa,ya,xr,yr; + return 1; + } + +static char promacknuti(int id,int xa,int ya,int xr,int yr) + { + char *z; + word *w; + + z=ablock(H_MENU_MASK);w=(word *)z; + z+=6+512; + z+=xr+yr*w[0]; + vymacknout(id,xa,ya,xr,yr); + if (*z!=0) cur_dir[*z-1]=SELECT; + return 1; + } + +static char click(int id,int xa,int ya,int xr,int yr) + { + int i; + + id,xa,ya,xr,yr; + for(i=0;i<5;i++) if (cur_dir[i]==SELECT) break; + if (i!=5) send_message(E_MENU_SELECT,i); + return 1; + } + + +T_CLK_MAP clk_main_menu[]= + { + {-1,220,300,220+206,300+178,promacknuti,1,-1}, + {-1,220,300,220+206,300+178,click,2,-1}, + {-1,0,0,639,479,vymacknout,1,-1}, + {-1,0,0,639,479,empty_clk,0xff,H_MS_DEFAULT}, + }; + +void rozdily(void *orign,void *obr,void *hicolor,void *xtab,int pocet) +//#pragma aux rozdily parm[EDX][ESI][EDI][EBX][ECX]= +{ +__asm + { + mov edx,orign + mov esi,obr + mov edi,hicolor + mov ebx,xtab + mov ecx,pocet + +jp1:lodsb + xor al,[edx] + movzx eax,al + inc edx + movzx eax,short ptr[ebx+eax*2] + stosw + dec ecx + jnz jp1 + } +} + +static void nahraj_rozdilovy_pcx(void **pp,long *s) + { + char *org,*pos; + char *vysl; + word *size,*paltab; + word *hicolor,*p; + void *origin; + int siz; + + load_pcx((char *)*pp,*s,A_8BIT,&vysl); + size=(word *)vysl; + free(*pp); + siz=size[0]*size[1]; + p=hicolor=getmem(siz*2+12); + *p++=size[0]; + *p++=size[1]; + *p++=16; + origin=ablock(H_ANIM_ORIGN); + org=(char *)origin+6+512; + pos=(char *)vysl+6+512; + paltab=(word *)vysl+3; + rozdily(org,pos,hicolor+3,paltab,siz); + free(vysl); + *pp=hicolor; + *s=_msize(*pp); + } + + +static void init_menu_entries(void) + { + int i; + char *a; + def_handle(H_ANIM_ORIGN,"LOGO00.PCX",pcx_8bit_decomp,SR_BGRAFIKA); + def_handle(H_ANIM,"LOGO00.PCX",pcx_15bit_decomp,SR_BGRAFIKA); + a=alloca(15); + for(i=1;i<30;i++) + { + sprintf(a,"LOGO%02d.PCX",i); + def_handle(H_ANIM+i,a,nahraj_rozdilovy_pcx,SR_BGRAFIKA); + } + def_handle(H_MENU_BAR,"MAINMENU.PCX",pcx_8bit_decomp,SR_BGRAFIKA); + def_handle(H_MENU_MASK,"MENUVOL5.PCX",pcx_8bit_decomp,SR_BGRAFIKA); + for(i=0;i<5;i++) + { + sprintf(a,"MENUVOL%d.PCX",i); + def_handle(H_MENU_ANIM+i,a,pcx_15bit_decomp,SR_BGRAFIKA); + } + } + +void zobraz_podle_masky_asm(char barva,void *scr,void *data, void *maska,int xs,int ys) +//#pragma aux zobraz_podle_masky_asm parm[al][edi][esi][ebx][edx][ecx]= + { + __asm + { + mov al,barva + mov edi,scr + mov esi,data + mov ebx,maska + mov edx,xs + mov ecx,ys + push ebp + mov ebp,edx + jp3: cmp al,[ebx] + jnz jp1 + movsw + jmp jp2 +jp1: add edi,2 + add esi,2 +jp2: inc ebx + dec edx + jnz jp3 + mov edx,ebp + add edi,scr_linelen + sub edi,edx + sub edi,edx + dec ecx + jnz jp3 + pop ebp + } + } + +static void zobraz_podle_masky(char barva,char anim) + { + char *maska; + word *data; + word *obr=GetScreenAdr()+300*scr_linelen2+220; + word xs,ys; + + alock(H_MENU_MASK); + maska=ablock(H_MENU_MASK); + data=ablock(H_MENU_ANIM+anim); + xs=data[0]; + ys=data[1]; + zobraz_podle_masky_asm(barva,obr,data+3,maska+6+512,xs,ys); + aunlock(H_MENU_MASK); + } + +static void prehraj_animaci_v_menu(EVENT_MSG *msg,char **unused) + { + static counter=0; + unused; + if (msg->msg==E_TIMER) + { + if (counter % SPEED==0) + { + int i=counter/SPEED;char show=0; + + schovej_mysku(); + if (!low_mem || ~i & 1)put_picture(0,56,ablock(H_ANIM+i)); + do_events(); + for(i=0;i<5;i++) + { + cur_pos[i]+=cur_dir[i]; + if (cur_pos[i]<0) cur_pos[i]=0; + else if (cur_pos[i]>4) cur_pos[i]=4; + else + { + zobraz_podle_masky(i+1,cur_pos[i]); + do_events(); + show=1; + } + } + ukaz_mysku(); + update_mysky(); + showview(0,56,640,250); + if (show) showview(220,300,206,178); + } + counter++; + if (counter>=(SPEED*30)) counter=0; + } + } + + +static void preload_anim(va_list args) + { + int i; + + low_mem=0; + ablock(H_ANIM+29); + for(i=0;i<30;i+=2) + { + apreload(H_ANIM+i); + task_sleep(NULL); + } + for(i=1;i<30;i+=2) + { + THANDLE_DATA *h; + + h=get_handle(H_ANIM+29); + if (h->status!=BK_PRESENT) + { + low_mem=1; + break; + } + apreload(H_ANIM+i); + task_sleep(NULL); + } + for(i=0;i<5;i++) + { + apreload(H_MENU_ANIM+i); + task_sleep(NULL); + } + apreload(H_MENU_MASK); + task_wait_event(E_TIMER); + load_ok=1; + } + +static void klavesnice(EVENT_MSG *msg,void **unused) + { + short cursor,i; + unused; + + + if (msg->msg==E_KEYBOARD) + { + for(cursor=0;cursor<5;cursor++) if (cur_dir[cursor]==SELECT) break; + if (cursor==5) cursor=-1; + + switch(*((char *)msg->data+1)) + { + case 'H':cursor--;if (cursor<0) cursor=0;break; + case 'P':cursor++;if (cursor>4) cursor=4;break; + case 28: + case 57:click(0,0,0,0,0);return; + } + for(i=0;i<5;i++) if (i==cursor) cur_dir[i]=SELECT;else cur_dir[i]=UNSELECT; + } + } + +int enter_menu(char open) + { + char c; + char *d; + init_menu_entries(); + add_task(2048,preload_anim); + load_ok=0; + while(!load_ok) task_sleep(NULL); + if (!open) + { + play_next_music(&d); + change_music(d); + } + update_mysky(); + schovej_mysku(); + curcolor=0;bar(0,0,639,479); + put_picture(0,0,ablock(H_MENU_BAR)); + put_picture(0,56,ablock(H_ANIM)); + ukaz_mysku(); + if (open) effect_show(NULL);else showview(0,0,0,0); + change_click_map(clk_main_menu,CLK_MAIN_MENU); + send_message(E_ADD,E_TIMER,prehraj_animaci_v_menu); + send_message(E_ADD,E_KEYBOARD,klavesnice); + ms_last_event.event_type=0x1; + send_message(E_MOUSE,&ms_last_event); + d=task_wait_event(E_MENU_SELECT); + c=*d; + disable_click_map(); + send_message(E_DONE,E_KEYBOARD,klavesnice); + cur_dir[c]=UNSELECT; + while (cur_pos[c]) task_wait_event(E_TIMER); + task_wait_event(E_TIMER); + send_message(E_DONE,E_TIMER,prehraj_animaci_v_menu); + return c; + } + +char *get_next_title(char control,char *filename) + { + static FILE *titles=NULL; + static ENCFILE fl; + static char buffer[81]; + char *path,*c; + + switch(control) + { + case 1:concat(path,pathtable[SR_MAP],filename); + titles=enc_open(path,&fl); + if (titles==NULL) + { + concat(path,pathtable[SR_DATA],filename); + titles=enc_open(path,&fl); + if (titles==NULL) + { + char popis[300]; + closemode(); + sprintf(popis,"Soubor nenalezen: %s%s nebo %s%s\n",pathtable[SR_MAP],filename,pathtable[SR_DATA],filename); + MessageBox(NULL,popis,NULL,MB_OK|MB_ICONSTOP); + exit(1); + } + } + return (char *)titles; + case 0:if (titles!=NULL)fgets(buffer,80,titles); + c=strchr(buffer,'\n');if (c!=NULL) *c=0; + return buffer; + case -1:if (titles!=NULL)enc_close(&fl); + break; + } + return NULL; + } + +static int title_lines[640][2]; + +static int insert_next_line(int ztrata) + { + char *c; + int ll=-1; + RedirectScreenBufferSecond(); + do + { + if (title_mode!=TITLE_KONEC) c=get_next_title(0,NULL);else c[0]=0; + if (c[0]=='*') + { + strupr(c); + if (!strcmp(c+1,"HEAD")) + { + title_mode=TITLE_HEAD; + set_font(titlefont,RGB(146,187,142)); + } + else if (!strcmp(c+1,"NAME")) + { + title_mode=TITLE_NAME; + set_font(titlefont,RGB(186,227,182)); + } + else if (!strcmp(c+1,"CENTER")) + { + title_mode=TITLE_CENTER; + set_font(titlefont,RGB(255,248,240)); + } + else if (!strcmp(c+1,"TEXT")) + { + title_mode=TITLE_TEXT; + set_font(titlefont,RGB(255,248,240)); + } + else if (!strcmp(c+1,"KONEC")) + { + title_mode=TITLE_KONEC; + } + else if (!strncmp(c+1,"LINE",4)) + { + sscanf(c+5,"%d",&title_line); + } + else if (!strncmp(c+1,"SMALL",5)) titlefont=H_FBOLD; + else if (!strncmp(c+1,"BIG",3)) titlefont=H_FBIG; + else if (!strncmp(c+1,"SPEED",5)) sscanf(c+6,"%d",&speedscroll); + } + else + { + ll=text_height(c); + if (ll==0) ll=text_height("W"); + if (ll0) + { + if (skip>10) skip=10; + newc+=skip*speedscroll; + scan_lines(buff,360,skip); + scroll_and_copy((word *)picture+640*60+3,buff,scr,360,skip,title_lines); + //memcpy(GetScreenAdr(),buff,480*scr_linelen); + get_max_extend(&l,&r); + memmove(title_lines,&title_lines[skip],sizeof(title_lines)-skip*sizeof(int)*2); + //showview(l,60,r-l+1,360); + showview(0,60,639,360); + buff+=scr_linelen2*359; + memcpy(buff,buff+scr_linelen2*skip,40*scr_linelen); + showview(0,0,640,40); + task_wait_event(E_TIMER); + counter+=skip; + lcounter-=skip; + } + else + if (skip<0) counter=skip; + while (lcounter<=0 && !end) + { + int c; + c=insert_next_line(lcounter); + scan_lines(GetBuffer2nd(),360+lcounter,-lcounter); + if (c==-1) + { + end=1; + lcounter=360; + } + else + lcounter+=c; + } + } + while (!(task_quitmsg() || (end && lcounter<=0))); + ukaz_mysku(); + get_next_title(-1,NULL); + aunlock(H_PICTURE); + if (send_back)send_message(E_KEYBOARD,27); + } + +void run_titles(va_list args) + { + int task_id; + task_id=add_task(8196,titles,1,"titulky.TXT"); + task_wait_event(E_KEYBOARD); + term_task(task_id); + } + +void konec_hry() + { + int task_id; + int timer; + char *d; + + schovej_mysku(); + curcolor=0; + bar(0,0,639,479); + effect_show(NULL); + create_playlist(texty[205]); + play_next_music(&d); + change_music(d); + timer=get_timer_value(); + while (get_timer_value()-timer<150) task_sleep(NULL); + task_id=add_task(8196,titles,1,"ENDTEXT.TXT"); + task_wait_event(E_KEYBOARD); + if (is_running(task_id)) term_task(task_id); + task_wait_event(E_TIMER); + task_wait_event(E_TIMER); + task_id=add_task(8196,titles,0,"TITULKY.TXT"); + task_wait_event(E_KEYBOARD); + if (is_running(task_id)) term_task(task_id); + change_music("?"); + curcolor=0; + bar(0,0,639,479); + ukaz_mysku(); + effect_show(NULL); + timer=get_timer_value(); + while (get_timer_value()-timer<150) task_sleep(NULL); + } + diff --git a/GAME/REALGAME.C b/GAME/REALGAME.C new file mode 100644 index 0000000..a4721e8 --- /dev/null +++ b/GAME/REALGAME.C @@ -0,0 +1,1997 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "engine1.h" +#include +#include "globals.h" +#include "inicfg.h" + + + +#define A_OPEN_DOOR 1 +#define A_CLOSE_DOOR 2 +#define A_OPEN_CLOSE 3 +#define A_RUN_PRIM 4 +#define A_SHOW_PRIM 5 +#define A_HIDE_PRIM 6 +#define A_SHOW_HIDE_PRIM 7 +#define A_RUN_SEC 8 +#define A_SHOW_SEC 9 +#define A_HIDE_SEC 10 +#define A_SHOW_HIDE_SEC 11 +#define A_HIDE_PRIM_SEC 12 +#define A_DISPLAY_TEXT 13 +#define A_CODELOCK_LOG 14 +#define A_OPEN_TELEPORT 15 +#define A_CLOSE_TELEPORT 16 +#define A_CODELOCK_LOG2 17 + +#define MAX_FLY_SECT 4 + +#define DIS (char *)0x1 +#define START_HANDLE hl_ptr + +extern TSTR_LIST texty_v_mape; + +static TSTR_LIST leaving_places=NULL; + +char pass_zavora=0; + +char map_with_password=0; + +MAPGLOBAL mglob={ + "","","","",0,0,0,1 +}; +TSTENA *map_sides; +TSECTOR *map_sectors; +TVYKLENEK *map_vyk; //mapa vyklenku +word vyk_max; //pocet vyklenku v mape +short **map_items; +char *flag_map; +TMAP_EDIT_INFO *map_coord; +TSTR_LIST level_texts; +int mapsize; +int num_ofsets[10]; //tabulka ofsetu pro cisla sten k levelu +char sekceid[]=""; +char datapath; +D_ACTION *d_action={NULL}; +int end_ptr; +char cur_group=1; +char group_select=1; +char cancel_pass=0; +char break_sleep=0; +char enable_sort=0; +int sleep_ticks=MAX_SLEEP; +char side_touched=1; +char save_map=1; +//char formace=0; +char last_send_action; //naposled vyslana akce +char insleep=0; +short moving_player=0; + +char force_start_dialog=0; +int start_dialog_number=0; +int start_dialog_mob=0; + +long money=0; + +char runes[5]={0,0,0,0,0}; + +char group_sort[POCET_POSTAV]={0,1,2,3,4,5}; + +long load_section(FILE *f,void **section, int *sct_type,long *sect_size) +// + { + long s; + char c[20]; + + *section=NULL; + fread(c,1,sizeof(sekceid),f); + if (strcmp(c,sekceid)) return -1; + fread(sct_type,1,sizeof(*sct_type),f); + fread(sect_size,1,sizeof(*sect_size),f); + fread(&s,1,sizeof(s),f); + *section=getmem(*sect_size); + s=fread(*section,1,*sect_size,f); + return s; + } + + +void prepare_graphics(int *ofs,char *names,long size,void *decomp,int class) + { + char *p,*end; + + end=names+size; + p=names; + while (p640) pos=640; + curcolor=RGB555(16,16,16);hor_line(0,476,pos); + curcolor=RGB555(8,8,8);hor_line(0,477,pos); + curcolor=RGB555(31,31,31);hor_line(0,475,pos); + showview(0,460,640,20); + do_events(); + } + +void preload_objects(int ofsts) +//#pragma preload_objects parm []; + { + int i; + char lodka=1; + char c[200]; + + for(i=1;iH_LODKA7 || lodka) apreload_sign(i,ofsts); + } + apreload_start(preload_percent); +/* for(i=0;inext;} + calc_fly(); + save_map=1; + free(map_sides); + free(map_sectors); + free(flag_map); + free(map_coord); + free(map_vyk);map_vyk=NULL;vyk_max=0; + if (texty_v_mape!=NULL)release_list(texty_v_mape); + while (d_action!=NULL) + { + void *p=d_action; + d_action=d_action->next; + free(p); + } + texty_v_mape=NULL; + release_list(level_texts); + if (mob_map!=NULL) free(mob_map); + if (macro_block!=NULL) + { + free(macro_block); + free(macros); + macros=NULL; + macro_block=NULL; + macro_block_size=0; + } + if (map_items!=NULL) + { + for(i=0;iloadproc==pcx_fade_decomp) zneplatnit_block(i); + } + for(i=hl_ptr;i>=24; + flags&=0x1f; + return q->flags ^ flags; + } + +void recheck_button(int sector,char auto_action) + { + TSECTOR *ts; + short **ms; + char swch; + char flrpls[]={1,2,2,4,4,8,2,2}; + + ts=map_sectors+sector; + if (ts->sector_type!=S_TLAC_OFF && ts->sector_type!=S_TLAC_ON) return; + ms=map_items+(sector<<2); + swch=(map_coord[sector].flags & MC_DPLAYER || mob_map[sector] || + ms[0]!=NULL || ms[1]!=NULL || ms[2]!=NULL || ms[3]!=NULL); + switch (ts->sector_type) + { + case S_TLAC_OFF:if (swch) + { + ts->floor+=flrpls[ts->flags & 7]; + ts->sector_type=S_TLAC_ON; + if (auto_action) do_action(ts->action,ts->sector_tag,ts->side_tag,0,0); + } + break; + case S_TLAC_ON:if (!swch) + { + ts->floor-=flrpls[ts->flags & 7]; + ts->sector_type=S_TLAC_OFF; + if (auto_action) do_action(ts->action,ts->sector_tag,ts->side_tag,0,0); + } + break; + } + } + +void stop_fly(LETICI_VEC *p,char zvuk) + { + if (zvuk && ~p->flags & FLY_NEDULEZITA)sirit_zvuk(p->sector); + if (!(p->flags & FLY_DESTROY)) + { + item_sound_event(p->items==NULL?p->item:p->items[0],p->sector); + if (p->xpos>=0) push_item(p->sector,(p->smer+(p->ypos>0))&3,p->items); + else push_item(p->sector,(p->smer+(p->ypos<0)+2)&3,p->items); + } + p->flags |= FLY_BURNT; + } + +void interrupt_fly(LETICI_VEC *p) + { + if (p->flags & FLY_DESTROY_SEQ) return; + p->speed=0; + if (p->flags & FLY_DESTROY) + { + p->flags|=FLY_DESTROY_SEQ|FLY_NEHMOTNA; + p->anim_pos=3; + p->velocity=0; + item_sound_event(p->items==NULL?p->item:p->items[0],p->sector); + } + else + if (p->velocity==0) stop_fly(p,1);else if (p->velocity<10) p->velocity=10; + } + +LETICI_VEC *create_fly() + { + LETICI_VEC *p,*q; + + p=letici_veci; + q=NULL; + while (p!=NULL) if (p->flags & FLY_UNUSED) + { + if (q==NULL) letici_veci=p->next;else q->next=p->next; + free(p->items); + break; + } + else + { + q=p; + p=p->next; + } + if (p==NULL) p=New(LETICI_VEC); + p->flags=0; + p->items=NULL; + p->item=0; + p->lives=0; + return p; + } + +TFLY *duplic_fly(TFLY *p) + { + TFLY *q; + + q=create_fly(); + *q=*p; + if (q->items!=NULL) + { + int s=_msize(q->items); + q->items=(short *)getmem(s); + memcpy(q->items,p->items,s); + } + return q; + } + +void calc_fly() + { + LETICI_VEC *p,*q; + short ss; + + for(p=letici_veci;p!=NULL;p=q) + { + p->xpos+=p->speed; + if (p->flags & FLY_BURNT) + if (p->flags & FLY_UNUSED) + { + short ds[2]; + if (letici_veci==p) letici_veci=p->next; + else + { + for(q=letici_veci;q->next!=p;q=q->next); + q->next=p->next; + } + q=p->next; + ds[0]=p->item;ds[1]=0; + if (p->items!=NULL) destroy_items(p->items); else destroy_items(ds); + free(p->items); + p->items=NULL; + free(p); + continue; + } + else + { + q=p->next; + continue; + } + q=p->next; + if (!(p->flags & FLY_NEHMOTNA)) + { + p->velocity+=1; + } + p->zpos-=p->velocity; + ss=p->sector; + if (!(p->flags & FLY_NEDULEZITA)) neco_v_pohybu=1; + if (p->zpos>110) p->zpos=110; + if (p->zpos<=20) + { + if (map_sectors[p->sector].sector_type==S_DIRA) + { + p->speed=0; + if (p->zpos<=-128) + { + p->sector=map_sectors[p->sector].sector_tag; + p->zpos=256; + } + } + else + stop_fly(p,1); + continue; + } + if (p->flags & FLY_IN_FLY && p->xpos>-16 && zasah_veci(p->sector,p)) + { + interrupt_fly(p); + continue; + } + if (p->xpos>63) + { + p->flags|=FLY_IN_FLY; + p->xpos-=127; + ss=map_sectors[p->sector].step_next[p->smer]; + if (p->sector != 0 && !(map_sides[p->sector*4+p->smer].flags & SD_THING_IMPS)) + { + p->sector=ss; + + if (ISTELEPORTSECT(p->sector)) + p->sector=map_sectors[p->sector].sector_tag; + } + + else + { + p->xpos+=127-p->speed; + if (!zasah_veci(p->sector,p) && p->lives) p->lives--; + if (p->lives) + { + TFLY *q,*z; + + q=duplic_fly(p);q->smer=p->smer+1&3; + z=duplic_fly(p);z->smer=p->smer-1&3; + add_fly(q); + add_fly(z); + } + interrupt_fly(p); + } + } + else if (p->counter++ > 100) { + zasah_veci(p->sector,p); + interrupt_fly(p); + continue; + } + } + + } + +extern long sound_side_flags; + + +void calc_animations() + { + int i; + + for (i=0;iflags; + pj=p->prim_anim>>4;pk=p->prim_anim & 15; + sj=p->sec_anim>>4;sk=p->sec_anim & 15; + if (!pk && !sk) continue; + if (p->flags & SD_PRIM_ANIM) + { + if (p->flags & SD_PRIM_GAB) + if (pj==0 || pj==pk) p->flags^=SD_PRIM_FORV; + if (p->flags & SD_PRIM_FORV) pj++; else pj--; + if (pj>pk) pj=0; + if (pj<0) pj=pk; + } + else + { + if (p->flags & SD_PRIM_FORV) pj++; else pj--; + if (pk && (pj+(!(p->flags & SD_PRIM_FORV))==pk)) + {p->flags&=~0xff;p->flags|=flag_map[i];} + if (pj>pk) pj=pk; + else if (pj<0) pj=0; + else call_macro(i,MC_ANIM|((pj & 1)?MC_ANIM2:0)|(pj?0:MC_CLOSEDOOR)|(pj==pk?MC_OPENDOOR:0)); + if (pk==pj && p->flags & SD_PRIM_GAB) + p->flags&=~SD_PRIM_FORV; + } + if (p->flags & SD_SEC_ANIM) + { + if (p->flags & SD_SEC_GAB) + if (sj==0 || sj==sk) p->flags^=SD_SEC_FORV; + if (p->flags & SD_SEC_FORV) sj++; else sj--; + if (sj>sk) sj=0; + if (sj<0) sj=sk; + } + else + { + if (p->flags & SD_SEC_FORV) sj++; else sj--; + if (!pk && sk && (sj+(!(p->flags & SD_SEC_FORV))==sk)) + {p->flags&=~0xff;p->flags|=flag_map[i];} + if (sj>sk) sj=sk; + else if (sj<0) sj=0; + else if (!pk) call_macro(i,MC_ANIM|((sj & 1)?MC_ANIM2:0)|(pj?0:MC_CLOSEDOOR)); + if (sk==sj && p->flags & SD_SEC_GAB) + p->flags&=~SD_SEC_FORV; + } + p->prim_anim=(pj<<4)+pk; + p->sec_anim=(sj<<4)+sk; + } + sound_side_flags=0; + } + + +void delay_action(int action_numb,int sector,int direct,int flags,int nosend,int delay) + { + D_ACTION *d; + if (!sector && !direct) return; + if (!delay) do_action(action_numb,sector,direct,flags,nosend); + else + { + d=(D_ACTION *)getmem(sizeof(D_ACTION)); + d->action=action_numb; + d->sector=sector; + d->side=direct; + d->flags=flags>>16; + d->nocopy=nosend; + d->delay=delay; + d->next=d_action; + d_action=d; + } + } +/* +int get_action_delay(TSTENA *q) + { + if (q->flags & SD_DELAY) + { + if (q->sec) return q->sec_anim & 0xf; + return q->prim_anim & 0xf; + } + else + return 0; + } +*/ +void check_codelock_log(int sector,unsigned long flags) + { + int i; + TSTENA *p; + TSECTOR *s; + p=&map_sides[sector*4]; + s=&map_sectors[sector]; + for (i=0;i<4;i++) if (!(p[i].flags & SD_PRIM_VIS)) break; + if (i==4) do_action(s->action,s->sector_tag,s->side_tag,flags,0); + } + + +int do_action(action_numb,sector,direct,flags,nosend) + { + TSTENA *q; + TSECTOR *s; + char *c; + int sid; + char ok=0; + + sid=sector*4+direct; + s=&map_sectors[sector]; + q=&map_sides[sid]; + c=&flag_map[sid]; + switch (action_numb) + { + case 0: + q->flags=actn_flags(q,flags); + break; + case A_OPEN_DOOR: + if (!(q->flags & SD_PRIM_FORV) && !(q->flags & SD_PRIM_ANIM)) + { + q->flags|=SD_PRIM_FORV; + *c=(char)actn_flags(q,flags); + ok=1; + } + if (!(q->flags & SD_SEC_FORV)) + { + q->flags|=SD_SEC_FORV; + ok=1; + } + sound_side_flags=q->flags; + break; + case A_CLOSE_DOOR: + if (q->flags & SD_PRIM_FORV && !(q->flags & SD_PRIM_ANIM)) + { + q->flags&=~SD_PRIM_FORV; + *c=(char)actn_flags(q,flags); + ok=1; + } + if (q->flags & SD_SEC_FORV) + { + q->flags&=~SD_SEC_FORV; + ok=1; + } + sound_side_flags=q->flags; + break; + case A_OPEN_CLOSE: + if (!(q->flags & SD_PRIM_ANIM)) q->flags^=SD_PRIM_FORV | SD_SEC_FORV; + else q->flags^= SD_SEC_FORV ; + *c=(char)actn_flags(q,flags); + ok=1; + sound_side_flags=q->flags; + break; + case A_RUN_PRIM: + q->flags|=SD_PRIM_ANIM; + ok=1; + break; + case A_HIDE_PRIM: + if (q->flags & SD_PRIM_VIS) + { + q->flags&=~SD_PRIM_VIS; + *c=(q->flags=actn_flags(q,flags)); + ok=1; + } + break; + case A_SHOW_PRIM: + if (!(q->flags & SD_PRIM_VIS)) + { + q->flags|=SD_PRIM_VIS; + *c=(q->flags=actn_flags(q,flags)); + ok=1; + } + break; + case A_SHOW_HIDE_PRIM: + q->flags^=SD_PRIM_VIS; + *c=(q->flags=actn_flags(q,flags)); + ok=1; + break; + case A_RUN_SEC: + q->flags|=SD_SEC_ANIM; + ok=1; + break; + case A_HIDE_SEC: + if (q->flags & SD_SEC_VIS) + { + q->flags&=~SD_SEC_VIS; + *c=(q->flags=actn_flags(q,flags)); + ok=1; + } + break; + case A_SHOW_SEC: + if (!(q->flags & SD_SEC_VIS)) + { + q->flags|=SD_SEC_VIS; + *c=(q->flags=actn_flags(q,flags)); + ok=1; + } + break; + case A_SHOW_HIDE_SEC: + q->flags^=SD_SEC_VIS; + *c=(q->flags=actn_flags(q,flags)); + ok=1; + break; + case A_HIDE_PRIM_SEC: + if ((q->flags & SD_SEC_VIS)||(q->flags & SD_PRIM_VIS)) + { + q->flags&=~(SD_SEC_VIS+SD_PRIM_VIS); + *c=(q->flags=actn_flags(q,flags)); + ok=1; + } + break; + case A_DISPLAY_TEXT: + bott_disp_text(level_texts[sector]); + ok=1; + return 0; + case A_CODELOCK_LOG2: + check_codelock_log(sector,flags); + q->flags^=SD_PRIM_VIS; + check_codelock_log(sector,flags); + ok=1; + break; + case A_CODELOCK_LOG: + check_codelock_log(sector,0x1f000000); + q->flags^=SD_PRIM_VIS; + check_codelock_log(sector,0x1f000000); + ok=1; + break; + case A_OPEN_TELEPORT: + ok=(s->sector_type!=S_TELEPORT); + s->sector_type=S_TELEPORT; + { + int i; + for(i=0;i<4;i++) map_sides[(sector<<2)+i].flags|=SD_SEC_VIS; + } + nosend=1; + break; + case A_CLOSE_TELEPORT: + ok=(s->sector_type==S_TELEPORT); + s->sector_type=S_NORMAL; + { + int i; + for(i=0;i<4;i++) map_sides[(sector<<2)+i].flags&=~SD_SEC_VIS; + } + nosend=1; + break; + } + if (nosend) return 0; + last_send_action=action_numb; + call_macro(sid,MC_INCOMING); + if (ok) + { + ok=0; + call_macro(sid,MC_SUCC_DONE); + } + if (q->flags & SD_COPY_ACTION) + { + + q->flags&=~SD_COPY_ACTION; + delay_action(action_numb,q->sector_tag,q->side_tag,flags,0,0); + q->flags|=SD_COPY_ACTION; + } + if (q->flags & SD_SEND_ACTION) + { + + q->flags&=~SD_SEND_ACTION; + delay_action(q->action,q->sector_tag,q->side_tag,q->flags,0,0); + q->flags|=SD_SEND_ACTION; + } + if (q->flags & SD_APPLY_2ND && s->step_next[direct]) + do_action(action_numb,s->step_next[direct],(direct+2)&3,flags,1); + return 0; + } + +/* +void black(int i,int sector,int dir) + { + int xl,y1,xr,y2; + + if (!(map_sides[sector*4+dir].flags & SD_INTERIER)) return; + y2=MIDDLE_Y+points[i][0][VIEW3D_Z].y+16; + y1=MIDDLE_Y+points[i][1][VIEW3D_Z].y+16; + if (i<0) + { + xl=MIDDLE_X-points[i][0][VIEW3D_Z].x; + xr=MIDDLE_X-points[i+1][0][VIEW3D_Z].x; + } + else + if (i>0) + { + xl=MIDDLE_X+points[i-1][0][VIEW3D_Z].x; + xr=MIDDLE_X+points[i][0][VIEW3D_Z].x; + } + else + { + xl=MIDDLE_X-points[0][0][VIEW3D_Z].x; + xr=MIDDLE_X+points[0][0][VIEW3D_Z].x; + } + if (xl<0) xl=0; + if (xr>639) xr=639; + curcolor=back_color; + bar(xl,y1,xr,y2); + } +*/ + +void do_delay_actions() + { + D_ACTION *d,*p,*q; + + d=d_action;p=NULL; + while (d!=NULL) + { + if (!(--d->delay)) + { + q=d; + if (q==d_action) + { + d_action=d->next; + d=d_action; + } + else + { + p=d_action; + while (p->next!=d) p=p->next; + p->next=d->next; + d=p->next; + } + do_action(q->action,q->sector,q->side,q->flags<<16,q->nocopy); + free(q); + } + else + { + d=d->next; + } + } + } + +void mrtva_skupina() + { + int i=0; + + for(i=0;!postavy[i].groupnum || !postavy[i].used;i++); + zmen_skupinu(&postavy[i]); + } +/* +static void check_pod_vodou(char mode) + { + short sectors[POCET_POSTAV]; + short psec; + short pp=0; + int i,j; + + + for(i=0;ikondice) h->kondice-=ziv*2; + else + { + player_hit(h,h->lives,0); + } + if (h->kondice<0) h->kondice=0; + bott_draw(0); + } + +void check_players_place(char mode) + { + int i; + THUMAN *h=postavy; + char vir_eff=0; + static char vir_zavora=0; + char levitat; + + for(i=0;iused && h->lives) + { + int sect; + int u1; + + levitat=(h->vlastnosti[VLS_KOUZLA] & SPL_LEVITATION)!=0; + sect=h->sektor; + if (sect>=mapsize) continue; + switch (map_sectors[sect].sector_type) + { + case S_ACID:if (!levitat) + if (h->lives>3) {h->lives-=3;bott_draw(0);} + else + player_hit(h,3+7*mode,0); + break; + case S_VIR: + if (!levitat) + if (mode==0 && vir_zavora==0) + { + int i,smer; + vir_zavora=1;pass_zavora=0; + smer=rnd(100)<50?-1:1; + if (vir_eff==0) + for(i=0;i<8;i++) turn_zoom(smer); + vir_eff=1; + vir_zavora=0; + cancel_pass=1; + } + else + break; + case S_LAVA: if (!levitat) + { + u1=(h->lives); + player_hit(h,u1,0); + bott_draw(0); + } + else + { + if (h->lives>3) {h->lives-=3;bott_draw(0);} + else + player_hit(h,3+7*mode,0); + } + + break; + case S_SSMRT: + u1=(h->lives); + player_hit(h,u1,0); + bott_draw(0); + break; + case S_VODA: + if (!levitat) + akce_voda(h,mode);break; + case S_DIRA:if (!pass_zavora) postavy_propadnout(sect);break; + case S_LODKA:if (lodka!=1 && mode) + { + set_backgrnd_mode(1);lodka=1; + } + break; + } + if (mglob.map_effector==ME_PVODA && ~map_coord[h->sektor].flags & MC_SAFEPLACE) akce_voda(h,mode); + if (map_sectors[sect].sector_type!=S_LODKA && lodka) + { + set_backgrnd_mode(0);lodka=0; + } + } + } + +static void move_lodka(int oldsect,int newsect) + { + if (map_sectors[oldsect].sector_type==S_LODKA && + map_sectors[newsect].sector_type==S_VODA) + { + map_sectors[oldsect].sector_type=S_VODA; + map_sectors[newsect].sector_type=S_LODKA; + } + } + +void calc_game() + { + int d; + calc_animations(); + if (d_action!=NULL) do_delay_actions(); + calc_mobs(); + if (force_start_dialog && !norefresh && !cancel_render) + { + force_start_dialog=0; + call_dialog(start_dialog_number,start_dialog_mob); + } + check_players_place(0); + if ((d=check_end_game())!=0) + if (d==1) wire_end_game();else mrtva_skupina(); + if (battle && cur_mode!=MD_INBATTLE) + { + start_battle(); + } + else if(!battle && select_player!=-1) + { + select_player=-1; + bott_draw(0); + } + } + +void a_touch(sector,dir) + { + TSTENA *q; + int sid; + + sid=sector*4+dir; + q=&map_sides[sid]; + if (q->flags & SD_PASS_ACTION) return; + if (q->sec && ~q->flags & SD_SEC_VIS) return; + side_touched=1; + if (!q->sec) delay_action(q->action,q->sector_tag,q->side_tag,q->flags,0,0); + else + if (q->flags & SD_SEC_VIS) + { + if (q->flags & SD_AUTOANIM) do_action(A_OPEN_CLOSE,sector,dir,0,1); + delay_action(q->action,q->sector_tag,q->side_tag,q->flags,0,0); + } + call_macro(sid,MC_TOUCHSUC); + } + +void a_pass(sector,dir) + { + TSTENA *q; + + q=&map_sides[sector*4+dir]; + q->flags&=~SD_SECRET; + if (q->flags & SD_ALARM) + { + if (GlobEvent(MAGLOB_ALARM,viewsector,viewdir)) + sirit_zvuk(map_sectors[sector].step_next[dir]); + } + if (!(q->flags & SD_PASS_ACTION)) return; + delay_action(q->action,q->sector_tag,q->side_tag,q->flags,0,0); + } + +void zmen_skupinu(THUMAN *p) + { + int i; + + if (p->groupnum==0) {bott_draw(0);return;} + cur_group=p->groupnum; + for(i=0;isektor; + viewdir=p->direction; + schovej_mysku(); + bott_draw(0); + other_draw(); + ukaz_mysku(); + showview(0,378,640,480); + ukaz_mysku(); + cancel_render=1; + } + +void sort_groups() + { + int i,j,t=0; + + if (cur_mode==MD_PRESUN) group_sort[0]=moving_player; + if (enable_sort) + { + for(i=0;iused && h->groupnum==1 && h->sektor!=viewsector) break; + if (i==POCET_POSTAV) cur_group=1; + } + for(i=0,h=postavy;iused && h->lives && h->sektor==viewsector) h->groupnum=cur_group; + } + + bott_draw(0); + } + +void destroy_player_map() //je nutne volat pred presunem postav + { + int i; + for(i=0;isektor].flags|=(p->lives?MC_PLAYER:MC_DEAD_PLR); + if (mglob.map_effector==ME_PVODA) + { + if (q_item_one(i,water_breath+1))map_coord[p->sektor].flags|=MC_SAFEPLACE; + } + } + } + + +char chod_s_postavama(char sekupit) + { + int i,/*j,*/lastsec=-1; + char marks[6]; + char gatt=0; + signed char group_nums[7]; + + destroy_player_map(); + if (cur_mode==MD_PRESUN) + { + postavy[select_player].sektor=viewsector; + postavy[select_player].direction=viewdir; + } + else + { + memset(group_nums,0xff,sizeof(group_nums)); + group_nums[0]=0; + for(i=0;iused && h1->lives && !marks[group_sort[i]]) + { + int sc; + int ss=(sc=h1->sektor)<<2; + for(dir=0;dir<4;dir++) if (map_sectors[sc].step_next[dir]==lastsec && ~map_sides[ss+dir].flags & SD_PLAY_IMPS) break; + if (dir!=4) + { + for(j=0,h2=postavy;jused && h2->lives && h2->groupnum==h1->groupnum) + { + h2->sektor=lastsec; + h2->direction=dir; + h2->utek=1; + marks[j]=1; + } + lastsec=sc; + attach=1; + gatt=1; + group_nums[h1->groupnum]=gr++; + } + } + if (!attach) break; + } + for(i=1;i<7;i++) if (group_nums[i]==-1) group_nums[i]=gr++; + for(i=0;imsg==E_INIT || msg->msg==E_DONE) return; + check_all_mobs(); + calc_game();msg;data; + SEND_LOG("(GAME) STEP",0,0); + } + +void do_halucinace() + { + hal_sector=rnd(mapsize-1)+1; + hal_dir=rnd(4); + } + +void sector0(void) + { + int i; + + for(i=0;iused && h->groupnum==grp && h->lives && + (h->vlastnosti[VLS_POHYB]==0 || h->kondice==0)) return 0; + return 1; + } + +void step_zoom(char smer) + { + char nopass,drs; + int sid,nsect,sect; + char can_go=1; + + if (running_anm) return; + if (pass_zavora) return; + if (lodka && (smer==1 || smer==3)) return; + cancel_pass=0; + drs=(viewdir+smer)&3; + sid=viewsector*4+drs; + sect=viewsector; + call_macro(sid,MC_EXIT); + nopass=(map_sides[sid].flags & SD_PLAY_IMPS); + if (nopass) call_macro(sid,MC_PASSFAIL);else call_macro(sid,MC_PASSSUC); + if (cur_mode==MD_PRESUN) + { + select_player=moving_player; + if(!postavy[select_player].actions) nopass=1; + } + else can_go=test_can_walk(cur_group); + if (!can_go) + { + bott_disp_text(texty[220]); + return; + } + if (force_start_dialog) cancel_pass=1; + if (cancel_pass) return; + if (!GlobEvent(MAGLOB_ONSTEP,viewsector,viewdir)) return; + if (viewsector!=sect) nsect=viewsector,viewsector=sect;else nsect=map_sectors[viewsector].step_next[drs]; + if (map_sectors[nsect].sector_type==S_SCHODY) + { + int i; + viewdir=(viewdir+map_sectors[nsect].side_tag) & 3; + nsect=map_sectors[nsect].sector_tag; + i=mob_map[nsect]; + while (i!=0) + { + i--; + mobs[i].sector=mobs[i].home_pos; + i=mobs[i].next; + } + mob_map[nsect]=0; + } + else if (mob_map[nsect] && !nopass) + if (!battle){ if (!mob_alter(nsect)) return; } + else return; + if (map_sectors[nsect].sector_type==S_LODKA) + { + int i; + THUMAN *h; + group_all();can_go=1; + for(i=0,h=postavy;igroupnum!=cur_group && h->lives) break; + if (i!=POCET_POSTAV) + { + bott_disp_text(texty[66]); + return; + } + } + pass_zavora=1; + norefresh=1; + schovej_mysku(); + anim_sipky(H_SIPKY_S+smer,1); + anim_sipky(0,255); + hide_ms_at(385); + ukaz_mysku(); + if (set_halucination) do_halucinace(); + if (loadlevel.name[0]) + { + if (!battle) + { + pass_zavora=0; + return; + } + nopass=1; + loadlevel.name[0]=0; + exit_wait=0; + } + if (!can_go) nopass=1; + if (!nopass) + { + a_pass(viewsector,drs); + viewsector=nsect; + move_lodka(sect,nsect); + chod_s_postavama(1); + send_message(E_KROK); + } + if (!cancel_pass) + { + render_scene(viewsector,viewdir); + if (smer==2) + { + OutBuffer2nd(); + if (!nopass) shift_zoom(smer); + } + else + { + shift_zoom(smer); + OutBuffer2nd(); + if (nopass) shift_zoom(smer+2); + } + if (battle || (game_extras & EX_ALWAYS_MINIMAP)) draw_medium_map(); + sort_groups(); + bott_draw(0); + other_draw(); + } + update_mysky(); + ukaz_mysku(); + if (!cancel_render) showview(0,0,0,0); + norefresh=0; + cancel_render=1; + mix_back_sound(0); + viewsector=postavy_propadnout(viewsector); + check_postavy_teleport(); + recheck_button(sect,1); + recheck_button(viewsector,1); + check_players_place(1); + cancel_pass=0; + pass_zavora=0; + if (force_start_dialog) + { + force_start_dialog=0; + call_dialog(start_dialog_number,start_dialog_mob); + } + if (cur_mode==MD_GAME) recalc_volumes(viewsector,viewdir); + } + +void turn_zoom(int smer) + { + if (running_anm) return; + if (pass_zavora) return;else pass_zavora=1; + if (!GlobEvent(MAGLOB_ONTURN,viewsector,viewdir)) return; + if (set_halucination) do_halucinace(); + norefresh=1; + hold_timer(TM_BACK_MUSIC,1); + viewdir=(viewdir+smer)&3; + render_scene(viewsector,viewdir); + hide_ms_at(387); + if (smer==1) + { + anim_sipky(H_SIPKY_SV,1); + anim_sipky(0,255); + turn_left(); + } + else + { + anim_sipky(H_SIPKY_SZ,1); + anim_sipky(0,255); + turn_right(); + } + chod_s_postavama(0); + OutBuffer2nd(); + if (battle || (game_extras & EX_ALWAYS_MINIMAP)) draw_medium_map(); + other_draw(); + update_mysky(); + ukaz_mysku(); + showview(0,0,0,0); + recalc_volumes(viewsector,viewdir); + if (!battle) calc_game(); + norefresh=0; + cancel_render=1; + hold_timer(TM_BACK_MUSIC,0); + mix_back_sound(0); + pass_zavora=0; + } + +int check_path(word **path,word tosect) + { + word *p,*n,ss; + char ok; + int i; + + p=*path; + n=p+1;ok=0; + while (*p!=tosect) + { + if (map_sectors[*n].sector_type!=S_DIRA && ISTELEPORTSECT(*n)) + { + for(i=0;i<4 && map_sectors[*p].step_next[i]!=*n;i++) + if (i==4) + { + ss=*p; + free(*path);*path=NULL; + return ss; + } + if (!map_sides[(*p<<2)+i].flags & SD_PLAY_IMPS) ok=1; + } + if (!ok) + { + ss=*p; + free(*path);*path=NULL; + najdi_cestu(*p,tosect,SD_PLAY_IMPS,path,0); + if (*path==NULL) return ss; + p=*path; + n=p+1; + a_touch(ss,i); + } + p++;n++; + ok=0; + } + free(*path);*path=NULL; + return tosect; + } + +void recall() + { + int tosect,max,i,j; + word *paths[POCET_POSTAV]; + + for(i=0;imsg==E_KEYBOARD) break_sleep=1; + if (msg->msg==E_MOUSE) + { + MS_EVENT *ms; + + ms=get_mouse(msg); + if (ms->event_type & (0x2+0x8+0x20)) break_sleep=1; + } + } + +void sleep_players(va_list args) + { + int i; + int hours=0; + char reg; + char enablity; + + if (!sleep_ticks) return; + if (!GlobEvent(MAGLOB_STARTSLEEP,viewsector,viewdir)) return; + enablity=enable_sound(0); + mute_all_tracks(0); + autosave(); + insleep=1; + update_mysky(); + schovej_mysku(); + curcolor=0;bar(0,17,639,360+16); + send_message(E_ADD,E_KEYBOARD,key_break_sleep); + ukaz_mysku(); + showview(0,0,0,0); + unwire_proc(); + break_sleep=0; + while (sleep_ticks && !break_sleep) + { + reg=0; + if (!(sleep_ticks%6)) + { + if ((reg=(sleep_ticks%HODINA==0))==1) + { + char s[50]; + for(i=0;imsg==E_KEYBOARD) + { + c=(*(int *)msg->data)>>8; + while (_bios_keybrd(_KEYBRD_READY) ) _bios_keybrd(_KEYBRD_READ); + switch (c) + { + case 'H':step_zoom(0);break; + case 'P':step_zoom(2);break; + case 'M':if (GetKeyState(VK_CONTROL) & 0x80) + step_zoom(1); + else + turn_zoom(1); + break; + case 'K':if (GetKeyState(VK_CONTROL) & 0x80) + step_zoom(3); + else + turn_zoom(-1); + break; + case 79: + case 's':step_zoom(3);break; + case 81: + case 't':step_zoom(1);break; + case 0x21:if (q_item(flute_item,viewsector)) bott_draw_fletna(); + case 57:a_touch(viewsector,viewdir);if (cur_mode==MD_PRESUN)send_message(E_KEYBOARD,28*256);break; + case 15: + case 50: + if (GlobEvent(MAGLOB_BEFOREMAPOPEN,viewsector,viewdir)) + show_automap(1); + break; + case 0x17:unwire_proc(); + wire_inv_mode(human_selected);break; +// case 'A':lodka=!lodka;set_backgrnd_mode(lodka);break; + case 1:konec(0,0,0,0,0);break; +// case 25:GamePause();break; + case 28:enforce_start_battle();break; + case 82:group_all();break; + case '<':if (!battle && GlobEvent(MAGLOB_CLICKSAVE,viewsector,viewdir)) + {unwire_proc();cancel_render=1;wire_save_load(1);}break; + case '=':unwire_proc();cancel_render=1;wire_save_load(0);break; + case '>':game_setup(0,0,0,0,0);break; + CASE_KEY_1_6:c=group_sort[c-2]; + if (postavy[c].sektor==viewsector && postavy[c].used) + add_to_group(c); + zmen_skupinu(postavy+c); + bott_draw(1); + break; +/* default: + { + char s[20]; + bott_disp_text(itoa(c,s,10)); + break; + }*/ + } + } + return &game_keyboard; + } + + +void start_dialog(int dialog,int mob) + { + if (battle) + { + call_dialog(dialog,mob); + } + else + { + force_start_dialog=1; + start_dialog_number=dialog; + start_dialog_mob=mob; + } +// call_dialog(dialog,mob); + } + + +int postavy_propadnout(int sector) + { + char redraw=0; + int i,z=sector; + mute_hit_sound=0; + if (map_coord[sector].flags & MC_DPLAYER && map_sectors[sector].sector_type==S_DIRA) + { + for(i=0;i + +#define DELITEL 0xC005 + + +unsigned long vysledek; + +main() + { + int i; + for(i=0;i<65535;i++) + { + vysledek=DELITEL*i; + printf("%08X ",vysledek); + } + } diff --git a/GAME/SETUP.C b/GAME/SETUP.C new file mode 100644 index 0000000..c2790d4 --- /dev/null +++ b/GAME/SETUP.C @@ -0,0 +1,265 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "engine1.h" +#include +#include "globals.h" +#include +#include + +extern char enable_sort; +extern char autoattack; + + +char q_runsetup(char *parm) + { + char c[6]; + + strncpy(c,parm,6); + strupr(c); + return !strncmp(c,"/SETUP",6); + } + + +static void show_setup_desktop(WINDOW *w) + { + put_picture(w->x,w->y,ablock(H_SETUPBAR)); + } + +static void checkbox_animator(THE_TIMER *t) + { + t; + animate_checkbox(10,130,10); + } + +static int effects[]={SND_GVOLUME,SND_MUSIC,SND_GFX,SND_TREBL,SND_BASS,SND_XBASS}; + +static void do_setup_change() + { + char c; + + c=f_get_value(0,o_aktual->id); + switch (o_aktual->id) + { + case 10:set_snd_effect(SND_SWAP,c & 1);break; + case 20:set_snd_effect(SND_OUTFILTER,c & 1);break; + default:set_snd_effect(effects[o_aktual->id/10-20],c);break; + } + } + +static void change_zoom() + { + int id=o_aktual->id; + int i; + + for(i=30;i<60;i+=10) c_set_value(0,i,f_get_value(0,i) & ~1 | (i==id)); + zoom_speed((id-30)/10); + } + +static void change_turn() + { + int id=o_aktual->id; + int i; + + for(i=60;i<90;i+=10) c_set_value(0,i,f_get_value(0,i) & ~1 | (i==id)); + turn_speed((id-60)/10); + } + +void unwire_setup(); + +static EVENT_PROC(setup_keyboard) + { + user_ptr; + WHEN_MSG(E_KEYBOARD) + { + if (GET_DATA(char)==27) + { + unwire_proc(); + } + } + } + +static void wire_setup() + { + unwire_proc(); + unwire_proc=unwire_setup; + mute_all_tracks(0); + cur_mode=MD_SETUP; + send_message(E_ADD,E_KEYBOARD,setup_keyboard); + SEND_LOG("(GAME) Starting setup",0,0); + } + +static void unwire_setup() + { + show_names=f_get_value(0,90) & 1; + enable_sort=f_get_value(0,100) & 1; + autoattack=f_get_value(0,110) & 1; + autosave_enabled=f_get_value(0,120) & 1; + level_preload=f_get_value(0,130) & 1; + delete_from_timer(TM_CHECKBOX); + mix_back_sound(32768); + close_current(); + send_message(E_DONE,E_KEYBOARD,setup_keyboard); + wire_proc(); + cancel_render=1; + SEND_LOG("(GAME) Setup closed",0,0); + } + +char exit_setup(int id,int xa,int ya,int xr,int yr) + { + id,xa,ya,xr,yr; + unwire_setup(); + return 0; + } + +T_CLK_MAP setup[]= + { + {-1,0,0,639,14,exit_setup,2,H_MS_DEFAULT}, + {-1,0,15,639,479,exit_setup,0x8,H_MS_DEFAULT}, + }; + + +void skeldal_checkbox(OBJREC *); +void setup_ok_button(OBJREC *); +void skeldal_soupak(OBJREC *); + + + + +void new_setup() + { + WINDOW *w; + CTL3D ctl; + int i; + static int textxp[]={ 75, 75,435,435,434,535,535,535,434,434,434,434,434, 35,410,510}; + static int textyp[]={275,305, 65, 95,125, 65, 95,125,185,215,245,275,305,235, 40, 40}; + static int textc[]={ 53, 54, 56, 57, 58, 56, 57, 58,140,141,142,143,144 ,51, 55, 59}; + + mix_back_sound(256000-16384); + memset(&ctl,0,sizeof(ctl)); + change_click_map(setup,4); + set_font(H_FBOLD,SETUP_COL2); + default_font=curfont; + memcpy(f_default,charcolors,sizeof(f_default)); + w=create_window(0,SCREEN_OFFLINE,639,359,0,&ctl); + w->draw_event=show_setup_desktop; + desktop_add_window(w); + define(10,50,270,190,20,0,skeldal_checkbox); c_default(get_snd_effect(SND_SWAP)); on_change(do_setup_change); + if (check_snd_effect(SND_OUTFILTER)) + { + define(20,50,300,190,20,0,skeldal_checkbox);c_default(get_snd_effect(SND_OUTFILTER)); + on_change(do_setup_change); + } + + define(30,410,60,90,20,0,skeldal_checkbox);c_default(zoom_speed(-1)==0); + on_change(change_zoom); + define(40,410,90,90,20,0,skeldal_checkbox);c_default(zoom_speed(-1)==1);on_change(change_zoom); + define(50,410,120,90,20,0,skeldal_checkbox);c_default(zoom_speed(-1)==2);on_change(change_zoom); + + define(60,510,60,90,20,0,skeldal_checkbox);c_default(turn_speed(-1)==0);on_change(change_turn); + define(70,510,90,90,20,0,skeldal_checkbox);c_default(turn_speed(-1)==1);on_change(change_turn); + define(80,510,120,90,20,0,skeldal_checkbox);c_default(turn_speed(-1)==2);on_change(change_turn); + + for(i=0;i<5;i++) + { + define((i+9)*10,410,180+i*30,190,20,0,skeldal_checkbox); + switch(i) + { + case 0:c_default(show_names);break; + case 1:c_default(enable_sort);break; + case 2:c_default(autoattack);break; + case 3:c_default(autosave_enabled);break; + case 4:c_default(level_preload);break; + } + } + + for(i=0;imsg==E_INIT) + { + volsave=get_snd_effect(SND_GVOLUME); + set_snd_effect(SND_GVOLUME,volsave>>1); + } + if (msg->msg==E_KEYBOARD) + { + set_snd_effect(SND_GVOLUME,volsave); + wire_main_functs(); + msg->msg=-2; + } + } + +void GamePause() + { + int i; + unwire_proc(); + send_message(E_ADD,E_KEYBOARD,GameResume); + update_mysky(); + schovej_mysku(); + trans_bar(0,0,640,480,0); + set_font(H_FBOLD,RGB555(0,23,0)); + i=text_width(texty[5]); + add_window(320-(i/2)-10,100,i+40,40,H_IDESKA,4,20,20); + redraw_window(); + set_aligned_position(320,115,1,1,texty[5]); + outtext(texty[5]); + ukaz_mysku(); + showview(0,0,0,0); + cancel_render=1; + } + +/*void user_setup() + { + + initmode256(cur_xlat); + init_mysky(); + hranice_mysky(0,0,639,479); + mouse_set_default(H_MS_DEFAULT); + ukaz_mysku(); + setup_dialoge(); + escape(); + schovej_mysku(); + closemode(); + } + */ diff --git a/GAME/SKELDAL.C b/GAME/SKELDAL.C new file mode 100644 index 0000000..24e8d88 --- /dev/null +++ b/GAME/SKELDAL.C @@ -0,0 +1,1755 @@ +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "globals.h" +#include "engine1.h" +#include "wizard.h" +#include "version.h" +#include + +#define CONFIG_NAME SKELDALINI + +#define INI_TEXT 1 +#define INI_INT 2 + +#define ERR_GENERAL 1 +char def_path[]=""; +char graph_path[]="graphics\\"; +char basc_graph[]="graphics\\basic\\"; +char item_graph[]="graphics\\items\\"; +char sample_path[]="samples\\"; +char font_path[]="font\\"; +char map_path[]="maps\\"; +char music_path[]="music\\"; +char org_music_path[]="music\\"; +char temp_path[]="?"; +char enemies_path[]="graphics\\enemies\\"; +char video_path[]="video\\"; +char dialogs_path[]="graphics\\dialogs\\"; +char saves_path[]=""; +char work_path[]=""; +char cd_path[]=""; +char map2_path[]=""; +char plugins_path[]=""; +char *pathtable[]={def_path,graph_path,sample_path,font_path,map_path,music_path,temp_path,basc_graph,item_graph,enemies_path,video_path,dialogs_path,saves_path,work_path,cd_path,map2_path,plugins_path,org_music_path}; + +/* +char *pathtable[]= + {"", + "graphics\\", + "graphics\\basic\\", + "graphics\\items\\", + "samples\\", + "font\\", + "maps\\", + "music\\", + "", + "graphics\\enemies\\", + "video\\", + "graphics\\dialogs\\" + }; +*/ + +char **texty; + +char skip_intro=0; +char autosave_enabled=0; +long game_time=0; +int charmin=3; +int charmax=3; + +int autoopenaction=0; +int autoopendata=0; + +void *cur_xlat; + +void redraw_desktop_call(); + +TMA_LOADLEV loadlevel; + +typedef struct inis + { + char heslo[15]; + char parmtype; + }INIS; + +THE_TIMER timer_tree; + + +int hl_ptr=H_FIRST_FREE; +int debug_enabled=0; +char sound_detection=1; +int snd_devnum,snd_parm1,snd_parm2,snd_parm3,snd_mixing=22000; +char gamespeed=6; +char gamespeedbattle=0; +char level_preload=1; +char *level_fname=NULL; +int game_extras=0; + +char default_map[20]="LESPRED.MAP"; + +THUMAN postavy[POCET_POSTAV],postavy_save[POCET_POSTAV]; +void (*unwire_proc)(); +void (*wire_proc)(); +char cur_mode,battle_mode; +static init_music_vol=127,init_gfx_vol=255; +static char full_video=0; +static char titles_on=0; +static char windowed=0; +static char windowedzoom=1; +static char monitor=0; +static int refresh=0; + +void pcx_fade_decomp(void **p,long *s); +void pcx_15bit_decomp(void **p,long *s); +void pcx_15bit_autofade(void **p,long *s); +void pcx_15bit_backgrnd(void **p,long *s); +void pcx_8bit_decomp(void **p,long *s); + +char *texty_knihy; +static char *patch_file=NULL; +int cur_page=0; + +TSTR_LIST cur_config=NULL; + +TDREGISTERS registred[]= + { + {H_DESK,"desk.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_TOPBAR,"topbar.pcx",pcx_15bit_decomp,SR_BGRAFIKA}, + {H_OKNO,"okno.pcx",pcx_15bit_decomp,SR_BGRAFIKA}, + {H_MS_DEFAULT,"msc_sip.pcx", pcx_8bit_decomp,SR_BGRAFIKA}, + {H_MS_SOUBOJ,"msc_x.pcx", pcx_8bit_decomp,SR_BGRAFIKA}, + {H_MS_WHO,"msc_who.pcx", pcx_8bit_decomp,SR_BGRAFIKA}, +// {H_MS_LIST,"msc_list.pcx", pcx_8bit_decomp,SR_BGRAFIKA}, + {H_MS_ZARE,"msc_zare.pcx", pcx_8bit_decomp,SR_BGRAFIKA}, + {H_KOMPAS,"kompas.pcx", pcx_15bit_decomp,SR_BGRAFIKA}, + {H_SIPKY_S,"sipky_s.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_SIPKY_SV,"sipky_sv.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_SIPKY_SZ,"sipky_sz.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_SIPKY_V,"sipky_v.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_SIPKY_Z,"sipky_z.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_SIPKY_J,"sipky_j.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_BACKMAP,"backmap.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_FBOLD,"sada16.fon",NULL,SR_FONT}, + {H_FSYMB,"ikones.fon",NULL,SR_FONT}, + {H_FLITT,"font4x8.fon",NULL,SR_FONT}, + {H_FLITT5,"font5x8.fon",NULL,SR_FONT}, + {H_FONT6,"font6x9.fon",NULL,SR_FONT}, + {H_FONT7,"sada7.fon",NULL,SR_FONT}, + {H_FTINY,"tiny.fon",NULL,SR_FONT}, + {H_FKNIHA,"kniha.fon",NULL,SR_FONT}, + {H_FBIG,"timese.fon",NULL,SR_FONT}, + {H_IOBLOUK,"ioblouk.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_LODKA,"lodka.pcx",pcx_15bit_decomp,SR_BGRAFIKA}, + {H_IDESKA,"ideska.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_IMRIZ1,"imriz1.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_RAMECEK,"ramecek.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_ENEMY,"enemy.dat",NULL,SR_MAP}, + {H_BATTLE_BAR,"souboje.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_BATTLE_MASK,"m_souboj.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_MZASAH1,"mzasah1.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_MZASAH2,"mzasah2.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_MZASAH3,"mzasah3.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_PZASAH,"pzasah.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_BATTLE_CLICK,"souboje2.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_SIPKY_END,"sipky.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_KOUZLA,"kouzla.dat",NULL,SR_MAP}, + {H_LEBKA,"death.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_KOSTRA,"bones.pcx",pcx_fade_decomp,SR_BGRAFIKA}, + {H_RUNEHOLE,"runehole.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_RUNEMASK,"runemask.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_POWERBAR,"powerbar.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_POWERLED,"powerled.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_POSTAVY_DAT,"postavy.dat",NULL,SR_MAP}, + {H_SOUND_DAT,"sound.dat",NULL,SR_MAP}, + {H_SND_SWHIT1,"swd_hit0.wav",wav_load,SR_ZVUKY}, + {H_SND_SWHIT2,"swd_hit1.wav",wav_load,SR_ZVUKY}, + {H_SND_SWMISS1,"swd_mis0.wav",wav_load,SR_ZVUKY}, + {H_SND_SWMISS2,"swd_mis1.wav",wav_load,SR_ZVUKY}, + {H_SND_SIP1,"sip2.wav",wav_load,SR_ZVUKY}, + {H_SND_SIP2,"sip1.wav",wav_load,SR_ZVUKY}, + {H_SND_KNIHA,"kniha.wav",wav_load,SR_ZVUKY}, + {H_SND_OBCHOD,"obchod.wav",wav_load,SR_ZVUKY}, + {H_SND_LEKTVAR,"lektvar.wav",wav_load,SR_ZVUKY}, + {H_SND_TELEPIN,"telepin.wav",wav_load,SR_ZVUKY}, + {H_SND_TELEPOUT,"telepout.wav",wav_load,SR_ZVUKY}, + {H_SND_HEK1M,"jauu1m.wav",wav_load,SR_ZVUKY}, + {H_SND_HEK2M,"jauu2m.wav",wav_load,SR_ZVUKY}, + {H_SND_HEK1F,"jauu1f.wav",wav_load,SR_ZVUKY}, + {H_SND_HEK2F,"jauu2f.wav",wav_load,SR_ZVUKY}, + {H_SND_EAT,"jidlo.wav",wav_load,SR_ZVUKY}, + {H_SND_WEAR,"obleci.wav",wav_load,SR_ZVUKY}, + {H_SND_PUTINV,"put_inv.wav",wav_load,SR_ZVUKY}, + {H_RUNEBAR1,"r_ohen.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_RUNEBAR2,"r_voda.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_RUNEBAR3,"r_zeme.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_RUNEBAR4,"r_vzduch.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_RUNEBAR5,"r_mysl.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_SPELLDEF,"spelldef.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_KNIHA,"kniha.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_WINTXTR,"wintxtr.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_SAVELOAD,"saveload.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_SVITEK,"svitek.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_LOADTXTR,"loadtxtr.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_DIALOG,"dialog.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_DIALOGY_DAT,"dialogy.dat",NULL,SR_MAP}, + {H_SHOP_PIC,"shop.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_TELEPORT,"teleport.mgf",NULL,SR_BGRAFIKA}, + {H_FX,"fx.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_CHECKBOX,"checkbox.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_SETUPBAR,"volbades.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_SOUPAK,"volbasou.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_SETUPOK,"volbazpe.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_POSTUP,"postup.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_LODKA0,"lesda21a.pcx",pcx_fade_decomp,SR_GRAFIKA}, + {H_LODKA1,"lesda22a.pcx",pcx_fade_decomp,SR_GRAFIKA}, + {H_LODKA2,"lesda23a.pcx",pcx_fade_decomp,SR_GRAFIKA}, + {H_LODKA3,"lesda24a.pcx",pcx_fade_decomp,SR_GRAFIKA}, + {H_LODKA4,"lesda25a.pcx",pcx_fade_decomp,SR_GRAFIKA}, + {H_LODKA5,"lesda26a.pcx",pcx_fade_decomp,SR_GRAFIKA}, + {H_LODKA6,"lesda27a.pcx",pcx_fade_decomp,SR_GRAFIKA}, + {H_LODKA7,"lesda28a.pcx",pcx_fade_decomp,SR_GRAFIKA}, + {H_FLETNA,"fletna.wav",wav_load,SR_ZVUKY}, + {H_FLETNA_BAR,"stupnice.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_FLETNA_MASK,"stupni_m.pcx",pcx_8bit_nopal,SR_BGRAFIKA}, + {H_SND_SEVER,"sever.wav",wav_load,SR_ZVUKY}, + {H_SND_VYCHOD,"vychod.wav",wav_load,SR_ZVUKY}, + {H_SND_JIH,"jih.wav",wav_load,SR_ZVUKY}, + {H_SND_ZAPAD,"zapad.wav",wav_load,SR_ZVUKY}, + {H_SND_RAND1,"random1.wav",wav_load,SR_ZVUKY}, + {H_SND_RAND2,"random2.wav",wav_load,SR_ZVUKY}, + {H_SND_RAND3,"random3.wav",wav_load,SR_ZVUKY}, + {H_SND_RAND4,"random4.wav",wav_load,SR_ZVUKY}, + {H_CHARGEN,"chargen.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_CHARGENB,"chargenb.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_CHARGENM,"chargenm.pcx",pcx_8bit_nopal,SR_BGRAFIKA}, + {H_BGR_BUFF,"",set_background,SR_BGRAFIKA}, + {H_KREVMIN,"krevmin.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_KREVMID,"krevmid.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + {H_KREVMAX,"krevmax.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, + + }; + +INIS sinit[]= + { + {"VMODE",INI_INT}, + {"ZOOM_SPEED",INI_INT}, + {"TURN_SPEED",INI_INT}, + {"MUSIC_VOLUME",INI_INT}, + {"SOUND_VOLUME",INI_INT}, + {"SOUND_DEVICE",INI_TEXT}, + {"SOUND_MIXFREQ",INI_INT}, + {"DEFAULT_MAP",INI_TEXT}, + {"GAME_SPEED",INI_INT}, + {"PRELOAD",INI_INT}, + {"INSTALL",INI_TEXT}, + {"PATCH",INI_INT}, + {"SKIP_INTRO",INI_INT}, + {"AUTOSAVE",INI_INT}, + {"DEBUG",INI_INT}, + {"FULLRESVIDEO",INI_INT}, + {"PATCH_FILE",INI_TEXT}, + {"TITLES",INI_INT}, + {"CHAR_MIN",INI_INT}, + {"CHAR_MAX",INI_INT}, + {"EXTRAS",INI_INT}, + {"WINDOWED", INI_INT}, + {"BATTLE_ACCEL",INI_INT}, + {"WINDOWEDZOOM", INI_INT}, + {"MONITOR",INI_INT}, + {"VERSION",INI_INT}, + {"REFRESHRATE",INI_INT}, + {"CESTA_DATA",INI_TEXT}, + {"CESTA_GRAFIKA",INI_TEXT}, + {"CESTA_ZVUKY",INI_TEXT}, + {"CESTA_FONTY",INI_TEXT}, + {"CESTA_MAPY",INI_TEXT}, + {"CESTA_MUSIC",INI_TEXT}, + {"CESTA_TEMPY",INI_TEXT}, + {"CESTA_BGRAFIKA",INI_TEXT}, + {"CESTA_ITEMY",INI_TEXT}, + {"CESTA_ENEMY",INI_TEXT}, + {"CESTA_VIDEO",INI_TEXT}, + {"CESTA_DIALOGY",INI_TEXT}, + {"CESTA_POZICE",INI_TEXT}, + {"CESTA_HLAVNI",INI_TEXT}, + {"CESTA_CD",INI_TEXT}, + {"CESTA_MAPY2",INI_TEXT}, + {"CESTA_PLUGINS",INI_TEXT}, + {"CESTA_ORIG_MUSIC",INI_TEXT} + }; + + +#define CESTY_POS 27 +int last_ms_cursor=-1; +int vmode=2; + +int set_video(int mode) + { + int er=0; + + report_mode(1); + er=initmode_dx(windowed,windowedzoom,monitor,refresh); +/* + switch(mode) + { + case 1:er=initmode256(cur_xlat); + if (banking) report_mode(5); else report_mode(2); + SEND_LOG("(GAME) Video changed to 256 colors %s",banking?"Bank":"LFB",0); + break; + case 2:er=initmode32(); + if (banking) report_mode(4); else report_mode(1); + SEND_LOG("(GAME) Video changed to HIcolor %s",banking?"Bank":"LFB",0); + break; + case 0:er=initmode_lo(cur_xlat); + report_mode(3); + SEND_LOG("(GAME) Video changed to 256 VGA comp. ",0,0); + break; + case 3: free(cur_xlat);cur_xlat=create_blw_palette16(); + er=initmode16(cur_xlat); + SEND_LOG("(GAME) Video changed to 16 grayscale",0,0); + report_mode(3); + break; + case 4:er=init_empty_mode(); + report_mode(3); + SEND_LOG("(GAME) Video changed to ",0,0); + break; + case 5:free(cur_xlat);cur_xlat=create_hixlat(); + er=initmode64(cur_xlat); + if (banking) report_mode(7); else report_mode(6); + SEND_LOG("(GAME) Video changed to HIcolor64 %s",banking?"Bank":"LFB",0); + break; + + default:er=-1; + }*/ + screen_buffer_size=scr_linelen*480; + return er; + } + +int ask_video() + { + int c; + printf("\nJaky videomode?:\n" + " 1) 640x480x256 \n" + " 2) 640x480xHiColor \n"); + c=_bios_keybrd(_KEYBRD_READ)>>8; + if (c==1) exit(0); + return c-1; + } + +void pcx_fade_decomp(void **p,long *s) + { + char *buff; + load_pcx(*p,*s,A_FADE_PAL,&buff,mglob.fade_r,mglob.fade_g,mglob.fade_b); + *s=_msize(buff); + free(*p); + *p=buff; + } + +void pcx_15bit_decomp(void **p,long *s) + { + char *buff; + load_pcx(*p,*s,A_16BIT,&buff); + *s=_msize(buff); + free(*p); + *p=buff; + } + +void pcx_15bit_autofade(void **p,long *s) + { + char *buff; + load_pcx(*p,*s,A_16BIT,&buff); + *s=_msize(buff); + free(*p); + *p=buff; + buff[5]=0x80; + } + +void pcx_15bit_backgrnd(void **p,long *s) + { + char *buff; + long i;long *z; + + if (*p!=NULL) + { + load_pcx(*p,*s,A_16BIT,&buff); + z=(long *)buff; + *s=_msize(buff); + for(i=*s;i>0;i-=4,z++) *z|=0x80008000; + free(*p); + *p=buff; + } + } + +void pcx_8bit_nopal(void **p,long *s) + { + char *buff; + + if (*p!=NULL) + { + load_pcx(*p,*s,A_8BIT_NOPAL,&buff); + *s=_msize(buff); + free(*p); + *p=buff; + } + } + + +void pcx_8bit_decomp(void **p,long *s) + { + char *buff; + load_pcx(*p,*s,A_8BIT,&buff); + *s=_msize(buff); + free(*p); + *p=buff; + } + +void hi_8bit_correct(void **p,long *s) +{ + word *ptr=(word *)*p; + int i; + if (ptr[2]==8) + { + for (i=0;i<256;i++) + { + ptr[i+3]=((ptr[i+3] & ~0x1F)+ptr[i+3]); + } + } +} + + +void set_background(void **p,long *s) + { + word *data; + word *ptr; + word *pal; + char *pic; + int counter; + + if (!bgr_handle) return; + if (bgr_distance==-1) return; + data=ablock(bgr_handle); + *s=scr_linelen2*360*2; + ptr=*p=getmem(*s); + counter=scr_linelen2*360; + pal=data+3+bgr_distance*256; + pic=(char *)data+PIC_FADE_PAL_SIZE; + do + *ptr++=pal[*pic++] | BGSWITCHBIT; + while (--counter); + } + +void mouse_set_cursor(int cursor) + { + static short *ms_item=NULL; + + if (cursor==last_ms_cursor) return; + if (last_ms_cursor>0) aunlock(last_ms_cursor); + if (cursor>0) + { + alock(cursor); + schovej_mysku(); + register_ms_cursor(ablock(cursor)); + last_ms_cursor=cursor; + set_ms_finger(0,0); + ukaz_mysku(); + } + else + { + char *p; + + cursor=-cursor; + if (ms_item==NULL) ms_item=(short *)getmem(IT_ICONE_SIZE); + p=(char *)ablock(cursor/18+ikon_libs); + memcpy(ms_item,&p[(cursor%18)*IT_ICONE_SIZE],IT_ICONE_SIZE); + schovej_mysku(); + register_ms_cursor(ms_item); + set_ms_finger(45/2,55/2); + last_ms_cursor=-cursor; + ukaz_mysku(); + } + } + +void mouse_set_default(int cursor) + { + default_ms_cursor=cursor; + mouse_set_cursor(cursor); + } + +void set_font(int font,int c1,...) + { + static int last_font=-1; + int i; + + if (last_font!=-1 && last_font!=font) + { + aunlock(last_font); + alock(font); + } + curfont=ablock(font); + if (c1>=0) + if (c1 & BGSWITCHBIT) + { + charcolors[0]=0xFFFF; + for (i=1;i<5;i++) charcolors[i]=c1 & ~0x20; + } + else + { + charcolors[0]=0; + for (i=1;i<5;i++) charcolors[i]=c1 & ~0x20; + } + else if (c1==-2) + { + int *p; + + p=&c1;p++; + for (i=0;i<5;i++) charcolors[i]=*p++; + } + last_font=font; + default_font=curfont; + memcpy(f_default,charcolors,sizeof(charcolors)); + } + +void music_init() + { + char *path; +/* if (sound_detection) + { + SEND_LOG("(SOUND) SOUND_DETECT Detecting sound card",0,0); + if (sound_detect(&snd_devnum,&snd_parm1,&snd_parm2,&snd_parm3)) snd_devnum=DEV_NOSOUND; + }*/ + SEND_LOG("(SOUND) SOUND_SET Setting Sound: Device '%s' Port: %3X",device_name(snd_devnum),snd_parm1); + SEND_LOG("(SOUND) SOUND_SET Setting Sound: IRQ: %X DMA: %X",snd_parm2,snd_parm3); + set_mixing_device(snd_devnum,snd_mixing,snd_parm1,snd_parm2,snd_parm3); + SEND_LOG("(SOUND) SOUND_INIT Starting mixing",0,0); + start_mixing(); + set_snd_effect(SND_GFX,init_gfx_vol); + set_snd_effect(SND_MUSIC,init_music_vol); + path=plugins_path; + if (path==0 || path[0]==0) + path=AutodetectWinAmp(); + if (path!=0 && path[0]!=0) + { + SEND_LOG("(SOUND) Installing plugins, path: %s",path,0); + init_winamp_plugins(path); + if (path!=plugins_path) free(path); + } + SEND_LOG("(SOUND) SOUND_DONE Sound Engine should work now",0,0); + + } + +void clrscr() + { + + } + + + + +void purge_temps(char z) + { + HANDLE rc; + WIN32_FIND_DATA fi; + char c[200]; + + + strcpy(c,SWAPPATH); + strcat(c,"*.TMP"); + rc=FindFirstFile(c,&fi); + if (rc!=INVALID_HANDLE_VALUE) + do + { + strcpy(c,SWAPPATH); + strcat(c,fi.cFileName); + if (fi.cFileName[0]!='~') + { + SEND_LOG("(PURGE) Purging temp '%s'",c,0); + remove(c); + } + } + while (FindNextFile(rc,&fi)); + FindClose(rc); + + if (z) + { + strcpy(c,SWAPPATH); + strcat(c,TEMP_FILE); + SEND_LOG("(PURGE) Purging temp '%s'",c,0); + remove(c); + } + + } + + + +void back_music() + { + mix_back_sound(0); + } + +/*void *anim_idle(EVENT_MSG *msg,void **usr) + { + usr; + if (msg->msg==E_TIMER) calc_animations(); + return &anim_idle; + }*/ + +/*void timer_error() + { + puts("\x7"); + } +*/ +void *timming(EVENT_MSG *msg,void **data) + { + THE_TIMER *p,*q; + int i,j; + + data; + if (msg->msg==E_INIT) return &timming; + *otevri_zavoru=1; + j=*(int *)msg->data; + for (i=0;inext; + while (q!=NULL) + { + p=q->next; +// if (p!=NULL && p->zero!=0) timer_error(); + if (!(--q->counter)) + if (q->zavora && i==(j-1)) + { + q->zavora=0; + if (q->calls!=-2) q->proc(q); + p=q->next; + q->zavora=1; + q->counter=q->count_max; + if (q->calls!=-1) + if (--q->calls<1) + { + for(p=&timer_tree;p->next!=q;p=p->next); + p->next=q->next; + #ifdef LOGFILE + if (q->next==NULL) + SEND_LOG("(TIMER) Self remove for timer id: %d, next->",q->id,0); + else + SEND_LOG("(TIMER) Self remove for timer id: %d, next->%d",q->id,q->next->id); + #endif + free(q); + q=p; + } + //else + // q->counter=1; + } + else + q->counter=1; + if (q->next!=p && q!=p) + { + THE_TIMER *z; + SEND_LOG("(TIMER) Timer integrity corrupted",0,0); + z=&timer_tree;while(z->next!=p && z->next!=NULL) z=z->next; + if (z->next==NULL) return NULL; + } + q=p; + } + } + return NULL; + } + +void delete_from_timer(int id) + { + THE_TIMER *p,*q; + + p=&timer_tree; + q=p->next; + while (q!=NULL) + { + if (q->id==id) + { + if (q->zavora) + { + #ifdef LOGFILE + if (q->next==NULL) + SEND_LOG("(TIMER) Removing timer id: %d, next->",id,0); + else + SEND_LOG("(TIMER) Removing timer id: %d, next->%d",id,q->next->id); + #endif + p->next=q->next; + free(q); + q=p; + } + else + { + SEND_LOG("(TIMER) Can't remove timer! id: %d. Currently in use.",id,0); + q->calls=-2; + q->counter=1; + } + } + p=q;q=q->next; + } + } + +THE_TIMER *find_timer(int id) + { + THE_TIMER *p; + + p=timer_tree.next; + while (p!=NULL && p->id!=id) p=p->next; + return p; + } + + +void hold_timer(int id,char hld) + { + THE_TIMER *q; + + q=timer_tree.next; + while (q!=NULL && q->id!=id) q=q->next; + if (q!=NULL) q->counter=1-(hld<<1); + SEND_LOG("(TIMER) Timer hold id: %d status: %s",id,hld?"Hold":"Unhold"); + } + +THE_TIMER *add_to_timer(int id,int delay,int maxcall,void *proc) + { + THE_TIMER *q; + +// if (id==2 && marker && timer_tree.next->id==2) +// MARKER_HIT(timer_error()); + q=(THE_TIMER *)getmem(sizeof(THE_TIMER)); + q->counter=q->count_max=delay; + q->calls=maxcall; + q->proc=proc; + q->id=id; + q->next=timer_tree.next; + q->zavora=1; + q->zero=0; + timer_tree.next=q; + SEND_LOG("(TIMER) Adding to timer id: %d delay: %d",id,delay); + return q; + } + +static void kill_timer() + { + THE_TIMER *t; + + t=timer_tree.next; + while (t!=NULL) + { + THE_TIMER *p; + + p=t;t=t->next;free(p); + } + timer_tree.next=NULL; + } + +void *user_timer(EVENT_MSG *msg,void **usr) + { + int x; + static int lastvalue=0; + usr; + if (msg->msg==E_WATCH) + { + *otevri_zavoru=1; + x=get_timer_value(); + x-=lastvalue; + lastvalue+=x; + if (x) send_message(E_TIMER,x); + } + return &user_timer; + } + +void do_timer() + { + EVENT_MSG msg; + char x; + + msg.msg=E_IDLE; + otevri_zavoru=&x; + user_timer(&msg,NULL); + } + +void done_skeldal(void) + { + + SEND_LOG("(GAME) Video returned to textmode",0,0); + close_manager(); + close_story_file(); + purge_temps(1); + stop_mixing(); +// deinstall_mouse_handler(); + if (texty!=NULL) release_list(texty);texty=NULL; + if (cur_config!=NULL) release_list(cur_config);cur_config=NULL; + kill_timer(); + SEND_LOG("NORMAL TERMINATING--------------------------",0,0); + } + + +int cislovka(int i) + { + if (i==1) return 0; + if (i>1 && i<5) return 1; + return 2; + } + +void register_basic_data() + { + int i,s; + TDREGISTERS *p; + char xname[16]; + + s=sizeof(registred)/sizeof(TDREGISTERS); + p=registred; + for(i=0;ih_num,p->name,p->proc,p->path); + def_handle(H_BOTTBAR,"",bott_draw_proc,0); + for(i=0;imsg==E_KEYBOARD) + { + c=(*(int *)msg->data)>>8; + if (c==';') save_dump(); + } + return; + } + +void add_game_window() + { + WINDOW *p; + CTL3D *c; + + c=def_border(0,0); + p=create_window(0,0,0,0,0,c); + desktop_add_window(p); + } + + + +void error_exception(EVENT_MSG *msg,void **unused) + { + if (msg->msg==E_PRGERROR) + { + unused; + SEND_LOG("(ERROR) Runtime error detected ... Game terminator lunched.",0,0); + SEND_LOG("(ERROR) Log: Now dump of useful informations:",0,0); + SEND_LOG("(ERROR) Log: Map name '%s'",level_fname==NULL?"":level_fname,0); + SEND_LOG("(ERROR) Log: Sector %d Direction %d",viewsector,viewdir); + SEND_LOG("(ERROR) Log: Last 'memman' handle: %x",memman_handle,0); + SEND_LOG("(ERROR) Log: Battle: %d Select_player %d",battle,select_player); + closemode(); + printf("Program zpsobil bhovou chybu a bude ukonen\n" + "Posledn zpracovvan data mla rukoje slo %xh\n",memman_handle); + printf("Map: %s Sector %d Direction %d\n",level_fname==NULL?"":level_fname,viewsector,viewdir); + printf("Nyn se program pokus uloit hru...\n\n"); + autosave_enabled=1; + autosave(); + printf("Hra byla spn uloena pod nzvem AUTOSAVE\n"); + exit(0); + } + } + +void swap_error_exception() + { + closemode(); + SEND_LOG("(ERROR) Disk is full ...",0,0); + puts("Program jiz nema kam odkladat, protoze disk s odkladacim souborem byl \n" + "zaplnen. Uvolnete prosim nejake misto na odkladacim disku, nebo zmente \n" + "adresar odkladani na jednotku, kde je vice mista"); + puts("Vase pozice bude ulozena pod nazvem AUTOSAVE\n" + "Pokud vsak mate pozice na stejnm disku jako odkladaci soubor (coz je\n" + "zakladni nastaveni) bude ulozeni z 90% bohuzel neuspesne..."); + autosave_enabled=1; + autosave(); + exit(0); + } + +void *boldcz; + +#define ERR_WINX 320 +#define ERR_WINY 100 + +/* + +char device_error(int chyba,char disk,char info) + { + char c; + void *old; + + old=_STACKLOW; + _STACKLOW=NULL; + chyba,disk,info; + curfont=&boldcz; + charcolors[0]=0xffff; + for(c=1;c<5;c++) charcolors[c]=0x7fff; + memcpy(buffer_2nd,screen,screen_buffer_size); + trans_bar(320-ERR_WINX/2,240-ERR_WINY/2,ERR_WINX,ERR_WINY,0); + curcolor=0x7fff; + rectangle(320-ERR_WINX/2,240-ERR_WINY/2,320+ERR_WINX/2,240+ERR_WINY/2,0x7fff); + set_aligned_position(320,230,1,1,texty[8]);outtext(texty[8]); + set_aligned_position(320,250,1,1,texty[9]);outtext(texty[9]); + showview(0,0,0,0); + do + { + c=getche(); + } + while (c!=13 && c!=27); + memcpy(screen,buffer_2nd,screen_buffer_size); + showview(0,0,0,0); + _STACKLOW=old; + return (c==13?_ERR_RETRY:_ERR_FAIL); + } +*/ +static void patch_error(int err) + { + position(0,460); + curcolor=0;bar(0,460,640,479); + memcpy(charcolors,flat_color(RGB555(31,31,31)),sizeof(charcolors)); + curfont=boldcz; + switch(err) + { + case 0:outtext("File has been patched: ");outtext(patch_file);break; + case 1:outtext("Patch error within file: ");outtext(patch_file);break; + case 2:outtext("Cannot patch");break; + case 3:outtext("Missing or error in main data file, patching ingnored!");break; + break; + } + showview(0,460,640,20); + } + +void init_skeldal(void) + { + char c[200],d[200]; + int verr; + + boldcz=LoadDefaultFont(); +SEND_LOG("(INIT) Reading texts.",0,0); + cti_texty(); + timer_tree.next=NULL; +SEND_LOG("(INIT) Setting random seed.",0,0); + srand(clock()); +SEND_LOG("(INIT) Creating 256 color palette.",0,0); + cur_xlat=create_special_palette(); +SEND_LOG("(INIT) Init message system - event handler",0,0); + init_events(100); +SEND_LOG("(INIT) Setting videomode.",0,0); + verr=set_video(vmode); + if (verr) + { + exit(ERR_GENERAL); + } +SEND_LOG("(INIT) Initializing engine.",0,0); + general_engine_init(); + atexit(done_skeldal); +/*SEND_LOG("(INIT) Loading DOS error handler.",0,0); + install_dos_error(device_error,(char *)getmem(4096)+4096);*/ + swap_error=swap_error_exception; + sprintf(c,"%s%s",SWAPPATH,TEMP_FILE); + sprintf(d,"%s%s",pathtable[SR_DATA],"skeldal.ddl"); +SEND_LOG("(INIT) Initializing memory manager",0,0); + init_manager(d,c); +SEND_LOG("(GAME) Memory manager initialized. Using DDL: '%s' Temp dir: '%s'",d,c); + texty_knihy=find_map_path("kniha.txt"); +SEND_LOG("(INIT) Installing GUI",0,0); + install_gui(); +SEND_LOG("(INIT) Attaching patch.",0,0); + if (patch_file!=NULL) patch_error(add_patch_file(patch_file)); +SEND_LOG("(INIT) Registring basic data.",0,0); + register_basic_data(); +SEND_LOG("(INIT) Timer event handler.",0,0); + send_message(E_DONE,E_WATCH,timer); + send_message(E_DONE,E_IDLE,redraw_desktop_call); + send_message(E_ADD,E_TIMER,timming); +SEND_LOG("(INIT) User timer.",0,0); + send_message(E_ADD,E_WATCH,user_timer); +SEND_LOG("(INIT) Mouse clicking maps.",0,0); + send_message(E_ADD,E_MOUSE,ms_clicker); +SEND_LOG("(INIT) Global keyboard event handler.",0,0); + send_message(E_ADD,E_KEYBOARD,global_kbd); +SEND_LOG("(INIT) Error exception event handler.",0,0); + send_message(E_ADD,E_PRGERROR,error_exception); +SEND_LOG("(INIT) Wizard handler.",0,0); + if (debug_enabled) install_wizard(); +SEND_LOG("(INIT) Background music timer.",0,0); + add_to_timer(TM_BACK_MUSIC,5,-1,back_music); +SEND_LOG("(INIT) Creating game window.",0,0); + add_game_window(); +SEND_LOG("(INIT) Music.",0,0); + music_init(); +SEND_LOG("(INIT) Mouse interrupt handler.",0,0); + if ((verr=init_mysky())!=0) + { + closemode(); + puts(texty[174-verr]); + SEND_LOG("(ERROR) %s (%d)",texty[174-verr],verr); + SEND_LOG("(ERROR) Mouse not found, shutting down.",0,0); + exit(0); + } +SEND_LOG("(INIT) Mouse initialized.",0,0); +// hranice_mysky(0,0,639,479); +SEND_LOG("(INIT) Loading mouse cursor.",0,0); + mouse_set_default(H_MS_DEFAULT); + ukaz_mysku(); + konec_skladby=play_next_music; +SEND_LOG("(INIT) Loading spells.",0,0); + kouzla_init(); +SEND_LOG("(INIT) Loading items.",0,0); + load_items(); +SEND_LOG("(INIT) Loading shops.",0,0); + load_shops(); + SetWheelMapping('H','P'); + } + +void wire_main_functs(); +void unwire_main_functs() + { + SEND_LOG("(SYS) Wire main functions",0,0); + delete_from_timer(TM_FLY); + delete_from_timer(TM_SCENE); + delete_from_timer(TM_REGEN); + send_message(E_DONE,E_KEYBOARD,game_keyboard); + send_message(E_DONE,E_KROK,real_krok); + disable_click_map(); + cancel_render=1; + wire_proc=wire_main_functs; + } + + +void wire_main_functs() + { + SEND_LOG("(SYS) unWire main functions",0,0); + add_to_timer(TM_SCENE,gamespeed,-1,refresh_scene); + add_to_timer(TM_FLY,gamespeed,-1,calc_fly); + add_to_timer(TM_REGEN,500,-1,real_regeneration); + send_message(E_ADD,E_KEYBOARD,game_keyboard); + send_message(E_ADD,E_KROK,real_krok); + change_click_map(clk_main_view,CLK_MAIN_VIEW); + unwire_proc=unwire_main_functs; + cur_mode=MD_GAME; + running_battle=0; + recalc_volumes(viewsector,viewdir); + cancel_pass=1; + } + + +void init_game() + { + SEND_LOG("(INIT) Inventory.",0,0); + init_inventory(); + SEND_LOG("(INIT) Characters.",0,0); + reg_grafiku_postav(); + build_all_players(); + } + +void *map_keyboard(EVENT_MSG *msg,void **usr); + +char doNotLoadMapState=0; + +static reload_map_handler(EVENT_MSG *msg,void **usr) +{ +extern char running_battle; + if (msg->msg==E_RELOADMAP) + { + int i; + va_list list=msg->data; + const char *fname=va_arg(list,const char *); + int sektor=va_arg(list,int); + strncpy(loadlevel.name,fname,sizeof(loadlevel.name)); + loadlevel.start_pos=sektor; + for(i=0;i \n\n" + " jmeno mapy\n" + " Cislo startovaciho sektoru\n" + ); + exit(0); + } + +extern char nofloors; + +/* +void set_verify(char state); +#pragma aux set_verify parm [eax]=\ + "mov ah,2eh"\ + "int 21h" +*/ +void play_movie_seq(char *s,int y) + { + int hic=full_video?SMD_HICOLOR+128:SMD_HICOLOR,cc=full_video?SMD_256+128:SMD_256; + word *lbuffer=GetScreenAdr(); + set_play_attribs(lbuffer,0,banking,vmode==5); + switch (vmode) + { + case 1:if (!banking) + play_animation(s,cc,y,snd_devnum!=DEV_NOSOUND); + else + { + set_play_attribs(GetScreenAdr(),1,0,vmode==5); + play_animation(s,hic,y,snd_devnum!=DEV_NOSOUND); + } + break; + case 5: + case 2:play_animation(s,hic,y,snd_devnum!=DEV_NOSOUND);break; + default: set_play_attribs(GetScreenAdr(),1,0,vmode==5); + play_animation(s,hic,y,snd_devnum!=DEV_NOSOUND);break; + } + } + + +void play_anim(int anim_num) + { + char *s; + char *t,*z; + TSTR_LIST titl=NULL; + concat(s,pathtable[SR_VIDEO],texty[anim_num]); + if (snd_devnum==DEV_NOSOUND || titles_on) + { + concat(t,s," "); + z=strrchr(t,'.'); + if (z!=NULL) + { + strcpy(z,".TXT"); + if (load_string_list_ex(&titl,t)) titl=NULL; + } + else titl=NULL; + } + else titl=NULL; + set_title_list(titl);set_font(H_FBIG,RGB(200,200,200)); + curcolor=0;bar(0,0,639,459); + showview(0,0,0,0); + play_movie_seq(s,60); + set_title_list(NULL);if (titl!=NULL) release_list(titl); + } + + +/*main(int argc,char *argv[]) + { + int err;int sect;int dir=0; + + //if (argc<2) help(); + + dir; + set_verify(0); + mman_pathlist=&pathtable; + //nofloors=1; + zoom_speed(1); + turn_speed(1); + configure("skeldal.ini",config_skeldal); + purge_temps(1); + textmode_effekt(); + clrscr(); + init_skeldal(); + enter_menu(); + if (argc<2) + { + invex_anim(); + // send_message(E_ADD,E_MOUSE,waiter); + // send_message(E_ADD,E_KEYBOARD,waiter); + // add_to_timer(TM_WAITER,1,-1,timer_waiter); + strncpy(loadlevel.name,default_map,12); + } + else strncpy(loadlevel.name,argv[1],12); + err=load_map(loadlevel.name); + if (argc>=3) sscanf(argv[2],"%d",§); + else + { + sect=mglob.start_sector; + dir=mglob.direction; + } + loadlevel.start_pos=sect; + loadlevel.dir=dir; + init_game(); + while (loadlevel.name[0]) + { + if (err) + { + closemode(); + switch (err) + { + case -1: printf("Error while loading map....file not found\n");break; + case -2: printf("Missing -1 at the end of map string table");break; + case -3: printf("Map file is corrupted!\n");break; + default: printf("Error in string table at line %d",err);break; + } + exit(1); + } + viewsector=loadlevel.start_pos; + viewdir=loadlevel.dir; + loadlevel.name[0]=0; + enter_game(); + leave_current_map(); + if (loadlevel.name[0]!=0)err=load_map(loadlevel.name); + } + closemode(); + } + +*/ + +#define V_NOVA_HRA 0 +#define V_OBNOVA_HRY 1 +#define V_UVOD 2 +#define V_AUTORI 3 +#define V_KONEC 4 + +#define H_ETOPBAR (H_MENUS_FREE+100) +#define H_EDESK (H_MENUS_FREE+101) +static void game_big_circle(char enforced) + { + int err; + int r; + char s[13]; + SEND_LOG("\n(GAME) --------- Entering big loop ------------",0,0); + purge_playlist(); + s[12]=0;strncpy(s,loadlevel.name,12); + err=load_map(s); + if (!enforced) + { + loadlevel.start_pos=mglob.start_sector; + loadlevel.dir=mglob.direction; + } + while (loadlevel.name[0]) + { + if (err) + { + char buff[256]; + closemode(); + switch (err) + { + case -1: sprintf(buff,"Error while loading map (%s) ....file not found\n",s);break; + case -2: sprintf(buff,"Missing -1 at the end of map string table");break; + case -3: sprintf(buff,"Map file is corrupted!\n");break; + default: sprintf(buff,"Error in string table at line %d",err);break; + } + MessageBox(NULL,buff,NULL,MB_OK|MB_ICONSTOP); + exit(1); + } + viewsector=loadlevel.start_pos; + viewdir=loadlevel.dir; + if (viewsector==0) + { + viewsector=set_leaving_place(); + if (viewsector==0) + { + viewsector=mglob.start_sector; + viewdir=mglob.direction; + } + else + { + int i; + viewdir=0; + for (i=0;i<4;i++) if (~map_sides[i+(viewsector<<2)].flags & (SD_PLAY_IMPS | SD_PRIM_VIS)) + {viewdir=i;break;} + } + } + for(r=0;r2) + { + sscanf(argv[2],"%d",§); + enforce=1; + dir=0; + } + loadlevel.start_pos=sect; + loadlevel.dir=dir; + init_game(); + if (argc>=2) + { + memcpy(postavy,postavy_2,sizeof(THUMAN)*6); + memset(runes,0x7f,sizeof(runes)); + } + reg_grafiku_postav(); + memset(GlobEventList,0,sizeof(GlobEventList)); + game_big_circle(enforce); + } + +static void undef_menu() + { + int i; + for(i=0;i<255;i++) undef_handle(0x8000+i); + } + + +static EVENT_PROC(load_error_report) + { + user_ptr; + WHEN_MSG(E_IDLE) + { + message(1,0,0,"",texty[79],texty[80]); + exit_wait=0; + send_message(E_CLOSE_MAP); + } + } + +static void wire_load_saved() + { + send_message(E_CLOSE_MAP,-1); + } + +static void load_saved_game(void) + { + signed char game; + + err: + loadlevel.name[0]=0; + def_handle(H_ETOPBAR,"topbar_e.pcx",pcx_15bit_decomp,SR_BGRAFIKA); + schovej_mysku();wire_proc=wire_load_saved; + put_picture(0,0,ablock(H_ETOPBAR)); + put_picture(0,378,ablock(H_DESK)); + wire_save_load(4); + ukaz_mysku(); + update_mysky(); + game=*((char *)task_wait_event(E_CLOSE_MAP)); + unwire_proc(); + disable_click_map(); + task_wait_event(E_TIMER); + if (game!=-1) + { + reinit_kouzla_full(); + open_story_file(); + memset(GlobEventList,0,sizeof(GlobEventList)); + if (load_game(game)) + { + send_message(E_ADD,E_IDLE,load_error_report); + task_wait_event(E_CLOSE_MAP); + send_message(E_DONE,E_IDLE,load_error_report); + exit_wait=0; + goto err; + } + pick_set_cursor(); + undef_menu(); + init_game(); + build_all_players(); + game_big_circle(1); + exit_wait=1; + } + } + +static void start(va_list args) + { + int volba; + char /*d,*/openning; + + zde: + openning=0; + update_mysky(); + schovej_mysku(); + if (!skip_intro) + { + show_jrc_logo("LOGO.PCX"); + play_anim(7); + } + skip_intro=0; + create_playlist(texty[1]); + //play_next_music(&d); + change_music(NULL); + zobraz_mysku(); + showview(0,0,0,0); + do + { + volba=enter_menu(openning);openning=1; + switch (volba) + { + case V_KONEC:exit_wait=1;break; + case V_NOVA_HRA: if (!enter_generator()) + { + undef_menu(); + new_game(0,NULL); + exit_wait=1; + } + break; + case V_UVOD:bar(0,0,639,479);goto zde;break; + case V_OBNOVA_HRY:load_saved_game();break; + case V_AUTORI:run_titles(NULL);break; + } + } + while (!exit_wait); + } + +static void start_from_mapedit(va_list args) +//#pragma aux start_from_mapedit parm[] + { + int argc=va_arg(args,int); + char **argv=va_arg(args,char **); + new_game(argc-1,argv+1); + exit_wait=1; + } + +void disable_intro() + { + add_field_num(&cur_config,sinit[12].heslo,1); + update_config(); + } + +#include "crashdump.h" + +void main(int argc,char *argv[]) + { + char *c,rm; + + InitCrashDump(); + + if (argc>=3) rm=!strcmp(argv[1],"12345678");else rm=0; + if (!rm) if (OtevriUvodniOkno()==0) return; + + //OPEN_LOG("syslog"); + OPEN_LOG("con"); + SEND_LOG("START --------------------------",0,0); + argv; + c=getcwd(NULL,_MAX_PATH+1); + pathtable[SR_SAVES]=getmem(strlen(c)+2); + strcpy(pathtable[SR_SAVES],c); + strcat(pathtable[SR_SAVES],"\\"); + free(c); + SEND_LOG("(GAME) Save directory sets to '%s'",pathtable[SR_SAVES],0); +// set_verify(0); + mman_pathlist=pathtable; + zoom_speed(1); + turn_speed(1); + SetEnvironmentVariable("BSVER",VERSION); + configure(CONFIG_NAME); + if ((argc>=2 || SelectAdventure()) && !rm ) + { + char *adventure; + char **config=cur_config; + + const char *music = mman_pathlist[SR_MUSIC]; + mman_pathlist[SR_ORGMUSIC]=(char *)getmem(strlen(music)+1); + strcpy(mman_pathlist[SR_ORGMUSIC],music); + + if (argc<2) adventure=GetSelectedAdventure(); + else adventure=argv[1]; + cur_config=NULL; + SEND_LOG("(GAME) Starting new adventure: %s",adventure,0); + configure(adventure); + release_list(cur_config); + cur_config=config; + } +#ifdef LOGFILE + { + int i; + for(i=0;i<(sizeof(pathtable)/4);i++) SEND_LOG("(GAME) LOG: Using directory '%s' as '%s'",pathtable[i],sinit[i+CESTY_POS].heslo); + } +#endif + start_check(); + purge_temps(1); +// textmode_effekt(); + clrscr(); + SEND_LOG("\n(GAME) Init----------------",0,0); + init_skeldal(); + + //add_task(32768,check_number_1phase,argv[0]); + SEND_LOG("(INIT) Starting game thread.",0,0); + if (argc>=3 && rm) + { + add_task(65536,start_from_mapedit,argc,argv); + } + else + add_task(65536,start); + SEND_LOG("(INIT) Main thread goes to sleep.",0,0); +/* position(200,200); + set_font(H_FBIG,RGB(200,200,200)); + outtext("Ahoj lidi"); + showview(0,0,0,0);*/ + escape(); + update_config(); + closemode(); + } + +int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) + { + main(__argc, __argv); + } + +#include "..\game\version.h" + + +int GetExeVersion() + { + return VERSIONNUM; + } \ No newline at end of file diff --git a/GAME/SNDandMUS.C b/GAME/SNDandMUS.C new file mode 100644 index 0000000..b21c015 --- /dev/null +++ b/GAME/SNDandMUS.C @@ -0,0 +1,644 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "globals.h" +#include +//#include //Sound and Nosound +#include +#include + +#define PL_RANDOM 1 +#define PL_FORWARD 2 +#define PL_FIRST 3 + +#define CHANNELS 20 +#define TRACKS 512 + +#define SND_EFF_MAXVOL 32000 +#define SND_EFF_DESCENT 8000 + +#define have_loop(x) ((x)->start_loop!=(x)->end_loop) + +typedef unsigned short SND_FIND_TABLE[2]; +typedef struct snd_info + { + TMA_SOUND *data; //4 + short xpos,ypos,side; //10 + word volume,block; //14 + }SND_INFO; + +static short chan_state[CHANNELS]; +static short track_state[TRACKS]; +static short sample_volume=255; + +//static struct t_wave wav_last_head; +//static int wav_last_size; +static int mute_task=-1; +static char sound_enabled=1; + +SND_INFO tracks[TRACKS]; +SND_INFO playings[CHANNELS]; +static word locks[32]; + +TSTR_LIST cur_playlist=NULL; +TSTR_LIST sound_table=NULL; +int playlist_size; +int playing_track=0; +int remain_play=0; +int play_list_mode=PL_RANDOM; + +void init_tracks() + { + memset(tracks,0,sizeof(tracks)); + memset(playings,0,sizeof(playings)); + memset(chan_state,0xff,sizeof(chan_state)); + memset(track_state,0xff,sizeof(track_state)); + memset(locks,0,sizeof(locks)); + } + +static char last_beep_lev; + +/*void pcspeak_uroven(char value,int time); +#pragma aux pcspeak_uroven parm[bh][ecx]=\ + "mov ah,last_beep_lev"\ + "lp2:add ah,bh"\ + "mov al,48h"\ + "jc lp1"\ + "mov al,4ah"\ + "lp1:out 61h,al"\ + "loop lp2"\ + "mov last_beep_lev,ah"\ + modify [eax] + + +static int get_pc_speed() + { + int ticks=0; + int timer=get_timer_value(); + while (get_timer_value()-timer<50) pcspeak_uroven(127,1000),ticks+=1000; + return ticks; + } + +void pc_speak_play_sample(char *sample,int size,char step,int freq) + { + static speed=0; + int ticker; + if (!speed) speed=get_pc_speed(); + _disable(); + ticker=speed/freq; + sample+=step/2; + while (size>0) + { + if (step==2) + pcspeak_uroven(*sample ^ 0x80,ticker); + else + pcspeak_uroven(*sample,ticker); + sample+=step; + size-=step; + } + _enable(); + nosound(); + } + +*/ + +int find_free_channel(int stamp) + { + int i,j; + int minvol,left,right,mid; + + j=0; + if (stamp) for(i=0;i=0)-(side==3)*(*x<=0); + *y+=(side==2)*(*y>=0)-(side==0)*(*y<=0); + ds=abs(*x)+abs(*y); + ds=SND_EFF_MAXVOL-(SND_EFF_DESCENT*8*ds)/(8+ds); + return ds; + } + +int calcul_volume(int chan,int x,int y,int side,int volume) + { + int lv,rv; + int ds,bal,i; + + if (side==-1) side=viewdir; + side&=3; + ds=calc_volume(&x,&y,side); + if (ds<=0) + { + release_channel(chan); + return -1; + } + for(i=0;iy) + if (x>0) bal=100-y*50/x;else bal=-100-y*50/x; + else bal=50*x/y; + ds=ds*volume/100; + if (bal<0) + { + lv=ds*(100+bal)/100;rv=ds; + } + else + { + rv=ds*(100-bal)/100;lv=ds; + } + lv=(lv*sample_volume)>>8; + rv=(rv*sample_volume)>>8; + set_channel_volume(chan,lv,rv); + return 0; + } + +void wav_load(void **p,long *s) + { + char *sr; + long *d; + char *c; + char *tg; + void *tgr; + size_t siz; + struct t_wave x[3]; + + sr=*p; + sr=find_chunk(sr,WAV_FMT); + read_chunk(sr,&x); + sr=*p; + sr=find_chunk(sr,WAV_DATA); + *s=get_chunk_size(sr); + tgr=tg=getmem(*s+sizeof(struct t_wave)+4); + memcpy(tgr,x,sizeof(struct t_wave)); + tg+=sizeof(struct t_wave); + *(int *)tg=*s; + tg+=4; + read_chunk(sr,tg); + free(*p); + *p=tgr; + siz=*s; + *s+=sizeof(struct t_wave)+4; +/* if (x[0].freq!=x[0].bps) + { + char s; + + siz>>=1; + s=siz & 1; + siz>>=1; + d=tg; + for(;siz--;d++) *d^=0x80008000; + if (s) {c=(char *)d;c[1]^=0x80;} + } + else + { + char s; + + s=siz & 3; + siz>>=2; + d=(long *)tg; + for(;siz--;d++) *d^=0x80808080; + c=(char *)d; + for(;s--;c++) *c^=0x80; + }*/ + } + +void play_effekt(int x,int y,int xd,int yd,int side,int sided,TMA_SOUND *p) + { + int chan; + int blockid; + SND_INFO *track; + THANDLE_DATA *z; + char *s; + + if (!sound_enabled) return; + side; + chan=find_free_channel(p->soundid); + release_channel(chan); + track=&tracks[p->soundid]; + track->data=p; + track->xpos=xd; + track->ypos=yd; + track->side=sided; + track_state[p->soundid]=-1; + if (p->bit16 & 0x8) + { + int vol=SND_EFF_MAXVOL*p->volume/100; + if (rnd(100)>50) set_channel_volume(chan,rnd(vol),vol); + else set_channel_volume(chan,vol,rnd(vol)); + } + else + if (calcul_volume(chan,x-xd,y-yd,/*side-*/sided,p->volume)) return; + if (p->filename[0]==1) memcpy(&blockid,&p->filename[1],4); + else + { + blockid=find_handle(p->filename,wav_load); + if (blockid==-1) + { + z=def_handle(end_ptr,p->filename,wav_load,SR_ZVUKY); + blockid=end_ptr++; + if (level_preload) apreload(blockid); + } + memcpy(&p->filename[1],&blockid,4); + p->filename[0]=1; + } + alock(blockid); + s=ablock(blockid); + s+=p->offset+sizeof(struct t_wave)+4; + play_sample(chan,s,p->end_loop-p->offset,p->start_loop-p->offset,p->freq,1+(p->bit16 & 1)); + playings[chan].data=p; + playings[chan].xpos=xd; + playings[chan].ypos=yd; + playings[chan].side=sided; + playings[chan].volume=p->volume; + playings[chan].block=blockid; + chan_state[chan]=p->soundid; + track_state[p->soundid]=chan; + } + +void restore_sound_name(TMA_SOUND *p) + { + int blockid; + THANDLE_DATA *h; + + if (p->filename[0]==1) + { + memcpy(&blockid,&p->filename[1],4); + do + { + h=get_handle(blockid); + if (h->status==BK_SAME_AS) blockid=h->seekpos;else blockid=-1; + } + while (blockid!=-1); + strncpy(p->filename,h->src_file,12); + } + } + +void restore_sound_names() + { + int i; + + for(i=0;igeneral.action==MA_SOUND) restore_sound_name(&z->sound); + r=(int *)((char *)r+mcsiz); + } + } + } + +void recalc_volumes(int sector,int side) + { + int i; + int newx,newy,layer; + + if (sector>=mapsize) return; + + side; + SEND_LOG("(SOUND) %s","Recalculating volumes",0); + newx=map_coord[sector].x; + newy=map_coord[sector].y; + layer=map_coord[sector].layer; + for(i=0;i=0 && playings[i].side>=0) + { + calcul_volume(i,newx-playings[i].xpos,newy-playings[i].ypos,/*side-*/playings[i].side,playings[i].volume); + if (!get_channel_state(i)) release_channel(i); + } + else calcul_volume(i,0,0,-1,playings[i].volume); + for(i=1;i0) + if (have_loop(tracks[i].data))play_effekt(newx,newy,tracks[i].xpos,tracks[i].ypos,side,tracks[i].side,tracks[i].data); + } + } + mute_task=-1; + } + +void create_playlist(char *playlist) + { + char *c; + char mode[20]; + char shift; + int i=1,j; + if (cur_playlist!=NULL) release_list(cur_playlist); + cur_playlist=NULL; + if (playlist==NULL) return; + if (playlist=="") return; + c=playlist; + while (*c && *c==32) c++; + sscanf(c,"%s",mode); + strupr(mode); + shift=1; + if (!strcmp(mode,"RANDOM")) play_list_mode=PL_RANDOM; + else if (!strcmp(mode,"FORWARD")) play_list_mode=PL_FORWARD; + else if (!strcmp(mode,"FIRST")) play_list_mode=PL_FIRST; + else shift=0; + if (shift) c+=strlen(mode);else play_list_mode=PL_RANDOM; + while (*c && *c==32) c++; + playlist=c; + if (playlist=="") return; + for (c=playlist;c!=NULL;c=strchr(c+1,' ')) i++; + playlist_size=i-1; + cur_playlist=create_list(i); + j=0; + for (c=playlist;c!=NULL;c=strchr(c+1,' ')) + { + char *e; + char d[MAX_PATH+2]="!"; + strncat(d,c+j,MAX_PATH);d[MAX_PATH+1]=0;j=1; + if ((e=strchr(d,32))!=NULL) *e=0; + str_add(&cur_playlist,d); + } + if (play_list_mode==PL_FIRST) + { + cur_playlist[0][0]=32; + remain_play=1; + play_list_mode=PL_RANDOM; + } + else + { + remain_play=0; + } + playing_track=-1; + } + +void play_next_music(char **c) + { + int i,step; + static char d[MAX_PATH]; + + *c=NULL; + if (cur_playlist==NULL) return; + if (!remain_play) + for(i=0;cur_playlist[i]!=NULL;remain_play++,i++) cur_playlist[i][0]=32; + if (play_list_mode==PL_RANDOM) + step=rand()*(playlist_size-1)/32768+1; + else + step=1; + i=playing_track; + do + { + i++; + if (cur_playlist[i]==NULL) i=0; + if (cur_playlist[i][0]==32) step--; + } + while (step); + playing_track=i; + sprintf_s(d,sizeof(d),"%s%s",pathtable[SR_MUSIC],cur_playlist[i]+1); + if (_access(d,0) == -1) + sprintf_s(d,sizeof(d),"%s%s",pathtable[SR_ORGMUSIC],cur_playlist[i]+1); + cur_playlist[i][0]=33; + remain_play--; + *c=d; + } + +void purge_playlist() + { + if (cur_playlist!=NULL)release_list(cur_playlist); + cur_playlist=NULL; + } + +void play_sample_at_sector(int sample,int sector1,int sector2,int track, char loop) + { + int x,y,xd,yd,chan; + char *s; + struct t_wave *p; + int siz; + int oldtrack; + + if (!sound_enabled) return; + if (map_coord[sector1].layer!=map_coord[sector2].layer) return; + x=map_coord[sector1].x; + y=map_coord[sector1].y; + xd=map_coord[sector2].x; + yd=map_coord[sector2].y; + chan=find_free_channel(track); + oldtrack=track_state[track]; + if (!track || oldtrack==-1) release_channel(chan); + if (calcul_volume(chan,x-xd,y-yd,viewdir,100)) return; + if (!track || oldtrack==-1) + { + alock(sample); + s=ablock(sample); + p=(struct t_wave *)s; + s+=sizeof(struct t_wave); + siz=*(int *)s;s+=4; + play_sample(chan,s,siz,loop?0:siz,p->freq,(p->freq!=p->bps?2:1)); + playings[chan].data=NULL; + } + playings[chan].xpos=xd; + playings[chan].ypos=yd; + playings[chan].side=viewdir; + playings[chan].volume=100; + playings[chan].block=sample; + chan_state[chan]=track; + track_state[track]=chan; + } + +void play_sample_at_channel(int sample,int channel,int vol) + { + char *s; + struct t_wave *p; + int siz; + + if (!sound_enabled) return; + channel+=CHANNELS; + vol*=SND_EFF_MAXVOL/100; + set_channel_volume(channel,vol,vol); + if (locks[channel]) aunlock(locks[channel]); + alock(sample); + locks[channel]=sample; + s=ablock(sample); + p=(struct t_wave *)s; + s+=sizeof(struct t_wave); + siz=*(int *)s;s+=4; + play_sample(channel,s,siz,siz,p->freq,(p->freq!=p->bps?2:1)); + } + + +void create_sound_table(char *template,long size) + { + char *c,*s; + int i=0; + + if (sound_table==NULL) sound_table=create_list(2); + s=c=template; + while (c-s +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "globals.h" + +#define PRG_COLOR RGB555(0,31,31) +#define PRG_HELP_COLOR RGB555(31,31,0) + +TMOB *attack_mob; +short init_distance; +short init_sector; +short select_player=-1; +char running_battle=0; +char att_player; +char pgm_help; +char death_play;char far_play; +short cislo_potvory; +short cislo_kola; +HUM_ACTION spell_string; +short caster; +short vybrana_zbran=-1; +char plr_switcher[POCET_POSTAV]; +static autostart_round=0; + +char autoattack=0; +char immortality=0; +long level_map[]= + {400, //level 2 + 1000, // 3 + 1800, // 4 + 2800, // 5 + 5000, // 6 + 8400, // 7 + 13000, // 8 + 20000, // 9 + 30000, // 10 + 45000, // 11 + 70000, // 12 + 110000, // 13 + 180000, // 14 + 300000, // 15 + 500000, // 16 + 800000, // 17 + 1300000, // 18 + 2000000, // 19 + 3000000, // 20 + 4500000, // 21 + 6500000, // 22 + 10000000, // 23 + 11000000, // 24 + 13000000, // 25 + 16000000, // 26 + 20000000, // 27 + 25000000, // 28 + 32000000, // 29 + 40000000, // 30 + 50000000, // 31 + 60000000, // 32 + 70000000, // 33 + 80000000, // 34 + 90000000, // 35 + 100000000, // 36 + 110000000, // 37 + 120000000, // 38 + 130000000, // 39 + 140000000, // 40 + 0x7fffffff // Immortal! + }; + +#define MAX_WEAPON_SKILL 10 + +word weapon_skill[]= //tabulka poctu uspesnych zasahu pro kazdy level + { + 20, //level 1 + 40, // 2 + 80, // 3 + 160, // 4 + 320, // 5 + 640, // 6 + 1280, // 7 + 2560, // 8 + 5120, // 9 + 10240, // 10 + 65535, // max + }; + +char JePozdrzeno(); +char mask_click(int id,int xa,int ya,int xr,int yr); +char mask_click_help(int id,int xa,int ya,int xr,int yr); +char mask_click_help_clear(int id,int xa,int ya,int xr,int yr); +char souboje_clk_throw(int id,int xa,int ya,int xr,int yr); +char runes_mask(int id,int xa,int ya,int xr,int yr); +char cancel_runes(int id,int xa,int ya,int xr,int yr); +char power(int id,int xa,int ya,int xr,int yr); +char cancel_power(int id,int xa,int ya,int xr,int yr); +char ask_who_proc(int id,int xa,int ya,int xr,int yr); +void wire_programming(); +void souboje_vybrano(int d); +void program_draw(); + +void (*after_spell_wire)(); + +short *poradi=NULL; +short *prave_hraje; + +void wire_programming(); +void unwire_programming(); +void wire_jadro_souboje(); +void unwire_jadro_souboje(); + +char sel_zivel=0; +static char prekvapeni=0; +char powers[3]={0,1,2}; +HUM_ACTION *magic_data; + +static int minwait=0,maxwait=-1; + +#define CLK_SOUBOJE 15 +T_CLK_MAP clk_souboje[]= + { + {-1,337,0,357,14,go_map,2,H_MS_DEFAULT}, + {-1,87,0,142,14,game_setup,2,H_MS_DEFAULT}, + {-1,30,0,85,14,konec,2,H_MS_DEFAULT}, + {1,147,0,205,14,clk_saveload,2,H_MS_DEFAULT}, + {0,207,0,265,14,clk_saveload,2,H_MS_DEFAULT}, + {-1,291,0,313,14,go_book,2,H_MS_DEFAULT}, + {-1,528,378,630,479,mask_click,2,-1}, + {1,320,303,639,376,pick_item_,2,-1},//344 + {0,0,303,320,376,pick_item_,2,-1},//344 + {3,0,200,320,340,pick_item_,2,-1},//303 + {2,320,200,639,340,pick_item_,2,-1},//303 + {-1,528,378,630,479,mask_click_help,1,-1}, + {-1,0,0,640,480,mask_click_help_clear,1,-1}, + {MS_GAME_WIN,0,17,639,377,souboje_clk_throw,2,-1}, + {-1,54,378,497,479,start_invetory,2+8,-1}, + }; + + +char clk_enter(int id,int xa,int ya,int xr,int yr) + { + int i=28*256; + id;xa;ya;xr;yr; + send_message(E_KEYBOARD,i); + return 0; + } + + +char clk_battle_touch(int id,int xa,int ya,int xr,int yr) + { + int i; + side_touched=0; + i=clk_touch(id,xa,ya,xr,yr); + if (side_touched) clk_enter(id,xa,ya,xr,yr); + return i; + } + +#define CLK_PRESUN 12 +T_CLK_MAP clk_presun[]= + { + {H_SIPKY_S,561,378,598,407,clk_step,2,H_MS_DEFAULT}, + {H_SIPKY_SZ,530,387,560,418,clk_step,2,H_MS_DEFAULT}, + {H_SIPKY_Z,529,419,555,453,clk_step,2,H_MS_DEFAULT}, + {H_SIPKY_J,560,446,598,474,clk_step,2,H_MS_DEFAULT}, + {H_SIPKY_SV,599,387,628,418,clk_step,2,H_MS_DEFAULT}, + {H_SIPKY_V,605,420,632,454,clk_step,2,H_MS_DEFAULT}, + {MS_GAME_WIN,0,17,639,377,clk_battle_touch,2,-1}, + //{3,109,303,320,340,pick_item_,2,-1}, + //{2,320,303,531,340,pick_item_,2,-1}, + //{1,320,344,577,376,pick_item_,2,-1}, + //{0,63,344,320,376,pick_item_,2,-1}, + //{MS_GAME_WIN,0,17,639,377,clk_throw,2,-1}, + //{-1,337,0,357,14,go_map,2,H_MS_DEFAULT}, + {1,147,0,205,14,clk_saveload,2,H_MS_DEFAULT}, + {0,207,0,265,14,clk_saveload,2,H_MS_DEFAULT}, + {-1,30,0,85,14,konec,2,H_MS_DEFAULT}, + {-1,565,408,593,447,clk_enter,2,H_MS_DEFAULT}, + {-1,0,0,640,480,empty_clk,0xff,-1}, + }; + +#define CLK_RUNES 3 +T_CLK_MAP clk_runes[]= + { + {-1,520,378,639,479,runes_mask,2+1,H_MS_DEFAULT}, + {-1,0,0,639,479,cancel_runes,0x8,H_MS_DEFAULT}, + {-1,0,0,639,479,empty_clk,0xff,H_MS_DEFAULT}, + }; + + +#define CLK_POWER 5 +#define CLK_POWER_WHO 7 +T_CLK_MAP clk_power[]= + { + {0,535,391,637,411,power,2,H_MS_DEFAULT}, + {1,535,421,637,441,power,2,H_MS_DEFAULT}, + {2,535,431,637,471,power,2,H_MS_DEFAULT}, + {-1,0,0,639,377,cancel_power,2+8,-1}, + {-1,0,378,639,479,cancel_power,8,-1}, + {-1,54,378,497,479,ask_who_proc,2,-1}, + {-1,0,0,639,479,empty_clk,0xff,-1}, + }; + + +THUMAN *isplayer(int sector,THUMAN *h,char death) + { + short c=map_coord[sector].flags; + if (c & MC_PLAYER || (death && c & MC_DEAD_PLR)) + { + if (h==NULL) h=postavy;else h++; + while (h-postavyused && (h->lives || death) && h->sektor==sector) return h; + h++; + } + } + return NULL; + } + +int numplayers(int sector,char death) + { + int i,c; + THUMAN *h; + + for(i=0,c=0,h=postavy;iused && (death || h->lives) && h->sektor==sector) c++; + return c; + } + +TMOB *ismonster(int sector,TMOB *m) + { + if (mob_map[sector]) + { + if (m==NULL) m=mobs+mob_map[sector]-1;else + if (m->next) m=mobs+m->next-1;else return NULL; + } + else m=NULL; + return m; + } + +void presun_krok(EVENT_MSG *msg,void **user) + { + user; + if (msg->msg==E_INIT) return; + if (msg->msg==E_DONE) return; + postavy[select_player].actions--; + if (hromadny_utek) + { + int i; + destroy_player_map(); + for (i=0;imsg=-1; + } + +void poloz_vsechny_predmety() + { + int i; + + for(i=0;ivlastnosti[VLS_KOUZLA] & (SPL_STONED | SPL_FEAR)) return 0; + dsee++; +// if (battle) return 1; + prekvapeni=0; + if (d>p->dosah) return 0; + for(i=0;idir+2)&0x3)) break; + if (i==POCET_POSTAV) prekvapeni=!battle; + if (d==1) + { + ss=map_sectors[p->sector].step_next[p->dir]; + if (!(map_coord[ss].flags & MC_PLAYER)) return 0; + } + if (battle && p->vlajky & MOB_CASTING && get_spell_track(p->casting)) return 1; + if (d!=1) + { + if (prekvapeni) return 0; + } + return 1; + } + +void zacni_souboj(TMOB *p,int d,short sector) + { + int i; + //toto je jen test + battle=1; + attack_mob=p; + init_distance=d; + init_sector=sector; + map_coord[p->sector].flags |= MC_AUTOMAP; + for(i=0;imutok) mutok=0; + dmzhit=mutok; + zasah=utok-obrana; + } + else + { + int utok,obrana; + int ospod; + int x,y,z,zv; + + chaos=(chaos+1)/2; + ospod=obrance[VLS_OBRAN_L]/chaos; + x=rnd(utocnik[VLS_UTOK_H]-utocnik[VLS_UTOK_L]+1); + y=rnd(obrance[VLS_OBRAN_H]-ospod+1); + z=rnd(utocnik[VLS_MGSIL_H]-utocnik[VLS_MGSIL_L]+1); + dhit=utok=utocnik[VLS_UTOK_L]+x+(utocnik[VLS_SILA]*15+(utocnik[VLS_OBRAT])*10)/150+bonusplus; + obrana=ospod+y+(obrance[VLS_OBRAT]/5)+(flg & SPL_INVIS?10:0); + mutok=utocnik[VLS_MGSIL_L]+z; + zv=obrance[VLS_OHEN+utocnik[VLS_MGZIVEL]]; + zv=mgochrana(zv); + mutok=zv*mutok/100; + dmzhit=mutok; + zasah=utok-(ddef=obrana); + } + if (zasah<0) zasah=0; + if (zasah>0) zasah+=utocnik[VLS_DAMAGE],zasah=max(zasah,1); + ddostal=zasah; + zasah=zasah+mutok; + if (zasah>0) + { + zasah+=zbran; + if (zasah<1) zasah=1; + } + if (flg & SPL_SANC) zasah/=2; + if (flg & SPL_HSANC) zasah/=4; + if (flg & SPL_TVAR) zasah=-zasah; + return zasah; + } + +void rozhodni_o_poradi() + { + int celk=0; + int i,j; + short *r,mem; + + for(i=0;i378 && ms_last_event.x>510 && cur_mode!=MD_PRESUN; + if (cond) schovej_mysku(); + redraw_scene(); + if (!cancel_render && !norefresh) + { + if (cur_mode!=MD_PRESUN) + { + program_draw(); + draw_blood(0,0,0); + check_players_place(0); + } + showview(0,0,0,0); + if (neco_v_pohybu==2) neco_v_pohybu=0; else neco_v_pohybu=2; + calc_fly();mob_animuj(); + if (d_action!=NULL) do_delay_actions(); + } + if (cond) ukaz_mysku(); + if (neco_v_pohybu) + { + if (++counter>=maxwait && maxwait>0) neco_v_pohybu=0; + } + else + if (++countergroupnum && p->lives) + { + p->groupnum=t++; + for(j=i+1;q=&postavy[j],jsektor==q->sektor && p->direction==q->direction && q->used && q->lives) + q->groupnum=p->groupnum; + } + } +/* +int vyber_zacinajiciho(int att_player) + { + int gr; + THUMAN *p; + int i; + +// if (att_player==0xff) +// for(i=0;i=POCET_POSTAV?-POCET_POSTAV:1); + i++; + } + while ((!p->used || !p->actions)&& i<6); + return p-postavy; + } + +int vyber_prvniho(int att) + { + int grp; + int i; + + if (att==0xff) + for(i=0;iPOCET_POSTAV || att<0) + gr=cur_group,att=0xff; + else + gr=postavy[att].groupnum; + h=postavy; + for(i=0,h=postavy;iused || !h->lives || !h->actions || h->groupnum!=gr) ;i++,h++); + if (i==6) + if (att!=0xff) return att;else return group_sort[0]; + else + return i; + } + +void zacatek_kola() + { + int i; + THUMAN *p; + + SEND_LOG("(BATTLE) Start round",0,0); + build_player_map(); + cislo_kola++; + autostart_round=0; + for(i=0;iused) + { + postavy[i].programovano=0; + if (p->kondice && p->lives) + { + p->actions=get_ap(p->vlastnosti); + // if (p->actions) autostart_round=0; + } + else postavy[i].actions=0; + if (postavy[i].zvolene_akce!=NULL)free(postavy[i].zvolene_akce); + postavy[i].zvolene_akce=NewArr(HUM_ACTION,postavy[i].actions+1); + memset(postavy[i].zvolene_akce,0,(postavy[i].actions+1)*sizeof(HUM_ACTION)); + postavy[i].provadena_akce=postavy[i].zvolene_akce; + } + } + auto_group(); + sort_groups(); + select_player=vyber_hrace(att_player); + //att_player=vyber_prvniho(att_player); + //select_player=vyber_zacinajiciho(att_player); + zmen_skupinu(&postavy[select_player]); + viewsector=postavy[select_player].sektor; + viewdir=postavy[select_player].direction; + redraw_scene();cancel_render=1; + } + +char check_end_game() + { + THUMAN *p; + int i; + char end=1; + + for(i=0;iused && p->lives) + { + end=2; + if (p->groupnum==cur_group) return 0; + } + } + return end; + } + +void konec_kola() + { + int i;THUMAN *h;TMOB *m; + int j; + + SEND_LOG("(BATTLE) End round",0,0); + prekvapeni=0; + for(i=0,h=postavy;iused) + { + if (h->zvolene_akce!=NULL) free(h->zvolene_akce); + h->zvolene_akce=NULL; + h->programovano=0; + if (h->vlastnosti[VLS_KOUZLA] & SPL_REGEN && h->lives) + h->lives+=3; + player_check_death(h,1); + if (h->lives>h->vlastnosti[VLS_MAXHIT]) h->lives=h->vlastnosti[VLS_MAXHIT]; + } + for(i=0,m=mobs;ivlajky & MOB_LIVE && m->vlastnosti[VLS_KOUZLA] & SPL_REGEN) + { + m->lives+=3;if (m->lives>m->vlastnosti[VLS_MAXHIT]) m->lives=m->vlastnosti[VLS_MAXHIT]; + } + auto_group(); + sort_groups(); + select_player=-1; + GlobEvent(MAGLOB_ONROUND,viewsector,viewdir); + sleep_ticks+=MAX_SLEEP/12; + if (sleep_ticks>MAX_SLEEP) sleep_ticks=MAX_SLEEP; + for(i=0,j=0;imsg==E_KEYBOARD && !pass_zavora) + { + msg->msg=-2; + delete_from_timer(TM_SCENE); + delete_from_timer(TM_FLY); + wire_save_load(2); + bott_draw(1); + cancel_render=1; + } + } + +static char clk_goon(int id,int xa,int ya,int xr,int yr) + { + id,xa,ya,xr,yr; + send_message(E_KEYBOARD,13); + return 1; + } + +#define CLK_END_GAME 2 +T_CLK_MAP clk_end_game[]= + { + {-1,0,0,639,479,clk_goon,8+2,H_MS_DEFAULT}, + {-1,0,0,639,479,empty_clk,0xff,H_MS_DEFAULT}, + }; + + +EVENT_PROC(end_game_end_phase) + { + static wait=0; + WHEN_MSG(E_TIMER) + { + if (pass_zavora) return; + if (wait==2) + { + send_message(E_ADD,E_KEYBOARD,kbd_end_game); + send_message(E_DONE,E_TIMER,end_game_end_phase); + change_click_map(clk_end_game,CLK_END_GAME); + } + else wait++; + } + WHEN_MSG(E_INIT) + wait=0; + user_ptr; + } + +void wire_end_game() + { + int i; + if (cur_mode==MD_END_GAME) return; + konec_kola(); + battle=0;running_battle=0; + unwire_proc(); + for(i=0;imsg==E_KEYBOARD && ((*(int *)msg->data)>>8)==28 && !pass_zavora) + { + unwire_proc(); + wire_jadro_souboje(); + msg->msg=-1; + } + } + +void wire_presun_postavy(); +void unwire_presun_postavy() + { + disable_click_map(); + send_message(E_DONE,E_KEYBOARD,game_keyboard); + send_message(E_DONE,E_KROK,presun_krok); + send_message(E_DONE,E_KEYBOARD,konec_presunu); + delete_from_timer(TM_SCENE); + cur_mode=MD_INBATTLE; + sort_groups(); + wire_proc=wire_presun_postavy; + hromadny_utek=0; + } + +void wire_presun_postavy() + { + unwire_proc(); + + moving_player=select_player; + change_click_map(clk_presun,CLK_PRESUN); + send_message(E_ADD,E_KEYBOARD,game_keyboard); + send_message(E_ADD,E_KROK,presun_krok); + send_message(E_ADD,E_KEYBOARD,konec_presunu); + cur_mode=MD_PRESUN; + auto_group(); + sort_groups(); + bott_draw(1); + redraw_scene(); + add_to_timer(TM_SCENE,gamespeed,-1,hrat_souboj); + showview(0,0,0,0); + unwire_proc=unwire_presun_postavy; + cancel_render=1; + } + +static DWORD SPozdrzeno=0; + +static char JePozdrzeno() +{ + return GetTickCount()sektor; + viewdir=p->direction; + pozdrz_akci(); + hold_timer(TM_SCENE,1); + redraw_scene(); + cancel_render=1; + program_draw(); + showview(0,0,0,0); + hold_timer(TM_SCENE,0); + + } + +int hromadny_utek; +static int UtekHromadne(int sector) + { + int minact=999; + int i; + int p=0; + for (i=0;i2) + { + int wf=weigth_defect(postavy+i)+2; + if (postavy[i].provadena_akce==NULL || postavy[i].provadena_akce->action!=AC_RUN) return 0; + if (postavy[i].utek1?minact:0; + } + +void utek_postavy(THUMAN *p) + { + int minact=0; + p->actions=p->utek; + if (game_extras & EX_GROUP_FLEE && (minact=UtekHromadne(p->sektor))!=0) + { + int i; + p->actions=minact; + hromadny_utek=p->sektor; + for (i=0;isektor) + { + int wf=weigth_defect(postavy+i)+2; + postavy[i].kondice-=minact*wf; + if (postavy[i].kondice<0) postavy[i].kondice=0; + if (postavy+i!=p) postavy[i].programovano=0; + } + } + else + { + int wf=weigth_defect(p)+2; + hromadny_utek=0; + if (p->actions) + { + p->kondice-=p->actions*wf; + if (p->kondice<0) + { + p->actions+=p->kondice/wf; + p->kondice=0; + } + } + } + wire_presun_postavy(); + prejdi_na_pohled(p); + } + +int trace_path(sector,dir) + { + int mm,p,c=5; + int r=rnd(2); + do + { + if ((mm=mob_map[sector])!=0) + { + if (mobs[mm-1].stay_strategy & MOB_BIG) return 0; + if (mobs[mm-1].next!=0 && r==1) mm=mobs[mm-1].next; + switch (dir) + { + case 0: p=mobs[mm-1].locx-128;break; + case 1: p=mobs[mm-1].locy-128;break; + case 2: p=-(mobs[mm-1].locx-128);break; + case 3: p=-(mobs[mm-1].locy-128);break; + } + if (p<-12) return -24; + else if (p>12) return +24; + else return 0; + }/* return rnd(3)-1;*/ + if (map_sides[(sector<<2)+dir].flags & SD_THING_IMPS) return -255; + sector=map_sectors[sector].step_next[dir]; + c--; + } + while (c); + return -255; + } + +void hod_dykou(THUMAN *p,int where,int bonus) + { + short *pp; + int i; + int ps; + LETICI_VEC *v; + + ps=trace_path(p->sektor,p->direction); + if (ps==-255) return; + pp=picked_item; + picked_item=getmem(2*sizeof(short)); + picked_item[0]=p->wearing[where]; + picked_item[1]=0; + v=throw_fly(320,100,0); + v->ypos=ps; + v->hit_bonus=(p->vlastnosti[VLS_OBRAT]*3+p->vlastnosti[VLS_SILA]*2)/30+bonus; + v->damage=0; + for(i=0;iinv_size;i++) + { + int it; + + it=p->inv[i]; + if (it--) + { + if (glob_items[it].druh==TYP_VRHACI && glob_items[it].umisteni==PL_RUKA) + { + p->wearing[where]=it+1; + p->inv[i]=0; + break; + } + } + } + if(i==p->inv_size) p->wearing[where]=0; + picked_item=pp; + } + +void vystrel_sip(THUMAN *p,int bonus) + { + short *pp; + int ps; + int i; + int x; + LETICI_VEC *v; + TITEM *t; + + ps=trace_path(p->sektor,p->direction); + if (ps==-255) return; + if (!p->sipy) + { + char s[100]; + + sprintf(s,texty[72],p->jmeno); + bott_disp_text(s); + return; + } + for(i=0;isipy--; + v=throw_fly(320,100,1); + v->ypos=ps; + x=rnd(p->vlastnosti[VLS_UTOK_H]-p->vlastnosti[VLS_UTOK_L]); + v->hit_bonus=x+p->vlastnosti[VLS_UTOK_L]+(p->vlastnosti[VLS_SILA]*10+p->vlastnosti[VLS_OBRAT]*15)/150+bonus; + v->damage=p->vlastnosti[VLS_DAMAGE]; + picked_item=pp; + t->zmeny[VLS_MGSIL_H]=p->vlastnosti[VLS_MGSIL_H]; //adjust zmen v magickem utoku + t->zmeny[VLS_MGSIL_L]=p->vlastnosti[VLS_MGSIL_L]; + t->zmeny[VLS_MGZIVEL]=p->vlastnosti[VLS_MGZIVEL]; + play_sample_at_sector(H_SND_SIP1+rnd(2),0,0,0,0); + neco_v_pohybu=1; + } + +char is_useable_weapon(int i) + { + if (!i) return 0; + i--; + switch (glob_items[i].druh) + { + case TYP_UTOC: + case TYP_VRHACI: + case TYP_STRELNA: + case TYP_SVITEK:return 1; + default: return 0; + } + } + +int select_weapon(THUMAN *p,char ask) + { + char lp,rp; + int li,ri; + char *c; + + li=p->wearing[PO_RUKA_L]; + ri=p->wearing[PO_RUKA_R]; + lp=is_useable_weapon(li); + rp=is_useable_weapon(ri); + if (!lp && !rp) return 2; + if (lp && !rp) return 0; + if (!lp && rp) return 1; + li--; + ri--; + if (glob_items[li].druh==glob_items[ri].druh && glob_items[li].druh==TYP_UTOC) return 2; + if (!ask) return rnd(2); + unwire_proc(); + c=alloca(strlen(p->jmeno)+strlen(texty[82])+1); + sprintf(c,texty[82],p->jmeno); + lp=message(2,0,1,"",c,texty[83],texty[84]); + wire_proc(); + return lp; + } + +static int vypocti_bonus(THUMAN *p,int vybrana_zbran) + { + int bonus; + if (vybrana_zbran>-1) + if (vybrana_zbran>0) bonus=p->bonus_zbrani[glob_items[vybrana_zbran-1].typ_zbrane]; + else bonus=p->bonus_zbrani[TPW_OST]; + else bonus=0; + return bonus; + } + +static void pouzij_svitek(THUMAN *p,int ruka) + { + int it=p->wearing[ruka]-1; + short s[2]; + + thing_cast(glob_items[it].spell,p-postavy,p->sektor,NULL,0); + if (glob_items[it].magie==1) + { + s[0]=it+1; + s[1]=0; + destroy_items(s); + p->wearing[ruka]=0; + } + else + { + it=(p->wearing[ruka]=duplic_item(it+1)); + it--; + glob_items[it].magie--; + } + } + +static void play_weapon_anim(int anim_num,int hitpos) + { + char count_save=global_anim_counter; + int battlespeed=gamespeed-gamespeed*gamespeedbattle/5; + + if (anim_num==0) return; + hold_timer(TM_SCENE,1); + if (battlespeed<1) battlespeed=1; + add_to_timer(TM_SCENE2,battlespeed,-1,hrat_souboj); + play_big_mgif_animation(anim_num+face_arr[4]); + do + { + while (global_anim_counter==count_save) + { + do_events(); + } + count_save=global_anim_counter; + } + while (hitpos-- && running_anm); + delete_from_timer(TM_SCENE2); + hold_timer(TM_SCENE,0); + cancel_render=1; + } + +void pouzij_zbran(THUMAN *p,int ruka) + { + int itm,where; + TITEM *it; + int bonus; + int wf=weigth_defect(p)+1; + + + p->kondice-=wf; + if (ruka==2) ruka=plr_switcher[p-postavy]; + where=PO_RUKA_L+ruka; + itm=p->wearing[where]; + SEND_LOG("(BATTLE) Player uses weapon %d.in %s hand",itm,where?"right":"left"); + if (p->stare_vls[VLS_KOUZLA] & SPL_INVIS) + { + p->stare_vls[VLS_KOUZLA]&=~SPL_INVIS; + prepocitat_postavu(p); + build_all_players(); + } + vybrana_zbran=itm; + bonus=vypocti_bonus(p,itm); + if (itm>0) + memcpy(&p->vlastnosti[VLS_MGSIL_L],&glob_items[itm-1].zmeny[VLS_MGSIL_L],3*sizeof(short)); + else + memset(&p->vlastnosti[VLS_MGSIL_L],0,3*sizeof(short)); + if (!itm || (it=&glob_items[itm-1])->druh==TYP_UTOC) + { + TMOB *m;int mm,chaos; + mm=vyber_potvoru(p->sektor,p->direction,&chaos); + if (mm>=0) + { + TITEM *it=glob_items+itm-1; + m=mobs+mm; + bott_draw(1); + anim_mirror=ruka==0; + prejdi_na_pohled(p); + if (itm) play_weapon_anim(it->weapon_attack,it->hitpos); + if (utok_na_sektor(p,m,chaos,bonus)>0 && itm && rnd(100)+1magie) + thing_cast(it->spell,p-postavy,p->sektor,m,1); + } + } + else + { + prejdi_na_pohled(p); + switch(it->druh) + { + case TYP_VRHACI:hod_dykou(p,where,bonus);break; + case TYP_STRELNA:vystrel_sip(p,bonus);break; + case TYP_SVITEK:pouzij_svitek(p,where);break; + } + } + bott_draw(0); + } + +static word last_sector; +static char valid_sectors(word sector) + { + int pp; + int i; + + last_sector=sector; + if (mob_map[sector]) return 0; //nevyhovujici + pp=map_sectors[sector].sector_type; + if (pp==S_DIRA || ISTELEPORT(pp)) return 0; + for (i=0;i<4;i++) if (map_sectors[sector].step_next[i] && mob_map[map_sectors[sector].step_next[i]]) return 0; + return 1; + } + + +static char StrachPostavy(THUMAN *p) +{ + word *cesta; + int i; + int ln; + int wf=weigth_defect(p)+1; + + prejdi_na_pohled(p); + cur_group=p->groupnum; + for(select_player=0;select_player<6;select_player++) if (postavy+select_player==p) break; + bott_draw(0); + labyrinth_find_path(p->sektor,65535,SD_PLAY_IMPS,valid_sectors,NULL); + ln=labyrinth_find_path(p->sektor,last_sector,SD_PLAY_IMPS,valid_sectors,&cesta); + if (cesta[0]==0) {free(cesta);return 0;} + for (i=0;i<6 && cesta[i] && p->kondice ;i++) + { + int dir; + for (dir=0;dir<4;dir++) if (map_sectors[p->sektor].step_next[dir]==cesta[i]) break; + destroy_player_map(); + p->direction=dir; + p->sektor=cesta[i]; + build_player_map(); + prejdi_na_pohled(p); + Sleep(200); + p->kondice-=wf; + } + p->provadena_akce+=p->programovano-1; + p->programovano=1; + free(cesta); + return 1; +} + +void jadro_souboje(EVENT_MSG *msg,void **unused) //!!!! Jadro souboje + { + static char nowait=0; + unused; + + if (msg->msg==E_IDLE && (!neco_v_pohybu || !battle || nowait)&& !norefresh && !cancel_render) + { + short nxt; + + if (check_end_game()==1) + { + wire_end_game(); + return; + } + vybrana_zbran=-1; + cancel_render=1; + nxt=*prave_hraje++; + anim_mirror=0; + if (nxt) + { + if (nxt>0) + { + nxt--; + SEND_LOG("(BATTLE) Mobile action (%d. %s)",nxt,mobs[nxt].name); + nowait=akce_moba_zac(&mobs[nxt]) && *prave_hraje>0; + neco_v_pohybu=1; + cislo_potvory=nxt; + } + else + if(nxt==-255) + { + int i; + SEND_LOG("(BATTLE) Ending round...",nxt,mobs[nxt].name); + delete_from_timer(TM_SCENE); + add_to_timer(TM_SCENE,gamespeed,-1,refresh_scene); + for(i=0;iprogramovano && p->lives) + { + plr_switcher[select_player]=!plr_switcher[select_player]; + cur_group=p->groupnum; + cancel_render=1; + if (p->kondice || p->provadena_akce->action==AC_STAND) + { + if (p->vlastnosti[VLS_KOUZLA] & SPL_FEAR && StrachPostavy(p)) + {} + else + { + SEND_LOG("(BATTLE) Player Action '%s', number: %d",p->jmeno,p->provadena_akce->action); + switch(p->provadena_akce->action) + { + case AC_MOVE: + { + int wf=weigth_defect(p)+1; + p->actions++; + p->kondice-=p->actions*wf; + if (p->kondice<0) + { + p->actions+=p->kondice*wf; + p->kondice=0; + if (p->actions<0) + { + p->actions=0; + break; + } + } + viewsector=p->sektor; + viewdir=p->direction; + wire_presun_postavy(); + break; + } + case AC_ATTACK:pouzij_zbran(p,p->provadena_akce->data1);break; + case AC_ARMOR:souboje_prezbrojeni(nxt); + bott_draw(1); + other_draw(); + break; + case AC_THROW: + { + int x,y; + memcpy(&picked_item,&p->provadena_akce->data2,sizeof(short *)); + x=p->provadena_akce->data1; + y=(x>>8)*2;x=(x & 0xff)*4; + prejdi_na_pohled(p); + throw_fly(x,y,0); + cislo_potvory=-2; + neco_v_pohybu=1; + } + case AC_STAND:pomala_regenerace_postavy(p);break; + case AC_RUN:utek_postavy(p);break; + case AC_MAGIC: + prejdi_na_pohled(p); + bott_draw(1); + teleport_target=p->provadena_akce->data2; + cast(p->provadena_akce->data1,p,select_player,0); + cislo_potvory=-2; + break; + } + } + } + neco_v_pohybu=1; + p->provadena_akce++; + p->programovano--; + } + } + } + else + { + nowait=0; + konec_kola(); + check_all_mobs_battle(); + mouse_set_default(H_MS_DEFAULT); + if (battle) + { + delete_from_timer(TM_SCENE); + zacatek_kola(); + unwire_proc(); + wire_programming(); + } + else + { + int i; + THUMAN *p; + + SEND_LOG("(BATTLE) Leaving battle",0,0); + prekvapeni=0; + unwire_proc(); + wire_main_functs(); + bott_draw(1); + running_battle=0; + for(i=0;p=&postavy[i],isektor!=viewsector || !p->used || !p->groupnum);i++); + if (i==POCET_POSTAV) + for(i=0;p=&postavy[i],iused || !p->groupnum);i++); + cur_group=postavy[i].groupnum; + viewsector=postavy[i].sektor; + viewdir=postavy[i].direction; + build_player_map(); + GlobEvent(MAGLOB_AFTERBATTLE,viewsector,viewdir); + } + msg->msg=-2; + } + } + } + +void wire_jadro_souboje() + { + int battlespeed=gamespeed-gamespeed*gamespeedbattle/5; + recalc_volumes(viewsector,viewdir); + if (battlespeed<1) battlespeed=1; + add_to_timer(TM_SCENE,battlespeed,-1,hrat_souboj); + send_message(E_ADD,E_IDLE,jadro_souboje); + mouse_set_default(H_MS_SOUBOJ); + unwire_proc=unwire_jadro_souboje; + cur_mode=MD_INBATTLE; + pgm_help=10; + } + +void unwire_jadro_souboje() + { + delete_from_timer(TM_SCENE); + send_message(E_DONE,E_IDLE,jadro_souboje); + mouse_set_default(H_MS_DEFAULT); + wire_proc=wire_jadro_souboje; + pgm_help=0; + } + +void fill_rune(char *d,int i) + { + int x,y;char *dd; + + dd=((char *)d)+6+512; + for(y=378;y<480;y++) + { + word *z; + z=GetScreenAdr()+y*scr_linelen2; + for(x=520;x<640;x++) + if (*dd++==i) z[x]=z[x]-((z[x] & RGB555(28,28,28))>>2); + } + + } + +static void *runebar; +static char *rune_name=NULL; + +void display_rune_bar() + { + short coords[][2]={{3,26},{32,26},{61,26},{90,26},{18,64},{47,64},{76,64}}; + char c; + int i; + + schovej_mysku(); + if (runebar!=NULL) put_picture(520,378,runebar); + else + { + put_picture(520,378,ablock(H_RUNEBAR1+sel_zivel)); + c=runes[sel_zivel]; + for(i=0;i<7;i++,c>>=1) + if (!(c & 1)) put_picture(520+coords[i][0],378+coords[i][1],ablock(H_RUNEHOLE)); + else if (!get_rune_enable(&postavy[select_player],(sel_zivel*7+i)*3)) fill_rune((char *)ablock(H_RUNEMASK),i+6); + if (sel_zivel) trans_bar(520,378,sel_zivel*24,22,0); + if (sel_zivel!=4)trans_bar(544+sel_zivel*24,378,96-sel_zivel*24,22,0); + runebar=getmem(120*102*2+6); + get_picture(520,378,120,102,runebar); + } + ukaz_mysku(); + if (je_myska_zobrazena())showview(520,378,120,102); + } + + + +void rune_bar_redrawing() + { + redraw_scene(); + if (!norefresh && !cancel_render) + { + schovej_mysku(); + program_draw(); + display_rune_bar(); + ukaz_mysku(); + showview(0,0,0,0); + } + } + + +void display_power_bar(char drw) + { + int coords[][2]={{20,11},{20,41},{20,71}}; + int i; + + schovej_mysku(); + put_picture(520,378,ablock(H_POWERBAR)); + for(i=0;i<3;i++) + put_8bit_clipped(ablock(H_POWERLED),520+coords[i][0]+(378+coords[i][1])*scr_linelen2+GetScreenAdr(),24*powers[i],21,24); + ukaz_mysku(); + if (drw) showview(520,378,120,102); + } + +void display_power_bar_tm(THE_TIMER *tm) + { + tm; + display_power_bar(1); + } + +void wire_select_rune(); +void unwire_select_rune(); +void wire_select_power(); + +char cancel_power(int id,int xa,int ya,int xr,int yr) + { + xa;ya;xr;yr;id; + schovej_mysku(); + unwire_proc(); + magic_data->action=0; + after_spell_wire(); + mouse_set_default(H_MS_DEFAULT); + ukaz_mysku(); + return 1; + } + +char ask_who_proc(int id,int xa,int ya,int xr,int yr) + { + THUMAN *p; + int i; + word *xs; + + xs=ablock(H_OKNO); + i=xr/xs[0];yr;xa;ya;id; + if (isektor!=viewsector; + if (p->used) + if ((!far_play && !c || !death_play && c) && death_play==(p->lives==0)) + { + if (get_spell_teleport(magic_data->data1)) + if ((magic_data->data2=select_teleport_target())==0) + { + cancel_power(id,xa,ya,xr,yr); + return 1; + } + magic_data->data1+=(i+1)<<9; + magic_data->action=AC_MAGIC; + if (battle) souboje_vybrano(AC_MAGIC); + unwire_proc(); + after_spell_wire(); + mouse_set_default(H_MS_DEFAULT); + return 1; + } + } + return 0; + } + +void vyber_cil(int typ) + { + death_play=(typ==3)?1:0; + far_play=(typ==4)?1:0; + change_click_map(clk_power,CLK_POWER_WHO); + mouse_set_default(H_MS_WHO); + } + +char power(int id,int xa,int ya,int xr,int yr) + { + xa;ya;xr;yr; + if (powers[id]==1) return 1; + schovej_mysku(); + display_power_bar(0); + trans_bar(520+44,378+11+30*id,76,24,RGB555(31,31,31)); + mouse_set_default(H_MS_DEFAULT); + ukaz_mysku(); + showview(520,378,120,102); + magic_data->data1-=magic_data->data1 % 3; + magic_data->data1+=id; + id=magic_data->data1; + if ((id=ask_who(id))>1) + { + vyber_cil(id); + return 1; + } + magic_data->action=AC_MAGIC; + if (get_spell_teleport(magic_data->data1)) + if ((magic_data->data2=select_teleport_target())==0) + { + cancel_power(id,xa,ya,xr,yr); + return 1; + } + if (id==1) magic_data->data1+=(select_player+1)<<9; + schovej_mysku(); + if (battle) souboje_vybrano(AC_MAGIC); + unwire_proc(); + after_spell_wire(); + ukaz_mysku(); + return 1; + } + +char runes_mask(int id,int xa,int ya,int xr,int yr) + { + char *c; + int cc; + short *d; + + id;ya;xa; + d=ablock(H_RUNEMASK); + c=((char *)d)+6+512+xr+yr*d[0]; + cc=*c-6; + if (*c) + if (*c<6 && ms_last_event.event_type & 0x2) sel_zivel=*c-1; + else if (runes[sel_zivel] & (1<data1=x; + unwire_select_rune(); + wire_select_power(); + schovej_mysku(); + fill_rune((char *)d,*c); + ukaz_mysku(); + showview(520,378,120,102); + return 1; + } + else + { + rune_name=get_rune_name(x); + } + } + if (cc<0) rune_name=NULL; + free(runebar);runebar=NULL; + display_rune_bar(); + return 1; + } + +char cancel_runes(int id,int xa,int ya,int xr,int yr) + { + xa;ya;xr;yr;id; + rune_name=NULL; + schovej_mysku(); + unwire_select_rune(); + magic_data->action=0; + after_spell_wire(); + ukaz_mysku(); + return 1; + } + +void unwire_select_rune() + { + wire_proc=wire_select_rune; + delete_from_timer(TM_DELAIER); + delete_from_timer(TM_SCENE); + cancel_render=1; + free(runebar);runebar=NULL; + } + +void wire_select_rune() + { + THUMAN *p; + HUM_ACTION *c; + + mute_all_tracks(0); + p=&postavy[select_player]; + c=p->zvolene_akce;while (c->action) c++; + magic_data=c; + c++; + c->action=0; + unwire_proc(); + change_click_map(clk_runes,CLK_RUNES); + add_to_timer(TM_DELAIER,12,1,display_rune_bar); + add_to_timer(TM_SCENE,gamespeed,-1,rune_bar_redrawing); + unwire_proc=unwire_select_rune; + cancel_render=1; + } + +void wire_select_rune_fly() + { + mute_all_tracks(0); + unwire_proc(); + change_click_map(clk_runes,CLK_RUNES); + add_to_timer(TM_DELAIER,12,1,display_rune_bar); + add_to_timer(TM_SCENE,gamespeed,-1,rune_bar_redrawing); + unwire_proc=unwire_select_rune; + cancel_render=1; + } + +void unwire_select_power() + { + rune_name=NULL; + delete_from_timer(TM_DELAIER); + } + +void wire_select_power() + { + THUMAN *p; + int i; + + p=&postavy[select_player]; + mute_all_tracks(0); + unwire_proc(); + for(i=0;i<3;i++) powers[i]=get_spell_color(p,magic_data->data1+i); + change_click_map(clk_power,CLK_POWER); + unwire_proc=unwire_select_power; + add_to_timer(TM_DELAIER,12,1,display_power_bar_tm); + } + + + +void program_draw() + { + int x=54+74/2; + int i,j,maxy=0; + + maxy; + schovej_mysku(); + for(j=0;jmaxy) maxy=y; + } + if (!maxy && (pgm_help || rune_name!=NULL)) maxy+=10; + if (maxy) + { + maxy+=5; + trans_bar(0,377-maxy,640,maxy,0); + } + for(j=0;jaction+40]); + outtext(texty[c->action+40]); + c++; + y+=+10; + } + x+=74; + } + if(pgm_help || rune_name!=NULL) + { + char *c; + + if (rune_name!=NULL) c=rune_name;else c=texty[40+pgm_help]; + set_font(H_FLITT5,PRG_HELP_COLOR); + set_aligned_position(580,376,1,2,c); + outtext(c); + } + ukaz_mysku(); + } + + +void souboje_redrawing() + { + if (neco_v_pohybu) calc_mobs(); + calc_animations(); + redraw_scene(); + if (!norefresh && !cancel_render) + { + schovej_mysku(); + program_draw(); + ukaz_mysku(); + showview(0,0,0,0); + } + } + + +void souboje_stisknout(int d) + { + update_mysky(); + schovej_mysku(); + d--; + d*=105; + put_8bit_clipped(ablock(H_BATTLE_CLICK),378*scr_linelen2+520+GetScreenAdr(),d,120,102); + ukaz_mysku(); + showview(520,378,120,102); + cancel_render=1; + } + +static void souboje_dalsi() + { + int i,j=12,cd; + for(i=0;group_sort[i]!=select_player;i++); + cd=postavy[select_player].groupnum; + do + { + i++; + if (i>=POCET_POSTAV) i=0; + select_player=group_sort[i]; + j--; + } + while ((!postavy[select_player].used || !postavy[select_player].actions || (postavy[select_player].groupnum!=cd && j>6)) && j); + viewsector=postavy[select_player].sektor; + viewdir=postavy[select_player].direction; + } + +void souboje_vybrano(int d) + { + if (d==AC_STAND || d==AC_RUN) postavy[select_player].actions=0; + else postavy[select_player].actions--; + postavy[select_player].programovano++; + if (!postavy[select_player].actions) + souboje_dalsi(); + bott_draw(1); + } + +void zrusit_akce() + { + HUM_ACTION *c; + + c=postavy[select_player].zvolene_akce; + while (c->action) + if (c->action==AC_THROW) + { + poloz_vsechny_predmety(); + memcpy(&picked_item,&c->data2,sizeof(short *)); + c++; + } + else c++; + postavy[select_player].zvolene_akce->action=0; + postavy[select_player].actions=get_ap(postavy[select_player].vlastnosti);; + postavy[select_player].programovano=0; + postavy[select_player].utek=0; + pick_set_cursor(); + bott_draw(1); + } + +char souboje_clk_throw(int id,int xa,int ya,int xr,int yr) + { + HUM_ACTION *c; + + if (postavy[select_player].actions==0) return 0; + if (picked_item==NULL) return 0; + postavy[select_player].direction=viewdir; + c=postavy[select_player].zvolene_akce;while (c->action) c++; + c->action=AC_THROW; + memcpy(&c->data2,&picked_item,sizeof(short *));picked_item=NULL; + c->data1=xa/4+(ya/2)*256; + c++; + c->action=0; + pick_set_cursor();id;xr;yr; + souboje_vybrano(AC_THROW); + return 1; + } + + +char mask_click_help(int id,int xa,int ya,int xr,int yr) + { + char *c; + int d; + word *mask; + + id;xa;ya; + mask=(word *)ablock(H_BATTLE_MASK); + c=(char *)mask+6+512; + c+=yr*mask[0]+xr; + d=*c; + if (d) pgm_help=d; + return 1; + } + +char mask_click_help_clear(int id,int xa,int ya,int xr,int yr) + { + id;xa;ya; + xr;yr; + pgm_help=0; + return 1; + } + +static void zahajit_kolo(char prekvapeni) + { + int i,j; + + for(i=0;isektor,dir=p->direction; + char monster=0; + char monster_far=0; + char lnear=1; + int counter=5; + short w1,w2,dw1,dw2,w; + + while (~map_sides[(sect<<2)+dir].flags & SD_PLAY_IMPS) + { + int m1,m2; + sect=map_sectors[sect].step_next[dir]; + if (numplayers(sect,0)>2) break; + m1=mob_map[sect]-1;if (m1>=0) m2=mobs[m1].next-1;else m2=-1; + if ((m1>=0 && mobs[m1].vlajky & MOB_IN_BATTLE) || (m2>=0 && mobs[m2].vlajky & MOB_IN_BATTLE)) + if (lnear) monster=1;else monster_far=1; + lnear=0;counter--;if(!counter) break; + } + w1=p->wearing[PO_RUKA_L];w2=p->wearing[PO_RUKA_R]; + if (w1) dw1=glob_items[w1-1].druh;else dw1=-1; + if (w2) dw2=glob_items[w2-1].druh;else dw2=-1; + w=0; + if (dw1==TYP_STRELNA && p->sipy || dw1==TYP_VRHACI) w|=1; + if (dw2==TYP_STRELNA && p->sipy || dw2==TYP_VRHACI) w|=2; + if (w==0) w=select_weapon(p,0); + else if (w==3) w=select_weapon(p,0),monster|=monster_far; + else w--,monster|=monster_far; + if (p->used && !p->programovano && p->lives) + if (prekvapeni || !p->actions || !autoattack || !monster) + { + p->programovano++;p->zvolene_akce->action=AC_STAND; + } + else + { + for(j=0;jactions;j++) + { + p->zvolene_akce[j].action=AC_ATTACK; + p->zvolene_akce[j].data1=w; + } + p->programovano=(char)p->actions; + } + } + rozhodni_o_poradi(); + unwire_proc(); + wire_jadro_souboje(); + send_message(E_KOUZLO_KOLO); + } + +char mask_click(int id,int xa,int ya,int xr,int yr) + { + char *c; + int d; + word *mask; + + id;xa;ya; + mask=(word *)ablock(H_BATTLE_MASK); + c=(char *)mask+6+512; + c+=yr*mask[0]+xr; + d=*c; + if (d) + { + souboje_stisknout(d); + switch(d) + { + case AC_RUN: postavy[select_player].utek=5+postavy[select_player].actions; + case AC_ATTACK: + case AC_STAND: + case AC_ARMOR: + case AC_MOVE: + case AC_MAGIC:if (postavy[select_player].actions) + { + HUM_ACTION *c; + postavy[select_player].direction=viewdir; + c=postavy[select_player].zvolene_akce;while (c->action) c++; + if (d==AC_MAGIC) + { + wire_select_rune(); + return 1; + } + c->action=d; + if (d==AC_ATTACK) c->data1=select_weapon(&postavy[select_player],1); + c++; + c->action=0; + souboje_vybrano(d); + } + break; + case AC_CANCEL:zrusit_akce();break; + case AC_START:zahajit_kolo(0); + souboje_stisknout(d); + return 0; + break; + } + return 0; + } + bott_draw(1); + return 1; + } +void fix_group_direction() + { + int i,g; + + g=postavy[select_player].groupnum; + for(i=0;imsg==E_KEYBOARD) + { + c=(*(int *)msg->data)>>8; + while (_bios_keybrd(_KEYBRD_READY) ) _bios_keybrd(_KEYBRD_READ); + switch (c) + { + case 1:konec(0,0,0,0,0);break; + case 'M':souboje_turn(1);break; + case 'K':souboje_turn(-1);break; + case '=':unwire_proc();cancel_render=1;wire_save_load(0);break; + case '>':game_setup(0,0,0,0,0);break; + case 57:souboje_dalsi();bott_draw(1);break; + case 15: + case 50: + if (GlobEvent(MAGLOB_BEFOREMAPOPEN,viewsector,viewdir)) + show_automap(1); + break; + case 0x17:unwire_proc(); + wire_inv_mode(human_selected); + case 82:group_all();break; + CASE_KEY_1_6:c=group_sort[c-2]; + if (postavy[c].used) + { + select_player=c; + zmen_skupinu(postavy+c); + bott_draw(1); + } + break; + } + } + + } + +void unwire_programming() + { + disable_click_map(); + send_message(E_DONE,E_KEYBOARD,programming_keyboard); + delete_from_timer(TM_SCENE); + cancel_render=1; + wire_proc=wire_programming; + } + + + +void wire_programming() + { + schovej_mysku(); + after_spell_wire=wire_programming; + cur_mode=MD_INBATTLE; + battle_mode=0; + change_click_map(clk_souboje,CLK_SOUBOJE); + send_message(E_ADD,E_KEYBOARD,programming_keyboard); + add_to_timer(TM_SCENE,gamespeed,-1,souboje_redrawing); + ukaz_mysku(); + unwire_proc=unwire_programming; + bott_draw(1); + showview(0,0,0,0); + recalc_volumes(viewsector,viewdir); + if (autostart_round) zahajit_kolo(1); + } + +void wait_to_stop(EVENT_MSG *msg,void **unused) + { + + unused; + if (msg->msg==E_IDLE) + if (!neco_v_pohybu) + { + unwire_proc(); + calc_mobs(); + mouse_set_default(H_MS_DEFAULT); + refresh_scene(); + cancel_render=1; + if (prekvapeni) zahajit_kolo(1);else wire_programming(); + msg->msg=-2; + } + } + + +void start_battle() + { + spell_cast=0; + if (check_end_game()) + { + wire_end_game(); + return; + } + if (!GlobEvent(MAGLOB_BEFOREBATTLE,viewsector,viewdir)) + { + int i; + battle=0; + for (i=0;iname:"(NULL)",0); + poloz_vsechny_predmety(); + zacatek_kola(); + running_battle=1; +// select_player=att_player; + cislo_kola=0; + if (prekvapeni) + { + unwire_proc(); + mouse_set_default(H_MS_SOUBOJ); + zahajit_kolo(1); + } + else + { + unwire_proc(); + wire_programming(); + } + } + } + +int pocet_zivych(int sector) + { + char z=0; + int i; + for(i=0;iused && p->lives && p->sektor==sector) z++; + } + return z; + } + +void manashield_check(short *vls,short *lives,short *mana,int dostal) + { + if (vls[VLS_KOUZLA] & SPL_MANASHIELD) + { + *mana-=*mana>dostal?dostal:*mana; + if (!*mana) vls[VLS_KOUZLA]&=~SPL_MANASHIELD; + } + else + *lives-=dostal; + } + + + +char zasah_veci(int sector,TFLY *fl) + { + int mob1,mob2; + TMOB *m1,*m2; + TITEM *it; + + m1=NULL; + m2=NULL; + if (fl->items==NULL && fl->item==0) return 0; + if (fl->items==NULL) it=glob_items+fl->item-1;else it=&glob_items[*(fl->items)-1]; + if (fl->flags & FLY_DESTROY_SEQ || !fl->speed) return 0; + if (fl->flags & FLY_DESTROY) + { + if (mob_map[sector] && fl->owner>=0) + { + if (fl->owner>=0) select_player=fl->owner-1; + if (it->druh!=TYP_VRHACI) return 1; + if (it->magie) area_cast(it->spell,sector,fl->owner,1); + mob1=mob_map[sector]-MOB_START;m1=&mobs[mob1]; + mob2=m1->next-MOB_START; + if (mob2>=0) + { + m2=&mobs[mob2]; + if (m2->vlajky & MOB_PASSABLE) m2=NULL;//pruchozi nestvury nemaji affekt na hozenou vec + } + else m2=NULL; + if (m1->vlajky & MOB_PASSABLE) if (m2!=NULL) m1=m2;else return 0; + if (m2==NULL) + { + mob_hit(m1,vypocet_zasahu(it->zmeny,m1->vlastnosti,1,fl->damage,fl->hit_bonus)); + m1->dir=fl->smer+2&3; + } + else + { + mob_hit(m1,vypocet_zasahu(it->zmeny,m1->vlastnosti,2,fl->damage,fl->hit_bonus)); + mob_hit(m2,vypocet_zasahu(it->zmeny,m1->vlastnosti,2,fl->damage,fl->hit_bonus)); + m1->dir=fl->smer+2&3; + m2->dir=fl->smer+2&3; + } + return 1; + } + else if (map_coord[sector].flags & MC_PLAYER && (fl->owner<=0 || pocet_zivych(sector)>2)) + { + int kolik,i,c=0; + int owner=fl->owner; + + if (it->druh!=TYP_VRHACI) return 1; + if (it->magie) area_cast(it->spell,sector,fl->owner,1); + for(i=0,kolik=0;isektor && p->lives && p->used) + { + char death; + short vlastnosti[VLS_MAX]; + memcpy(vlastnosti,p->vlastnosti,sizeof(vlastnosti)); + if (game_extras & EX_SHIELD_BLOCKING) PodporaStitu(p, vlastnosti); + death=player_hit(p,vypocet_zasahu(it->zmeny,vlastnosti,kolik,fl->damage,fl->hit_bonus),1); + if (death && owner && hlubina_level) mobs[-owner-1].lives=0; //hlubina - nestvura je mrtva + c=1; + } + bott_draw(1); + } + return c; + } + } + else + if (mob_map[sector] && fl->owner>=0) + { + if (fl->owner>=0) select_player=fl->owner-1; + if (it->druh!=TYP_VRHACI) return 1; + mob1=mob_map[sector]-MOB_START;m1=&mobs[mob1]; + mob2=m1->next-MOB_START; + if (mob2>=0) + { + int x1,y1; + m2=&mobs[mob2]; + switch (fl->smer) + { + case 0:x1=fl->ypos;y1=32;break; + case 1:x1=-32;y1=fl->ypos;break; + case 2:x1=-fl->ypos;y1=-32;break; + case 3:x1=32;y1=-fl->ypos;break; + } + if (abs(x1-m1->locx+128)+abs(y1-m1->locy+128)>abs(x1-m2->locx+128)+abs(y1-m2->locy+128)) m1=m2; + } + if (m1->vlajky & MOB_PASSABLE) return 0; + mob_hit(m1,vypocet_zasahu(it->zmeny,m1->vlastnosti,(m2!=NULL)+1,fl->damage,fl->hit_bonus)); + if (it->druh==TYP_VRHACI) fl->flags|=FLY_DESTROY; + if (it->umisteni!=PL_SIP && !(it->flags & ITF_DESTROY)) + { + int i; + for(i=0;iinv[i]==0) { m1->inv[i]=it-glob_items+1;break;} + if (i==MOBS_INV) fl->flags &=FLY_DESTROY; + } + m1->dir=fl->smer+2&3; + return 1; + } + else if (map_coord[sector].flags & MC_PLAYER && (fl->owner<=0 || pocet_zivych(sector)>2)) + { + int kolik,i,j,c=0,r; + int owner=fl->owner; + + if (it->druh!=TYP_VRHACI) return 1;else fl->flags|=FLY_DESTROY; + fl->speed=0; + for(i=0,kolik=0;ivlastnosti,sizeof(vlastnosti)); + if (game_extras & EX_SHIELD_BLOCKING) PodporaStitu(p, vlastnosti);else uprav_podle_kondice(p,&kolik); + death=player_hit(p,vypocet_zasahu(it->zmeny,vlastnosti,kolik,fl->damage,fl->hit_bonus),1); + if (death && owner && hlubina_level) mobs[-owner-1].lives=0; //hlubina - nestvura je mrtva + c=1; + } + bott_draw(1); + } + return c; + } + return 0; + } + +void cast_wait(EVENT_MSG *msg,void **unused) + { + unused; + + if (msg->msg==E_TIMER) + if (!neco_v_pohybu) + { + send_message(E_DONE,E_TIMER,cast_wait); + delete_from_timer(TM_SCENE); + wire_main_functs(); + } + } + +void wire_cast_spell() + { + if (spell_string.action) + { + teleport_target=spell_string.data2; + select_player=caster; + cast(spell_string.data1,&postavy[caster],caster,0); + /*add_to_timer(TM_SCENE,gamespeed,-1,hrat_souboj); + neco_v_pohybu=1; + send_message(E_ADD,E_TIMER,cast_wait);*/ + } + wire_main_functs(); + bott_draw(0); + } + +void wire_fly_casting(int i) + { + if (!postavy[i].used || !postavy[i].lives) return; + magic_data=&spell_string; + memset(&spell_string,0,sizeof(spell_string)); + after_spell_wire=wire_cast_spell; + select_player=i; + wire_select_rune_fly(); + select_player=caster=i; + } + +static void rozdelit_skryte_bonusy(THUMAN *hu) + { + short *vls,*vls2; + short p[]={VLS_SILA,VLS_SMAGIE,VLS_OBRAT}; + short h[3]; + register i; + + vls=hu->vlastnosti; + vls2=hu->stare_vls; + if (vls[p[0]]lives+=h[i];break; + case VLS_SMAGIE: if (vls2[VLS_SMAGIE]) {vls2[VLS_MAXMANA]+=h[i];hu->mana+=h[i];}break; + case VLS_OBRAT: vls2[VLS_KONDIC]+=h[i];hu->kondice+=h[i];break; + } + } + prepocitat_postavu(hu); + } + + +void check_player_new_level(THUMAN *p) + { + int u; + + u=p->level-1; + while (level_map[u]<=p->exp) + { + u++;p->bonus+=5; + rozdelit_skryte_bonusy(p); + prepocitat_postavu(p); + SEND_LOG("(GAME) Character '%s' raised a level %d",p->jmeno,u); + } + p->level=u+1; + } + + +void send_experience(TMOB *p,int dostal) + { + if (select_player<0) return; + if (isdemon(postavy+select_player)) return; + if (p->lives<=0) + { + int i; + for(i=0;ibonus; + check_player_new_level(postavy+i); + } + if (hlubina_level==1) + { + postavy[select_player].lives=0; + player_check_death(postavy+select_player,0); + } + } + if (dostal>0) postavy[select_player].exp+=(long)((float)p->experience*(float)dostal/p->vlastnosti[VLS_MAXHIT]); + check_player_new_level(&postavy[select_player]); + } + + +void send_weapon_skill(int druh) + { + THUMAN *p=&postavy[select_player]; + + if (isdemon(p)) return; + if (p->bonus_zbrani[druh]bonus_zbrani[druh]; + if (c[0]weapon_expy[druh]++; + if (p->weapon_expy[druh]>=weapon_skill[c[0]]) + { + c[0]++; + SEND_LOG("(GAME) Character '%s' raised new weaponskill in '%s'",p->jmeno,texty[91+druh]); + } + } + } + } + +char player_check_death(THUMAN *p, char afterround) + { + p->used&=~0x80; + if (p->lives<=0 && p->groupnum) + if (!battle || afterround) + { + int mp; + int i; + if (isdemon(p)) + { + unaffect_demon(p-postavy); + return 0; + } + for(i=0;iwearing[i]; + if (j) + { + short it[2]; + it[1]=0;it[0]=j;j--; + if (glob_items[j].flags & ITF_NOREMOVE) + { + destroy_items(it); + p->wearing[i]=0; + } + } + } + p->groupnum=0; + p->lives=0; + if (p->level>1) p->exp=level_map[p->level-2]; + p->kondice=0; + p->mana=0; + SEND_LOG("(GAME) Character '%s' died. R.I.P.",p->jmeno,0); + if (numplayers(p->sektor,0)==0) map_coord[p->sektor].flags &=~MC_PLAYER; + mp=map_sectors[p->sektor].sector_type; + if (mp==S_VODA || mp==S_LAVA || mp==S_VIR) p->sektor=0; + else map_coord[p->sektor].flags |= MC_DEAD_PLR; + GlobEvent(MAGLOB_ONDEADMAN+p->female,viewsector,viewdir); + return 1; + } + else + { + if (p->lives<0) p->lives=0; + p->used|=0x80; + } + if (p->lives>p->vlastnosti[VLS_MAXHIT]) p->lives=p->vlastnosti[VLS_MAXHIT]; + return 0; + } + +char mute_hit_sound=0; + +char player_hit(THUMAN *p,int zraneni,char manashield) + { + char check=0; + + if (!p->lives) return check; + if (zraneni>0) + { + THE_TIMER *tt;int h; + + if (zraneni>p->lives) zraneni=p->lives; + p->dostal=zraneni; + if (manashield) manashield_check(p->vlastnosti,&p->lives,&p->mana,p->dostal); //manashield pro hrace + else p->lives-=zraneni; + if (p->female) h=H_SND_HEK1F;else h=H_SND_HEK1M; + h+=rnd(2); + if (!mute_hit_sound) + { + if (GlobEvent(MAGLOB_ONHITMAN+p->female,p->sektor,p->direction)) + play_sample_at_sector(h,p->sektor,viewsector,0,0); + tt=add_to_timer(TM_CLEAR_ZASAHY,100+rnd(100),1,vymaz_zasahy);tt->userdata[0]=p-postavy;tt->userdata[1]=p->dostal; + } + mute_hit_sound=0; + if (immortality) p->lives=p->vlastnosti[VLS_MAXHIT]; + check=player_check_death(p,0); + } + else + { + p->lives-=zraneni; + if (p->lives>p->vlastnosti[VLS_MAXHIT]) p->lives=p->vlastnosti[VLS_MAXHIT]; + } + return check; + } + +void enforce_start_battle() + { + if (!battle && see_monster) + { + int i;THUMAN *h; + stop_all_mobs();battle=1; + for(i=0,h=postavy;iused || !h->lives || h->groupnum!=cur_group);i++,h++); + if (i>=POCET_POSTAV) h=postavy,i=0; + att_player=i; + } + } + +void uprav_podle_kondice(THUMAN *p,int *chaos) + { + if (p->kondice<(p->vlastnosti[VLS_POHYB]/2) || p->vlastnosti[VLS_POHYB]<4) + { + *chaos=999; + } + else + p->kondice--; + } + + +void correct_level() + { + THUMAN *h; + int i; + + puts("\x7"); + h=postavy; + for (i=0;iused) + { + int j; + if (h->level>37 || (h->level>1 && h->explevel-2])) + { + poloz_vsechny_predmety(); + picked_item=NewArr(short,2); + picked_item[0]=h->level; + picked_item[1]=0; + pick_set_cursor(); + } + h->level=1; + for (j=0;;j++) if (h->exp>level_map[j]) h->level=j+2;else break; + } + } diff --git a/GAME/SPECPROC.C b/GAME/SPECPROC.C new file mode 100644 index 0000000..1390f67 --- /dev/null +++ b/GAME/SPECPROC.C @@ -0,0 +1,707 @@ +//Toto je hlavni soubor specialnich procedur pro hru BRANY SKELDALU +#include +#include +#include +#include +#include +#include "bgraph.h" +#include "globals.h" +#include "specproc.h" +#include "bmouse.h" +#include +//#include "i86.h" + +#define MOB_GO(m) if (m->dir & 1)m->headx=mob_go_x[m->dir];else m->heady=mob_go_y[m->dir] + +int cur_event_number; + +static void event_error(char *text,int number) + { + char buff[256]; + closemode(); + sprintf(buff,"%s\n Specproc num: %d\n",text,number); + MessageBox(NULL,buff,NULL,MB_OK|MB_ICONSTOP); + exit(1); + } + + +//Item procs--------------------------------------- +ITEM_PROC(item_test) + { + putchar('\x7');event,ptr,p; + putchar('\n'); + return 1; + } + +//Map procs--------------------------------------- +MAP_PROC(map_test) + { + putchar('\x7');sector,side,event,value; + putchar('\n'); + return 1; + } + +void spell_teleport(); +MAP_PROC(map_teleport) + { + side=0;event; + teleport_target=value; + if (mob_map[sector]!=0) + { + int i; + spell_teleport(-mob_map[sector],-1); + if ((i=mobs[mob_map[sector]-1].next)!=0) + spell_teleport(-i,-1); + side=1; + } + if (map_coord[sector].flags & MC_DPLAYER) + { + int i,j=-1;THUMAN *h; + int bit=0; + + for(i=0,h=postavy;iused && h->sektor==sector && h->sektor==viewsector) + { + j=i;break; + } + for(i=0,h=postavy;iused && h->sektor==sector) bit|=1<direction,bit,j!=-1); + side=1; + auto_group(); + } + return side; + } + +/* +static void otoc_obraz1(word *source,word *target) + { + word *p,*q; + word *sp,*sq; + int x,y; + + sp=source+320-180; + sq=target+scr_linelen2*359+320-180; + y=360; + while (y--) + { + p=sp; + q=sq; + x=360; + while (x--) + { + *q=*p; + q-=scr_linelen2; + p++; + } + sp+=scr_linelen2; + sq++; + } + } + +void swap_screen(word *_p,word *_q) + { + __asm + { + mov esi,_p + mov edi,_q + + std + mov ecx,115200 + lp1: + mov ax,[edi] + xchg ax,[esi] + stosw + add esi,2 + dec ecx + jnz lp1 + cld + } + } +// #pragma aux swap_screen parm [esi][edi]=\ modify [ecx eax] + +static void otoc_obraz2(word *source) + { + swap_screen(source,source+scr_linelen2*360-2); + } + +static void otoc_obraz3(word *source,word *target,short smer) + { + word *tt,*ss; + int x,y,xs,ys; + int xp,yp; + + tt=target; + if (smer>0)x=320+126-224;else x=320+126+224; + if (smer>0)y=180-126-224;else y=180+126-224; + yp=360; + ys=0; + while (yp--) + { + xs=0; + ss=source+scr_linelen2*y+x; + xp=640; + while (xp--) + { + if (ss>=source && ss10) + { + xs-=10; + ss+=scr_linelen2+smer; + } + } + ys+=7; + if (ys>10) + if (smer>0) + { + ys-=10; + x--; + y++; + } + else + { + ys-=10; + x--; + y--; + } + } + } + +static void show_liane(THE_TIMER *t) + { + word *bt,*bs; + static int counter=0; + + schovej_mysku(); + if (counter<5 && counter) + { + bt=GetScreenAdr()+SCREEN_OFFSET; + bs=GetBuffer2nd()+SCREEN_OFFSET; + } + else + { + redraw_scene(); + bs=GetScreenAdr()+SCREEN_OFFSET; + } + + switch(counter) + { + case 0:break; + case 1:otoc_obraz3(bs,bt,1);break; + case 2:curcolor=0; + bar(0,SCREEN_OFFLINE,139,SCREEN_OFFLINE+359); + bar(640-140,SCREEN_OFFLINE,639,SCREEN_OFFLINE+359); + otoc_obraz1(bs,bt);break; + case 3:otoc_obraz3(bs,bt,-1);break; + + default:otoc_obraz2(bs);if (counter==4)OutBuffer2nd();break; + } + ukaz_mysku(); + showview(0,0,0,0); + if (!counter) + { + schovej_mysku(); + OutBuffer2nd(); + ukaz_mysku(); + } + if (t->calls==1) + { + THUMAN *h; + int i; + + save_load_trigger((word)(t->userdata[0])); + for(i=0,h=postavy;ilives,0); + h->sektor=0; + } + wire_proc(); + counter=-1; + } + counter++; + } +*/ + + +static const float Inv2=0.5; +static const float Snapper=3<<22; + +static __inline int toInt(float fval) + { + fval += Snapper; + return ( (*(int *)&fval)&0x007fffff ) - 0x00400000; + } + +static void OtocObrazPodleMatice(float mx[3][2], word *picture) + { + word *trg=GetScreenAdr()+17*scr_linelen2; + int x,y; + picture+=6; + for (y=0;y<360;y++,trg+=scr_linelen2) + for (x=0;x<640;x++) + { + int oldx=x-320; + int oldy=y-180; + int newx=toInt(oldx*mx[0][0]+oldy*mx[1][0]+320); + int newy=toInt(oldx*mx[0][1]+oldy*mx[1][1]+180); + if (newx>=0 && newx<640 && newy>=0 && newy<360) + trg[x]=picture[newx+640*newy]; + else + trg[x]=0; + } + } + +static void OtaceniObrazu() + { + word *picture=(word *)malloc(640*360*2+16); + float mx[3][2]; + + int maxtime=500; + int lasttime=GetTickCount(); + int curtime; + get_picture(0,17,640,360,picture); + do + { + float phase; + float uhel; + float cosuhel; + float sinuhel; + curtime=GetTickCount()-lasttime; + phase=curtime/(float)maxtime; + if (phase>1.0f) phase=1.0f; + uhel=phase*3.14159265; + cosuhel=cos(uhel); + sinuhel=sin(uhel); + mx[0][0]=cosuhel; + mx[0][1]=sinuhel; + mx[1][0]=-sinuhel; + mx[1][1]=cosuhel; + OtocObrazPodleMatice(mx,picture); + showview(0,0,0,0); + do_events(); + } + while (curtimeuserdata[0]=save_load_trigger(-1); + schovej_mysku(); + OtaceniObrazu(); + ukaz_mysku(); + for(i=0,h=postavy;ilives,0); + h->sektor=0; + } + redraw_scene(); + cancel_pass=1; + cancel_render=1; + showview(0,0,0,0); + wire_proc(); + return 1; + } +#define ID_XS 400 +#define ID_YS 380 + +MAP_PROC(map_identify) + { + int x,y,yp,xp,ys,yss; + int i,cnt;char s[100]; + TITEM *it; + TSTR_LIST ls; + + sector;side;event;value; + if (picked_item==NULL) return 0; + it=glob_items+*picked_item-1; + ls=create_list(256); + unwire_proc(); + sprintf(s,texty[210],it->jmeno);str_add(&ls,s); + sprintf(s,texty[211],it->hmotnost*2,it->hmotnost>0 && it->hmotnost<3?texty[236]:texty[237]);str_add(&ls,s); + if (it->nosnost) + { + sprintf(s,texty[212],it->nosnost);str_add(&ls,s); + } + for(i=0;i<21;i++) + if (it->zmeny[i] && texty[213+i]!=NULL) + { + if (i==VLS_HPREG || i==VLS_MPREG || i==VLS_VPREG) + sprintf(s,texty[213+i],it->zmeny[i]>0?texty[234]:texty[235]); + else + sprintf(s,texty[213+i],it->zmeny[i],it->zmeny[i+1]); + str_add(&ls,s); + } + if (it->zmeny[VLS_MGSIL_H]) + { + sprintf(s,texty[233],texty[22+it->zmeny[VLS_MGZIVEL]]);str_add(&ls,s); + } + for(i=0;i<16;i++) + if (it->zmeny[VLS_KOUZLA] & (1<0;i--) if (ls[i-1]!=NULL) break; + cnt=i;i=0; + ys=cnt*10+10; + do + { + x=320-ID_XS/2; + y=y=240-ys/2; + create_frame(x,y,ID_XS,ys,1); + xp=x+5;yp=y+5;ys=ID_YS-10; + set_font(H_FBOLD,NOSHADOW(0)); + yss=ys; + while(iuser_data<128 || m->user_data>192) + { + int sector=m->sector; + int i; + TSTENA *side; + + for(i=0,side=map_sides+(sector<<2);i<4;side++,i++) + if (side->flags & SD_MONST_IMPS && side->sector_tag!=0 && (~side->flags & (SD_PASS_ACTION | SD_SECRET))==(SD_PASS_ACTION|SD_SECRET)) + break; + if (i!=4) + { + m->dir=i;stop_mob(m); + if (flag_map[(sector<<2)+i] & SD_MONST_IMPS) a_touch(sector,m->dir); + m->user_data=128; + return 1; + } + side=map_sides+(sector<<2)+((m->dir+2)&3); + if (~side->flags & SD_MONST_IMPS && side->sector_tag!=0 && (~side->flags & (SD_PASS_ACTION | SD_SECRET))==(SD_PASS_ACTION|SD_SECRET)) + { + int ss=map_sectors[sector].step_next[(m->dir+2)&3]; + int j=mob_map[ss]; + while (j) if (mobs[j-1].dir==m->dir) return 0; + else j=mobs[j-1].next; + a_touch(sector,(m->dir+2)&3); + return 0; + } + } + else + { + if (m->user_data>=128 && m->user_data<192) m->user_data++; + if (~map_sides[(m->sector<<2)+m->dir].flags & SD_MONST_IMPS) + { + if (m->dir & 1) m->headx=mob_go_x[m->dir];else m->heady=mob_go_y[m->dir]; + m->user_data=map_coord[map_sectors[m->sector].step_next[m->dir]].flags & MC_PLAYER?255:127; + } + return m->user_data<144; + } + return 0; + } + +MOB_PROC(mob_open_door_battle) + { + if (event==SMPR_ATTACK) + { + m->specproc=5; + } + return 0; + } + +static char spec_proc_test_mob(int event_type,TMOB *m) + { + m,event_type; + putchar('\x7'); + putchar('\n'); + return 0; + } + + +static char mob_dokola(int event_type,TMOB *m) + { + if (event_type==SMPR_WALK) + { + m->dir++; + m->dir &=3; + MOB_GO(m); + return 1; + } + return 0; + } + +static char mob_carodej(int event_type,TMOB *m) + { +static char kouzla[5]={3,8,13,18,80}; + + if (event_type==SMPR_ATTACK) + { + m->casting=kouzla[rnd(5)]; + } + return 0; + } + +static char mob_strelec(int event_type,TMOB *m) + { + if (event_type==SMPR_ATTACK) + { + int i,l; + + if (m->dostal==0 && ~m->user_data & 128) return 0; + for (i=0;i<4;i++) + { + l=map_sectors[m->sector].step_next[i]; + if (l!=0 && map_coord[l].flags & MC_PLAYER) break; + } + if (i==4) + { + if (m->user_data & 128) + { + int s=m->sector; + m->user_data&=~128; + i=m->dir+2&3; + while (s && !(map_coord[s].flags & MC_PLAYER)) if (map_sides[(s<<2)+i].flags & SD_MONST_IMPS) s=0;else s=map_sectors[s].step_next[i]; + if (s) m->dir=i;else return 1; + } + return 0; //strilej + } + i=i+2&3; + if (mob_check_next_sector(m->sector,i,m->stay_strategy & MOB_BIG,0)) + { + int l=4,z,max=RAND_MAX+1; + for(i=0;i<4;i++) + if (!mob_check_next_sector(m->sector,i,m->stay_strategy & MOB_BIG,0)) + { + int s=map_sectors[m->sector].step_next[i]; + if (!get_dangerous_place(s) && (z=rand())dir=i; + MOB_GO(m); + m->user_data|=128; + return 1; + } + else + { + /* + int i,l; + i=m->dir; + l=m->sector; + if (map_sides[(l<<2)+i].flags & SD_MONST_IMPS) return 0; + l=map_sectors[l].step_next[i]; + for(i=0;i<4;i++) + { + int s=map_sectors[l].step_next[i]; + if (isplayer(s,NULL,0)!=NULL) + { + m->dir=i+2&3; + m->headx=mob_go_x[i]; + m->heady=mob_go_y[i]; + return 1; + } + } + */ + if (m->user_data & 128) + { + THUMAN *h; + int i; + + for(i=0,h=postavy;ilives && h->used && + abs(map_coord[h->sektor].x-map_coord[m->sector].x)<2 && + abs(map_coord[h->sektor].y-map_coord[m->sector].y)<2) + { + stop_mob(m); + return 1; + } + } + return 0; //delej si co chces + } + } + + + + +MOB_PROC(mob_krikloun) + { + if (event==SMPR_ATTACK) + { + sirit_zvuk(m->sector); + } + return 0; + } + +static char mob_taktik_recurse(int recall,int sector,int *min_obr,int big,int *csect,int *cdir) + { + int i; + char nasel=0; + + //nejprve zjistime kdo je okolo nas + for(i=0;i<4;i++) + { + int s=map_sectors[sector].step_next[i]; + THUMAN *h=NULL; + + if (!s) continue; //pokud tam je stena tak pokracuj jinym smerem + if (mob_check_next_sector(sector,i,big,0)==1) continue; + if ((h=isplayer(s,h,0))!=NULL) //nekdo tam je - zjisti kdo + while(h!=NULL) + { + if (h->vlastnosti[VLS_OBRAN_H]<*min_obr) // pokud ma nizsi obranu + { + *csect=sector; + *cdir=i; + *min_obr=h->vlastnosti[VLS_OBRAN_H]; + nasel=1; + } + h=isplayer(s,h,0); + } + else if (recall) //pokud tam nikdo neni koukni se vedle + { + if (mob_taktik_recurse(0,s,min_obr,big,csect,cdir)) *cdir=i; + } + } + return nasel; + } + + +MOB_PROC(mob_taktik) + { + int min_obr=1000; + int csect=m->sector; + int cdir=-1; + + if (event==SMPR_ATTACK) + { + mob_taktik_recurse(1,m->sector,&min_obr,m->stay_strategy & MOB_BIG,&csect,&cdir); + if (cdir==-1) return 0; + m->dir=cdir; + if (m->sector!=csect) + { + MOB_GO(m); + return 1; + } + + } + return 0; + } + +MOB_PROC(mob_stoji) + { + if (event==SMPR_ATTACK) + { + int i; + int s; + + for(i=0;i<4;i++) + { + s=map_sectors[m->sector].step_next[i]; + if (s && map_coord[s].flags & MC_PLAYER) return 0; + } + m->headx=m->locx; + m->heady=m->locy; + m->stay_strategy&=~(MOB_WALK | MOB_LISTEN); + m->vlajky&=~MOB_IN_BATTLE; + return 1; + } + else if (event==SMPR_WALK) + { + m->headx=m->locx; + m->heady=m->locy; + } + else if (event==SMPR_KNOCK) return 1; + return 0; + } + +static t_mob_proc sp_mob_table[]= + { + NULL, //0 + spec_proc_test_mob, //1 + mob_dokola, //2 + mob_carodej, //3 + mob_strelec, //4 + mob_open_door, //5 + mob_open_door_battle, //6 + mob_krikloun, //7 + mob_taktik, //8 + mob_stoji, //9 + }; + +#define SP_MOB_TAB_SIZE (sizeof(sp_mob_table)/sizeof(t_mob_proc)) + +static t_item_proc sp_item_table[]= + { + NULL, //0 + item_test, //1 + }; + +#define SP_ITEM_TAB_SIZE (sizeof(sp_item_table)/sizeof(t_item_proc)) + +static t_map_proc sp_map_table[]= + { + NULL, //0 + map_test, //1 + map_teleport, //2 + map_liana, //3 + map_identify, //4 + }; + +#define SP_MAP_TAB_SIZE (sizeof(sp_map_table)/sizeof(t_map_proc)) + +char call_mob_event(int event_number,int event_type,TMOB *m) + { + if (!event_number) return 0; + if (event_number>=SP_MOB_TAB_SIZE) + event_error("Nestvra pouva neplatnou specproc.",event_number); + cur_event_number=event_number; + return sp_mob_table[event_number](event_type,m); + } + +char call_item_event(int event_number,int event_type,short *ptr,THUMAN *p) + { + if (!event_number) return 0; + if (event_number>=SP_ITEM_TAB_SIZE) + event_error("slo udlosti u vci je neplatn. Specproc nen definovna.",event_number); + cur_event_number=event_number; + return sp_item_table[event_number](event_type,ptr,p); + } + +char call_map_event(int event_number,int sector,int side,int value,int event) + { + if (!event_number) return 0; + if (event_number>=SP_MAP_TAB_SIZE) + event_error("Neplatn slo udlosti na stn. Specproc s tmto slem nen definovna.",event_number); + cur_event_number=event_number; + return sp_map_table[event_number](sector,side,value,event); + } + diff --git a/GAME/SPECPROC.H b/GAME/SPECPROC.H new file mode 100644 index 0000000..a8ca9a3 --- /dev/null +++ b/GAME/SPECPROC.H @@ -0,0 +1,39 @@ + + +#define SMPR_WALK 1 +#define SMPR_ATTACK 2 +#define SMPR_KNOCK 3 //povoleni, nebo zakazani KNOCK (zakazani = return 1) + +#define SIPR_USAGE 1 +#define SIPR_PICK 2 +#define SIPR_DROP 3 + + +typedef char (*t_mob_proc)(int event_type,TMOB *); +typedef char (*t_item_proc)(int event_type,short *ptr,THUMAN *p); +typedef char (*t_map_proc)(int sector,int side,int value,int event); + +#define MOB_PROC(name) static char name(int event,TMOB *m) +#define ITEM_PROC(name) static char name(int event,short *ptr,THUMAN *p) +#define MAP_PROC(name) static char name(int sector,int side,int value,int event) + +//specproc pro nestvury vraci char informaci +// 1 - nestvura ma jiz zadanou akci a program se zaridi podle pozadavku specproc +// 0 - specproc ignorovala udalost a nestvura se ma chovat stejne jako bez specproc + +//specproc do mapy +// 1 - specproc uspesna +// 0 - specproc neuspesna +// value - je cislo predavane specproc + + +char call_map_event(int event_number,int sector,int side,int value,int event); +char call_item_event(int event_number,int event_type,short *ptr,THUMAN *p); +char call_mob_event(int event_number,int event_type,TMOB *m); + + +//funkce z enemy.c +char mob_check_next_sector(int sect,int dir,char alone,char passable); + //alone = MOB_BIG, passable= 1 je-li pruchozi +extern char mob_go_x[]; +extern char mob_go_y[]; diff --git a/GAME/TRANSAV.C b/GAME/TRANSAV.C new file mode 100644 index 0000000..009df02 --- /dev/null +++ b/GAME/TRANSAV.C @@ -0,0 +1,682 @@ +#include +#include +#include +#include +#include +#include +#include +#define EVENT_MSG long +#include "globals.h" +#include +#include +#include + +TSTR_LIST skini; + +#define PLAYERS 3 + +void *datablast; +long datablastsize; +char *lasterror=NULL; +char relarr[6]; +char szBuff[65536]; +char sekceid[]=""; + +typedef struct s_save + { + int viewsector; + int viewdir; + int gold; + short cur_group; + char autosave; + char enable_sort; + char shownames; + char showlives; + char zoom_speed; + char turn_speed; + char autoattack; + char music_vol; + char sample_vol; + char xbass; + char bass; + char treble; + char stereing; + char swapchans; + char out_filter; + long glob_flags; + long game_time; + char runes[5]; + char level_name[12]; + short picks; //pocet_sebranych predmetu v mysi + short items_added; //pocet_pridanych predmetu + int sleep_long; + int game_flags; + }S_SAVE; + +typedef struct tkouzlo + { + word num,um,mge; + word pc; + short owner,accnum; //accnum = akumulacni cislo, owner = kdo kouzlo seslal + int start; + short cil; //kladna cisla jsou postavy zaporna potvory (0 je bez urceni postavy) + char povaha; + word backfire; //backfire / 1 = demon , 0 = bez demona + word wait; //wait - cekani pocet animaci + word delay; //delay - cekani pocet kol + char traceon; //jinak noanim - neprehravaji se animace a zvuky + char spellname[30]; + }TKOUZLO; + + +typedef struct _tkzlall + { + TKOUZLO kouzlo; + short vlstab[24]; + long flagmap; + }TKZLALL; + +THUMAN postavy[6],postavy2[6]; +S_SAVE s; +char mapname[13]; +int startsect; +int startsid; + + +char cz_table_1[]=" 1!3457908+,-./+\"?=:_2ABCDEFGHIJKLMNOPQRSTUVWXYZ\\)6=;abcdefghijklmnopqrstuvwxyz/|(; "; +char cz_table_2[]=" !\"#$%&'()*+,-./0123456789:;<=>?@BCDFGHJKMNPQSTVWXZ[\\]^_`bcdfghjkmnpqstvwxz{|}~ "; +char cz_table_3[]=" !\"#$%&'()*+,-./0123456789:;<=>?@ABFGHIJKMPQVWXY[\\]^_`abfghijkmpqvwxy{|}~ "; +char *cz_key_tabs[]={cz_table_1,cz_table_2,cz_table_3}; + +word keyconv(word key) + { + int i; + static char cz_mode=0; + char c,d; + + i=key; + d=i>>8; + c=i & 0xff; + if (c=='+' && d<55 && !cz_mode) cz_mode=2; + else if (c=='=' && d<55 && !cz_mode) cz_mode=1; + else if (c>32 && c<127 && d<=53) + { + c=cz_key_tabs[cz_mode][c-32]; + i=d; + i=(i<<8)+c; + cz_mode=0; + return i; + } + else + return i; + + return 0; + } + + +#define ZAKLAD_CRC 0xC005 + +static word vypocet_crc(char *data,long delka) + { + unsigned long l=0; + do + { + l=(l<<8)|(delka>0?*data++:0);delka--; + l=(l<<8)|(delka>0?*data++:0);delka--; + l%=ZAKLAD_CRC; + } + while(delka>-1); + return l & 0xffff; + } + +static simple_cz_input(char *buff,int maxchars) + { + int cnt=strlen(buff); + int w; + char *a; + a=alloca(cnt+1); + strcpy(a,buff); + maxchars--; + cputs(buff); + do + { + w=_bios_keybrd(_KEYBRD_READ); + w=keyconv(w); + if (w==0) continue; + switch (w & 0xff) + { + case 13: return; + case 0x8: if (cnt>0) + { + cnt--;buff[cnt]=0;cputs("\x8 \x8"); + } + break; + case 0:break; + case 27:strcpy(buff,a); + return; + default: if (cntkouzlo.cil-1; + + if (kzl->kouzlo.cil>0) + { + for (j=0;j<22;j++) h->stare_vls[j]+=kzl->vlstab[j]; + h->stare_vls[VLS_KOUZLA]&=~(kzl->flagmap & 0xffff); + } + } + } + +void zero_inv(THUMAN *h) + { + h->inv_size=6; + memset(h->inv,0,sizeof(h->inv)); + memset(h->wearing,0,sizeof(h->wearing)); + memset(h->prsteny,0,sizeof(h->prsteny)); + memcpy(h->vlastnosti,h->stare_vls,sizeof(h->vlastnosti)); + h->demon_save=NULL; + h->sektor=startsect; + h->direction=startsid; + h->groupnum=1; + } + + +void zero_all_inv() + { + THUMAN *h=postavy;int i; + + for (i=0;i<6;i++,h++) if (h->used) zero_inv(h); + } + +void unpack_save(void *in) + { + int kouzel; + TKZLALL *kzl; + int i; + + in=loadmem(&s,in,sizeof(s)); //load basic info + in=(void *)((char *)in+s.picks*2+s.items_added*sizeof(TITEM)); //skip items; + in=loadmem(&kouzel,in,sizeof(kouzel)); //load spell table + kzl=in; //signup spell table for future use + in=(void *)((char *)in+sizeof(TKZLALL)*kouzel); + in=loadmem(postavy,in,sizeof(postavy)); //load character table + for (i=0;i<6;i++) + if (postavy[i].demon_save!=NULL) //correct demons; + in=loadmem(postavy+i,in,sizeof(THUMAN)); + //skip dialog info. + //load done; + return_spells(kouzel,kzl); + zero_all_inv(); + s.viewsector=startsect; + s.viewdir=startsid; + s.picks=0; + s.items_added=0; + s.glob_flags=0; + s.game_time=0; + strncpy(s.level_name,mapname,12); + memset(s.runes,0,sizeof(s.runes)); + } + +void del_character(char c) + { + int i; + for(i=c;i<5;i++) relarr[i]=relarr[i+1]; + relarr[i]=0; + } + +void add_character(char c) + { + THUMAN *h=postavy+c; + int i; + + if (!h->used) + { + lasterror="Musis vybrat postavu!";return; + } + for (i=0;i<6;i++) if (relarr[i]==c+1) + { + del_character(i);return; + } + for (i=0;i<6;i++) if (!relarr[i]) break; + if (i==6) + { + lasterror="Nevim sice jak se ti to povedlo, ale neni uz misto!";return; + } + relarr[i]=c+1; + } + +char nvlast[][16]= + {"Sila","Schopnost magie","Pohyblivost","Obratnost","Max zraneni", + "Kondice","Max mana","Obrana(dolni)","Obrana(Horni)","Utok(Dolni)", + "Utok(Horni)","Ohen","Voda","Zeme","Vzduch","Mysl","Zivoty Regen", + "Mana Regen","Kondice Regen","Magicka sila(D)", "Magicka sila(H)","","Ucinnek zasahu","*"}; + +char *zbrane[]={"Mec","Sekera","Kladivo","Hul","Dyka","Strelne","Specialni"}; + + +char build_players() + { + int i; + char z=0; + + memset(postavy2,0,sizeof(postavy2)); + for (i=0;i<6;i++) + if (relarr[i])postavy2[i]=postavy[relarr[i]-1],z=1; + return z; + } + +void c_info(int b) + { + THUMAN *h=postavy+b; + int i; + + do + { + _clearscreen(_GCLEARSCREEN); + for(i=0;i<22;i++) + { + cprintf("%-17s %3d ",nvlast[i],h->stare_vls[i]); + if (i<7) + cprintf("%-12s %3d ",zbrane[i],h->bonus_zbrani[i]); + if (i<7) + switch (i) + { + case 0: cprintf("Jmeno: %s",h->jmeno);break; + case 1: cprintf("Uroven: %d",h->level);break; + case 2: cprintf("Zkusenost: %d",h->exp);break; + case 3: cprintf("Pohlavi: %s",h->female?"Zena":"Muz");break; + case 4: cprintf("Portret: XICHT%02X.PCX",h->xicht);break; + case 5: cprintf("Jidlo: %d",h->jidlo/360);break; + case 6: cprintf("Voda: %d",h->voda/360);break; + } + cprintf("\n\r"); + } + cprintf("ENTER - zmena jmena, P - pohlavi, X - vzhledu, ESC - navrat:"); + do + {i=toupper(getche());putch(8);} + while (i!=13 && i!='X' && i!=27 && i!='P'); + if (i==13) + { + cprintf("\r\n\n Zmen jmeno:");simple_cz_input(h->jmeno,sizeof(h->jmeno)); + } + else if (i=='X') + { + cprintf("\r\n\n Jelikoz jednoduchost tohoto programu neumoznuje prohizet si obrazky je nutne\n\r" + "tuto volbu odzkouset metodou pokus omyl. Nikdo totiz nezaruci, zda v novem \n\r" + "dobrodruzstvi se nektere z postav nezmeni pohlavi (na obrazku).\r\n" + "V puvodnim SKELDALU:\n\r" + "--------------------\n\r" + "Muzi: 0, 2, 3, 4, 8(Roland), 12(Gralt), 13(Erik)\n\r" + "Zeny: 1, 5, 6, 7\n\r" + "\nZmenit vzhled <%d>, 'x' storno:",h->xicht); + if (scanf("%hd",&h->xicht)==0) while (getchar()!='\n'); + } + else if (i=='P') h->female=!h->female; + } + while (i!=27) ; + } + + +char assign_players() + { + int i; + char c; + char backrel[6]; + + do + { + _clearscreen(_GCLEARSCREEN); + if (lasterror!=NULL) cprintf("%s\x7\r\n\n",lasterror); + lasterror=NULL; + memset(backrel,0,sizeof(backrel)); + for (i=0;i<6;i++) if (relarr[i]) backrel[relarr[i]-1]=i+1; + cprintf("%-33s%s\n\r====================================================\n\r","Stare dobrodruzstvi","Nove dobrodruzstvi"); + for(i=0;i<6;i++) + { + if (postavy[i].used) + cprintf("%c%d.%-30s",backrel[i]?'*':' ',i+1,postavy[i].jmeno); + else + cprintf(" %d.%-30s",i+1,""); + if (relarr[i]) + cprintf("%c.%-30s",i+'a',postavy[relarr[i]-1].jmeno); + else + cprintf("%c.%-30s",i+'a',""); + cputs("\n\r"); + } + cputs("\n\r"); + cputs("[1]-[6] prenese postavu,\n\r" + "[a]-[f] maze postavu.\n\r" + "[SHIFT]+[1]-[6] info o postave\n\r" + "[S] ulozit\n\r" + "[Q] nebo [ESC] konec bez ulozeni\n\n\r"); + cprintf("Doporuceny pocet postav v novem dobrodruzstvi je %d.\n\r",PLAYERS); + putch('>'); + i=_bios_keybrd(_KEYBRD_READ); + c=toupper(i & 0xff);i>>=8; + switch (c) + { + case 27: + case 'Q':return 1; + case 'S':return 0; + default: + if (i==0) lasterror="Prepni na anglickou klavesnici!!!"; + if (i>=2 && i<=7) + if (*(char *)0x417 & 0x3) c_info(i-2); + else add_character(i-2); + if (c>='A' && c<='F') del_character(c-'A'); + break; + } + } + while(1); + } + +char *scan_saves(char *text,char *path,char mustexists) + { + int i; + FILE *f; + + do + { + _clearscreen(_GCLEARSCREEN); + cprintf("%s\n\r============================\n\r",text); + if (lasterror!=NULL) cprintf("%s\x7\r\n\n",lasterror); + lasterror=NULL; + for(i=0;i<10;i++) + { + sprintf(szBuff,"%sSLOT%02d.SAV",path,i); + cprintf("%d. ",(i+1)%10); + f=fopen(szBuff,"rb"); + if (f!=NULL) + { + fread(szBuff,1,34,f);szBuff[34]=0; + fclose(f); + cprintf("%s\r\n",szBuff); + } + else + cputs("\r\n"); + } + cputs("\nVyber [1]-[9] a [0] pozici.\n\r[ESC] zrusit.\n\r"); + do + i=_bios_keybrd(_KEYBRD_READ)>>8; + while (i>11); + if (i==1) return NULL; + if (i==0) lasterror="Prepni na anglickou klavesnici!!!"; + else + { + i-=2; + sprintf(szBuff,"%sSLOT%02d.SAV",path,i); + if (!mustexists || access(szBuff,F_OK)==0) return szBuff; + } + } + while(1); + } + +int tracemap(char *name) + { + FILE *f; + void *section; + int type; + long size,s; + + f=fopen(name,"rb"); + if (f==NULL) return -1; + do + { + s=load_section(f,§ion,&type,&size); + if (s!=size) + { + free(section); + fclose(f); + return -1; + } + if (type==A_MAPGLOB) + { + MAPGLOBAL mglob; + memcpy(&mglob,section,sizeof(mglob)); + startsect=mglob.start_sector; + startsid=mglob.direction; + } + free(section); + } + while (type!=A_MAPEND); + fclose(f); + return 0; + } + +void *build_gametmp(int *size) + { + int siz=*size; + void *zac,*p; + int i,crc; + + siz+=256; + p=zac=malloc(siz); + p=addmem(p,&s,sizeof(s)); //add game info + //skip picks + //skip items added + i=0;//no spells; + p=addmem(p,&i,4); + p=addmem(p,postavy2,sizeof(postavy2)); + p=addmem(p,&i,4); //no dialogs... + *size=(char *)p-(char *)zac; + crc=vypocet_crc(zac,*size); + p=addmem(p,&crc,2); + size[0]+=2; + return zac; + } + +void save_savegame(char *soubor) + { + FILE *f; + void *p; + int s; + + f=fopen(soubor,"wb"); + strcpy(szBuff,"TRANSAV"); + fwrite(szBuff,SAVE_NAME_SIZE,1,f); + strcpy(szBuff,"_GAME.TMP"); + fwrite(szBuff,12,1,f); + s=datablastsize; + p=build_gametmp(&s); + fwrite(&s,4,1,f); + fwrite(p,s,1,f); + free(p); + szBuff[0]=0; + fwrite(szBuff,12,1,f); + fclose(f); + } + +void begin_program(char *sourceadv,char *targetadv) + { + TSTR_LIST src,trg; + char *c; + + src=read_config(sourceadv); + if (src==NULL) + { + cprintf("Nemohu otevrit zdrojove dobrodruzstvi: %s\n\r",sourceadv); + exit(1); + } + trg=read_config(targetadv); + if (trg==NULL) + { + cprintf("Nemohu otevrit cilove dobrodruzstvi: %s\n\r",targetadv); + exit(1); + } + c=get_text_field(trg,"DEFAULT_MAP"); + if (c==NULL) + { + cprintf("Vystupni dobrodruzstvi %s musi obsahovat polozku DEFAULT_MAP\n\r", targetadv); + exit(1); + } + strncpy(mapname,c,12);mapname[12]=0; + c=get_text_field(trg,"CESTA_MAPY"); + if (c==NULL) + { + cprintf("Vystupni dobrodruzstvi %s musi obsahovat polozku CESTA_MAPY\n\r", targetadv); + exit(1); + } + sprintf(szBuff,"%s%s",c,mapname); + if (tracemap(szBuff)) + { + cprintf("Nemohu precist mapu %s\n\r",szBuff); + exit(1); + } + c=get_text_field(trg,"CESTA_POZICE"); + if (c==NULL) + { + cprintf("Vystupni dobrodruzstvi %s musi obsahovat polozku CESTA_POZICE\n\r", targetadv); + exit(1); + } + c=get_text_field(src,"CESTA_POZICE"); + if (c==NULL) + { + cprintf("Vstupni dobrodruzstvi %s musi obsahovat polozku CESTA_POZICE\n\r", sourceadv); + exit(1); + } + c=scan_saves("Vyber pozici:",c,1); + if (c==NULL) exit(0); + load_specific_file(c,"_GAME.TMP",&datablast,&datablastsize); + if (datablast==NULL) + { + cprintf("Soubor %s: Pristup odmitnut - pozice je pozkozena!\n\r",c); + exit(1); + } + unpack_save(datablast); + do + { + do + if (assign_players()) exit(1); + while (!build_players()); + zpet: + c=get_text_field(trg,"CESTA_POZICE"); + c=scan_saves("Ulozit na pozici:",c,0); + } + while (c==NULL); + if (access(c,F_OK)==0) + { + cprintf("Prejes si prepsat existujici pozici? (A/cokoliv):"); + if (toupper(getche())!='A') goto zpet; + } + save_savegame(c); + } + +static char help1[]= + "Tento program prenasi ulozene pozice mezi jednotlivymi dobrodruzstvimi.\n\r" + "Jelikoz ulozena pozice je znacne zavisla na mapach a definicich, je mozne\n\r" + "timto programem prenaset pouze charakteristiky postav. Navic se mohou \n\r" + "objevit nejake komplikace vznikle s nemoznosti predvidat komplexnost obou\n\r" + "dobrodruzstvi.\n\r\n" + "Program ma dva zapisy parametru:\n\r" + "================================\n\r\n" + "TRANSAV \n\r\n" + " Prenasi puvodni pozici ze hry Brany Skeldalu do noveho dobrodruzstvi\n\r\n" + "TRANSAV \n\r\n" + " Prenasi pozici mezi dvema dobrodruzstvi\n\r\n"; +static char help2[]= + "Jak uz bylo receno, prenasi se pouze charakteristiky postav. Neprenasi se\n\r" + "predmety a runy. Nova pozice se jmenuje TRANSAV, pak si ji prejmenujte. \n\r" + "Ihned po nahrati prenesene pozice okamzite tuto pozici opet ulozte, aby SKELDAL\n\r" + "doplnil chybejici informace vztahujici se k novemu dobrodruzstvi. \n\r" + "V pokrocilejsich castech hry mohou tyto chybejici informace zpusobovat nejake\n\r" + "komplikace...\n\r\n" + "Prenasec pozic pro Vas napsal Ondrej Novak, programator hry Brany Skeldalu.\n\r\n" + "PS: Deaktivujte ovladace ceske klavesnice!!!\n\r"; + +void main(int argc,char **argv) + { + char szbuff[20]; + + if (argc!=2 && argc!=3) + { + cputs(help1); + cputs("--- klavesu ---");getche();putch('\r'); + cputs(help2); + return; + } + memset(relarr,0,sizeof(relarr)); + if (argc==2) + begin_program("SKELDAL.INI",argv[1]); + else + begin_program(argv[1],argv[2]); + } + + + + + diff --git a/GAME/WIZARD.C b/GAME/WIZARD.C new file mode 100644 index 0000000..afbf429 --- /dev/null +++ b/GAME/WIZARD.C @@ -0,0 +1,758 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "globals.h" +#include +#include + +void kamenik2windows(const char *src, int size, char *trg); + +#define BREAK + +static HWND hWizardDlg=NULL; +static HWND hWizardText; +static HFONT hfCourier; + +static void wzprintf(const char *text,...) + { + int len=GetWindowTextLength(hWizardText); + char *c=(char *)alloca(len+1024); + char *d; + va_list args; + + GetWindowText(hWizardText,c,len+1024); + if (len>10000) c+=1024; + d=strchr(c,0); + va_start(args,text); + _vsnprintf(d,1020,text,args); + SetWindowText(hWizardText,c); + len=strlen(c); + SendMessage(hWizardText,EM_SETSEL,len,len); + SendMessage(hWizardText,EM_SCROLLCARET,0,0); + } + +static void wzputs(const char *text) + { + wzprintf(text); + wzprintf("\r\n"); + } + +static void wzcls() + { + SetWindowText(hWizardText,""); + } + +static LRESULT InputWindow(HWND hDlg,UINT msg, WPARAM wParam,LPARAM lParam) + { + static char *buff; + switch (msg) + { + case WM_INITDIALOG: + buff=(char *)lParam; + SetDlgItemText(hDlg,IDC_PROMPT,buff); + hDlg=GetWindow(hDlg,GW_OWNER); + EnableWindow(hDlg,TRUE); + return 0; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDCANCEL: EndDialog(hDlg,0);break; + case IDOK: + GetDlgItemText(hDlg,IDC_VALUE,buff,1020); + EndDialog(hDlg,1); + break; + } + break; + default: return 0; + } + return 1; + } + +static LRESULT CALLBACK ListWindow(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + case IDCANCEL: PostQuitMessage(LOWORD(wParam));break; + case IDC_LIST: if (HIWORD(wParam)==LBN_DBLCLK) PostQuitMessage(IDOK);break; + default: return 0; + } + default: return 0; + } + return 1; +} + +static HWND PrepareListWindow(HWND parent) +{ + HWND res; + RECT rc1,rc2; + GetWindowRect(parent,&rc1); + EnableWindow(parent,0); + res=CreateDialog(GetModuleHandle(0),MAKEINTRESOURCE(IDD_LISTDIALOG),parent,(DLGPROC)ListWindow); + GetWindowRect(res,&rc2); + rc2.right=rc2.right-rc2.left; + rc2.bottom=rc2.bottom-rc2.top; + rc2.left=(rc1.left+rc1.right-rc2.right)/2; + rc2.top=(rc1.top+rc1.bottom-rc2.right)/2; + SetWindowPos(res,0,rc2.left,rc2.top,rc2.right,rc2.bottom,SWP_NOZORDER); + ShowWindow(res,SW_SHOW); + + return res; +} + +static void CloseListWindow(HWND wnd) +{ + HWND parent=GetParent(wnd); + DestroyWindow(wnd); + EnableWindow(parent,1); +} + +static int PumpDialogMessages(HWND dlg) +{ + MSG msg; + while (GetMessage(&msg,0,0,0)) + { + if (!IsDialogMessage(dlg,&msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + return msg.wParam; +} + + +static int wzscanf(const char *prompt, const char *format,...) + { + char buff[1024]; + va_list args; + unsigned long data[10]; + int i; + + static char notallowed=0; + + if (notallowed) return 0; + notallowed=1; + + strcpy(buff,prompt); + if (DialogBoxParam(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_INPUTWINDOW),GetActiveWindow(),(DLGPROC)InputWindow,(LPARAM)buff)==0) + { + notallowed=0; + return 0; + } + + notallowed=0; + + va_start(args,format); + for (i=0;i<10;i++) data[i]=va_arg(args,unsigned long); + return sscanf(buff,format,data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7],data[8],data[9]); + } + +char *side_flags[]= + { + "AUTOMAP", + "!PLR", + "!MONST", + "!THING", + "!SOUND", + "ALARM", + "PASS", + "TRANSPARENT", + "P_ANIM", + "P_VIS", + "P_PING", + "P_FORW", + "S_ANIM", + "S_VIS", + "S_PING", + "S_FORW", + "LEFT_A", + "RIGHT_A", + "ALT_SIDES", + "SPEC", + "COPY", + "SEND", + "APLY2ND", + "AUTOANIM", + "", + "", + "", + "", + "", + "SECRET", + "TRUESEE", + "INVIS" + }; + +char *obl_flags[]= + { + "RECESS", + "UP_SIDE", + "DOWN_SIDE", + "ITPUSH" + }; + +char *mc_flags[]= + { + "MAPPED", + "FLY_OBJECT", + "PLAYER", + "DEAD_PLAYER", + "SPECTXTR", + "SAFEPLACE", + "UNUSED", + "MARKED!", + "SHADED", + "STAIRS", + "DOWN", + "!AUTOMAP", + "!SUMMON" + }; + +void mman_scan(int action) + { + extern char screenstate; + static pos=0,zavora=0; + MEMORYSTATUS mmi; + char c[10]; + if (screenstate && !zavora) + { + zavora=1; + switch(action) + { + case MMA_SWAP:curcolor=RGB555(31,0,0);break; + case MMA_READ:curcolor=RGB555(0,31,0);break; + case MMA_SWAP_READ:curcolor=RGB555(0,0,31);break; + case MMA_FREE:curcolor=RGB555(31,31,31);break; + } + bar(pos,0,pos+16,16); + get_mem_info(&mmi); + set_font(H_FBOLD,RGB555(31,31,31)); + curcolor=0; + bar(16,0,66,16); + position(16,0);sprintf(c,"%d",mmi.dwAvailPageFile/1024); + outtext(c); + showview(pos,0,66,16); + zavora=0; + } + } + +void show_flags(int number,char **flags,char nums) + { + int i=0; + while (nums--) + { + if (number & 1) wzprintf("%s ",flags[i]); + i++; + number>>=1; + } + } + +void spell_group_invis() + { + int i; + char ok=1; + + for(i=0;ijidlo/MAX_HLAD(human_selected); + mv=(float)human_selected->voda/MAX_ZIZEN(human_selected); + human_selected=h; + h->exp=level_map[level-2]; + check_player_new_level(h); + if (auto_advance) + { + int vlssuma=h->vlastnosti[VLS_SILA]+ + h->vlastnosti[VLS_OBRAT]+ + h->vlastnosti[VLS_POHYB]+ + h->vlastnosti[VLS_SMAGIE]; + int b,i; + + for(i=0;i<4;i++) + { + b=h->vlastnosti[i]*h->bonus/vlssuma; + h->bonus-=b;vlssuma-=h->vlastnosti[i]; + while (b--) advance_vls(i); + } + prepocitat_postavu(human_selected); + } + human_selected->jidlo=(int)(mh*MAX_HLAD(human_selected)); + human_selected->voda=(int)(mv*MAX_ZIZEN(human_selected)); + wzprintf("%s ziskal%s uroven cislo %d\r\n",h->jmeno,h->female?"a":"",level); + } + + +extern char folow_mode; +extern char folow_mob; +void macro_drop_item(); + +static char take_money() + { + int i; + if (!wzscanf("Kolik: (0 - zrusit):","%d",&i)) return 0; + money+=i; + if (i) + { + SEND_LOG("(WIZARD) Take Money %d, total %d",i,money); + } + return (i!=0); + } + +#define ALL "ALL" +static char purge_map() + { + char buffer[200]; + char *c; + + STOP(); +/* struct find_t rc; + int rs; + + concat(c,pathtable[SR_TEMP],"*.TMP"); + rs=_dos_findfirst(c,_A_NORMAL,&rc); + while (rs==0) + { + if (rc.name[0]!='~') wzputs(rc.name); + rs=_dos_findnext(&rc); + } + _dos_findclose(&rc);*/ + wzprintf("\r\n Zadej jmeno tempu (all - vse):");gets(buffer); + if (buffer[0]==0) return 0; + strupr(buffer); + concat(c,pathtable[SR_TEMP],buffer); + if (strcmp(buffer,ALL) && access(c,0)) + { + wzputs("Soubor nenalezen!"); + return 0; + } + SEND_LOG("(WIZARD) Purge Map: '%s'",buffer,0); + if (!strcmp(buffer,ALL)) purge_temps(0); + else remove(c); + return 1; + } + +static char heal_meditate(void) + { + int a,b,i; + THUMAN *p; + + if (!wzscanf("Obnovit postavu c: (0 - vsechny, -1 - zrusit):","%d",&b)) return 0; + if (b==-1) return 0; + if (b) a=b-1;else a=0,b=POCET_POSTAV; + p=postavy+a; + for(i=a;iused && p->lives) + { + p->lives=p->vlastnosti[VLS_MAXHIT]; + p->mana=p->vlastnosti[VLS_MAXMANA]; + p->kondice=p->vlastnosti[VLS_KONDIC]; + p->jidlo=MAX_HLAD(p); + p->voda=MAX_ZIZEN(p); + SEND_LOG("(WIZARD) Restoring character '%s'",p->jmeno,0); + bott_draw(1); + } + return 1; + } + +static char raise_death(void) + { + int b; + THUMAN *p; + char *c,*d; + + if (!wzscanf("Obzivit postavu c: (0 a -1 - zrusit):","%d",&b)) return 0; + b--; + if (b<0) return 0; + p=postavy+b; + p->lives=p->vlastnosti[VLS_MAXHIT]; + p->mana=p->vlastnosti[VLS_MAXMANA]; + p->kondice=p->vlastnosti[VLS_KONDIC]; + c="(WIZARD) '%s' has been returned to game by gods power!";d=strchr(c,'\''); + wzprintf(d,p->jmeno);putchar('\r\n'); + bott_draw(1); + return 0; + } + + static char raise_killed_monster(HWND hDlg) + { + HWND listdlg=PrepareListWindow(hDlg); + HWND list=GetDlgItem(listdlg,IDC_LIST); + char buff[256]; + int i; + int res; + + for (i=0;ibonus_zbrani[i],h->weapon_expy[i]); + if (!wzscanf(" ","%[^\n]",buff)) return 0; + if (buff[0]==0) return 0; + if (sscanf(buff,"%d %d",&bonus,&value)!=2) wzputs("Huh?!"); + else + { + bonus--; + if (bonus<0 || bonus>=TPW_MAX) wzputs("Spatna zbran"); + else + if (value<0 || value>=10) wzputs("Spatna hodnota"); + else + h->bonus_zbrani[bonus]=value; + } + } + while(1); + } + +static reload_mobs() + { + extern char reset_mobiles; + reset_mobiles=1; + strncpy(loadlevel.name,level_fname,12); + loadlevel.start_pos=viewsector; + loadlevel.name[12]=0; + loadlevel.dir=viewdir; + send_message(E_CLOSE_MAP); + } + +static char display_game_status(void) + { + short *v; + THUMAN *p; + TSTENA *s; + TSECTOR *ss; + register i,cn,astr; + + wzcls(); + SEND_LOG("(WIZARD) Starting wizard window at Sect %d Side %d",viewsector,viewdir); + wzprintf("Sektor: %5d Smer: %d Skupina %d \r\n",viewsector,viewdir,cur_group); + for(i=0,p=postavy;iused) + wzprintf("%d.%-14s (%d) Sek:%5d Smr:%d HPReg:%d MPReg:%d VPReg:%d %04X%s\r\n",i+1,p->jmeno,p->groupnum,p->sektor,p->direction,p->vlastnosti[VLS_HPREG], + p->vlastnosti[VLS_MPREG], p->vlastnosti[VLS_VPREG], p->vlastnosti[VLS_KOUZLA], p->lives?"":"(smrt)"); + else + wzprintf("%d. (nepouzito)\r\n",i); + wzputs(""); + wzprintf("Predmet(y) v mysi: "); + v=picked_item; + if (v==NULL) wzprintf("");else while(*v) wzprintf("%d ",abs(*v++)-1); + wzputs("\r\n"); + for(i=0,cn=0,astr=0;isector_type, ss->floor,ss->ceil,ss->sector_tag,ss->side_tag,ss->action); + wzprintf(" Vychody: Sev %d Vych %d Jih %d Zp %d\r\n",ss->step_next[0],ss->step_next[1],ss->step_next[2],ss->step_next[3]); + wzprintf(" Vlajky: %02X %02X ",ss->flags,map_coord[viewsector].flags);show_flags(map_coord[viewsector].flags,mc_flags,12); + wzputs("\r\n"); + wzprintf("Stena: Prim %d Sec %d Obl %d Anim_prim %d/%d Anim_sec %d/%d\r\n", + s->prim,s->sec,s->oblouk & 0xf,s->prim_anim>>4,s->prim_anim & 0xf,s->sec_anim>>4,s->sec_anim & 0xf); + wzprintf(" Cil akce %d Smer akce %d Akce %d\r\n",s->action,s->sector_tag,s->side_tag & 0x3); + wzprintf(" Multiakce: %s\r\n",macros[viewsector*4+viewdir]==NULL?"":"Existuje"); + wzprintf(" Vlajky: %04X %02X %02X ",s->flags,s->oblouk>>4,s->side_tag>>2); + wzputs(""); + show_flags(s->flags,side_flags,32); + show_flags(s->oblouk>>4,obl_flags,4); + return 0; + } + +static LRESULT WizardDlgProc(HWND hDlg,UINT msg, WPARAM wParam,LPARAM lParam) + { + int i; + switch (msg) + { + case WM_INITDIALOG: + hWizardDlg=hDlg; + hWizardText=GetDlgItem(hDlg,IDC_OUTPUT); + SendMessage(hWizardText,WM_SETFONT,(WPARAM)hfCourier,1); + display_game_status(); + SetTimer(hDlg,10,20,NULL); + return 0; + case WM_TIMER: do_events();return 1; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDCANCEL: EndDialog(hDlg,0);return 0; + case IDC_CLEARMAP: + { + HWND listwnd=PrepareListWindow(hDlg); + HWND list=GetDlgItem(listwnd,IDC_LIST); + int res; + ListBox_AddString(list,"Clear Monsters"); + ListBox_AddString(list,"Clear Items"); + res=PumpDialogMessages(listwnd); + if (res==IDOK) + { + if (ListBox_GetSel(list,0)) + { + for(i=0;i:","%d %d",&i,&j)) return 0; + c=MessageBox(GetActiveWindow(),"Automaticky?","?",MB_YESNO|MB_ICONQUESTION); + if (i>0) advence_player(i-1,j,c==IDYES);else + for(i=0;i:",mapsize-1); + if (!wzscanf(prompt,"%d",&viewsector)) return 0; + chod_s_postavama(1); + SEND_LOG("(WIZARD) Goto %d",viewsector,0); + return 0; + } + case IDC_LOADMAP: + if (!wzscanf("Load Map ","%s %hd",loadlevel.name,&loadlevel.start_pos)) return 0; + for(i=0;imsg==E_KEYBOARD) + { + c=(*(int *)msg->data)>>8; + msg->msg=-1; + switch (c) + { + case 'C': + case 'D': + unwire_proc(); + OpenWizard(); + wire_proc(); + showview(0,0,0,0); + break; + case '<':show_debug=!show_debug;break; + case '=':show_lives=!show_lives;break; + case '>':if (mman_action!=NULL) mman_action=NULL;else mman_action=mman_scan;break; + case '@':set_immortality();set_nohassle();break; + case 'A':bott_draw_fletna();break; + case 'B':wire_global_map();break; + case '?':cur_group=10;break;/*folow_mode=!folow_mode; + if (folow_mode) folow_mob=mob_map[map_sectors[viewsector].step_next[viewdir]]-1; + else for(c=0;cmsg=E_KEYBOARD;break; + + } + } + return; + } + +void install_wizard() + { + send_message(E_ADD,E_KEYBOARD,wizard_kbd); + } + + + diff --git a/GAME/WIZARD.H b/GAME/WIZARD.H new file mode 100644 index 0000000..718a3b5 --- /dev/null +++ b/GAME/WIZARD.H @@ -0,0 +1 @@ +void install_wizard(); diff --git a/GAME/engine2.c b/GAME/engine2.c new file mode 100644 index 0000000..6e3777c --- /dev/null +++ b/GAME/engine2.c @@ -0,0 +1,1315 @@ +#include +#include "types.h" +#include "Engine1.h" +#include + + +typedef ZOOMINFO tzoom; + +extern ZOOMINFO zoom; +extern word *screen; + +void sikma_zleva(void) +{ + + word *scr = (word *)zoom.startptr; + const word *palette = (word *)zoom.palette; + word cy = zoom.ycount; + const unsigned char *pixmap = zoom.texture; + const short *ytable = zoom.ytable; + while (cy) { + const long *xtable = zoom.xtable; + word cx = zoom.xmax; + word *scr_iter = scr; + const unsigned char *pixmap_iter = pixmap; + while (cx > 0) { + unsigned char pb = *pixmap_iter++; + pixmap_iter+=*xtable; + xtable++; + if (pb == 1) break; + if (pb != 0) *scr_iter = palette[pb]; + scr_iter++; + cx--; + } + pixmap+=zoom.texture_line*(*ytable); + ytable++; + scr-=scr_linelen2; + cy--; + } + + + + /* + + + __asm + { + mov edi,zoom ;nacti ukazatel do obrazovky + mov ebx,[zoom]tzoom.palette ;ukazatel na paletu + mov cx,short ptr [zoom]tzoom.ycount ;velikost textury na y + shl ecx,16 ;vloz do horni pulky ecx + mov esi,[zoom]tzoom.texture ;nacti ukazatel na texturu + skzl3: mov edx,[zoom]tzoom.xtable ;nacti ukazetel na zvetsovaci tabulku x + push esi ;uchovej esi + push edi ;uchovej edi + mov cx,[zoom]tzoom.xmax + skzl1: xor eax,eax ;vynuluj eax pro spravny vypocet + lodsb ;nacti bod + add esi,[edx] ;posun se od nekolik pozic v texture podle hodnoty v tabulce x + add edx,4 ;posun se v tabulce x o dalsi polozku + or al,al ;test bodu na nulu + jz skz1 ;preskoc transparetni barvu + cmp al,1 ;test bodu na jedna + jz skz2 ;ukonci kresleni linky pokud narazi na 1 + mov ax,[eax*2+ebx] ;konverze barvy podle palety + mov [edi],ax ;nakresli bod na obrazovce + skz1: add edi,2 ;dalsi pozice + dec cx + jnz skzl1 ;opakuj dokola + skz2: pop edi ;obnov edi + pop esi ;obnov esi + mov edx,[zoom]tzoom.ytable ;vyzvedni ukazatel na ytable + mov cx,[edx] ;cx - o kolik pozic se mam v texture posunout dolu + or cx,cx + jz skzskp + skzl2: add esi,[zoom]tzoom.texture_line ;posun o jednu pozici + dec cx ;sniz citac + jnz skzl2 ;dokud neni nula + skzskp:add edx,2 ;dalsi hodnota v tabulce + mov [zoom]tzoom.ytable,edx ;uloaz na puvodni misto + sub edi,[zoom]tzoom.line_len ;odecti tolik, kolik odpovida lince na obrazovce + sub ecx,10000h ;sniz horni pulku ecx o jedna + jnz skzl3 ;opakuj dokud neni nula + }*/ +} + +void sikma_zprava(void) +{ + + word *scr = (word *)zoom.startptr; + const word *palette = (word *)zoom.palette; + word cy = zoom.ycount; + const unsigned char *pixmap = zoom.texture; + const short *ytable = zoom.ytable; + while (cy) { + const long *xtable = zoom.xtable; + word cx = zoom.xmax; + word *scr_iter = scr; + const unsigned char *pixmap_iter = pixmap; + while (cx > 0) { + unsigned char pb = *pixmap_iter++; + pixmap_iter+=*xtable; + xtable++; + if (pb == 1) break; + if (pb != 0) *scr_iter = palette[pb]; + scr_iter--; + cx--; + } + pixmap+=zoom.texture_line*(*ytable); + ytable++; + scr-=scr_linelen2; + cy--; + } +/* + __asm + { + mov edi,zoom ;nacti ukazatel do obrazovky + mov ebx,[zoom]tzoom.palette ;ukazatel na paletu + mov cx,short ptr [zoom]tzoom.ycount ;velikost textury na y + shl ecx,16 ;vloz do horni pulky ecx + mov esi,[zoom]tzoom.texture ;nacti ukazatel na texturu +skzp3: mov edx,[zoom]tzoom.xtable ;nacti ukazetel na zvetsovaci tabulku x + push esi ;uchovej esi + push edi ;uchovej edi + mov cx,[zoom]tzoom.xmax +skzp1: xor eax,eax ;vynuluj eax pro spravny vypocet + lodsb ;nacti bod + add esi,[edx] ;posun se od nekolik pozic v texture podle hodnoty v tabulce x + add edx,4 ;posun se v tabulce x o dalsi polozku + or al,al ;test bodu na nulu + jz skz3 ;preskoc transparetni barvu + cmp al,1 ;test bodu na jedna + jz skz4 ;ukonci kresleni linky pokud narazi na 1 + mov ax,[eax*2+ebx] ;konverze barvy podle palety + mov [edi],ax ;nakresli bod na obrazovce +skz3: sub edi,2 ;dalsi pozice + dec cx + jnz skzp1 ;opakuj dokola +skz4: pop edi ;obnov edi + pop esi ;obnov esi + mov edx,[zoom]tzoom.ytable ;vyzvedni ukazatel na ytable + mov cx,[edx] ;cx - o kolik pozic se mam v texture posunout dolu + or cx,cx + jz skpskp +skzp2: add esi,[zoom]tzoom.texture_line ;posun o jednu pozici + dec cx ;sniz citac + jnz skzp2 ;dokud neni nula +skpskp: add edx,2 ;dalsi hodnota v tabulce + mov [zoom]tzoom.ytable,edx ;uloaz na puvodni misto + sub edi,[zoom]tzoom.line_len ;odecti tolik, kolik odpovida lince na obrazovce + sub ecx,10000h ;sniz horni pulku ecx o jedna + jnz skzp3 ;opakuj dokud neni nula + }*/ +} + + +void fcdraw(void *source,void *target, void *table) +//#pragma aux fcdraw parm [EDX][EBX][EAX] modify [ECX ESI EDI]; +{ + + word *src = (word *)source; + word *trg = (word *)target; + T_FLOOR_MAP *t = (T_FLOOR_MAP *)table; + unsigned long cc; + + do { + word *ss = t->txtrofs/2+src; + word *tt = t->lineofs/2+trg; + cc = t->linesize; + memcpy(tt,ss,cc*2); + cc = t->counter; + t++; + } while (cc != 0); +/* + __asm + { + mov edx,source + mov ebx,target + mov eax,table + ;Kresli strop nebo podlahu podle draw_table + ;EDX - sourceTxt + ;EBX - TargerTxt - LineOfset + ; (Lineofs je pocet bajtu odpovidajici + ; souradnicim [0,184] pro podlahu nebo [0,0] + ; pro strop) + ;EAX - draw_table +fcdraw_:mov esi,[eax+12] + mov edi,[eax] + add edi,ebx + add esi,edx + mov ecx,[eax+4] + shr ecx,1 + rep movsd + rcl ecx,1 + rep movsw + mov ecx,[eax+8] + add eax,16 + or ecx,ecx + jnz fcdraw_ + }*/ +} + +void klicovani_anm_back(void *target,void *source); +void klicovani_anm(void *target,void *source,char mirror) +//#pragma aux klicovani_anm parm [edi][esi][eax] modify [ecx edx ebx] +{ + word *t = (word *)target; + word *s = (word *)source; + if (mirror) { + unsigned int l = 180; + while (l > 0) { + unsigned int c = 640; + while (c > 0) { + word p = *s++; + if ((p & 0x8000 ) == 0) { + p = p + (p & ~0x1F); + --c; + t[c] = p; + t[c+scr_linelen2] = p; + --c; + t[c] = p; + t[c+scr_linelen2] = p; + } else { + c-=2; + } + } + t+=2*scr_linelen2; + --l; + } + } else { + + unsigned int l = 180; + while (l > 0) { + unsigned int c = 320; + while (c > 0) { + word p = *s++; + if ((p & 0x8000 ) == 0) { + p = p + (p & ~0x1F); + t[0] = p; + t[scr_linelen2] = p; + ++t; + t[0] = p; + t[scr_linelen2] = p; + ++t; + } else { + t+=2; + } + --c; + } + t+=scr_linelen2; + --l; + } + + } +} + /* + __asm + { + mov edi,target + mov esi,source + + mov cl,180 +ka_lp2: mov ebx,320 +ka_lp1: lodsw + movzx eax,ax + test eax,0x8000 + jnz ka_skip + mov edx,eax + and edx,0x7FE0 + add eax,edx + mov edx,eax + shl edx,16 + add edi,scr_linelen + or eax,edx + mov [edi],eax + sub edi,scr_linelen + mov [edi],eax +ka_skip:add edi,4 + dec ebx + jnz ka_lp1 + sub edi,1280 + add edi,scr_linelen + add edi,scr_linelen + dec cl + jnz ka_lp2 + } +} + +static void klicovani_anm_back(void *target,void *source) +//#pragma aux klicovani_anm parm [edi][esi][eax] modify [ecx edx ebx] +{ + __asm + { + mov edi,target + mov esi,source + + mov ecx,180 + add edi,1280 +kba_lp2: mov ebx,320 +kba_lp1: lodsw + sub edi,4 + movzx eax,ax + test eax,0x8000 + jnz kba_skip + mov edx,eax + and edx,0x7FE0 + add eax,edx + mov edx,eax + shl edx,16 + add edi,scr_linelen + or eax,edx + mov [edi],eax + sub edi,scr_linelen + mov [edi],eax +kba_skip:dec ebx + jnz kba_lp1 + add edi,scr_linelen + add edi,scr_linelen + add edi,1280 + dec ecx + jnz kba_lp2 + } +} +*/ + +#define zobraz_1 \ + __asm lodsb \ + __asm movzx eax,al \ + __asm movzx eax,short ptr [eax*2+ebx] \ + __asm stosw \ + + + +void small_anm_buff(void *target,void *buff,void *paleta) +//#pragma aux small_anm_buff parm[edi][esi][ebx] modify [eax ecx] +{ + word *t = (word *)target; + unsigned char *s = (unsigned char *)buff; + word *p = (word *)paleta; + int i,j; + + for ( i = 0; i < 180; i++) { + for (j = 0; j < 320; j++) { + *t++ = p[*s++]; + } + t+=scr_linelen2-320; + } +/* + __asm + { + mov edi,target; + mov esi,buff; + mov ebx,paleta + + mov ecx,179*10000h +shmab4: mov cx,320 +shmab3: zobraz_1 + dec cx + jnz shmab3 + add edi,640 + sub ecx,010000h + jnc shmab4 + }*/ +} + +void small_anm_delta(void *target,void *buff,void *paleta) +//#pragma aux small_anm_delta parm[edi][esi][ebx] modify [eax ecx] +{ + word *t = (word *)target; + word *pal = (word *)paleta; + unsigned long *deltastart = (unsigned long *)buff; + unsigned long ofs = *deltastart++; + unsigned char *control = (unsigned char *)deltastart; + unsigned char *pixels = control + ofs; + int y; + + for (y = 0; y < 180; y++) { + word *tp = t; + do { + unsigned char c = *control++; + if (c >= 0xc0) { + //skip line + unsigned char d = c - 0xc0; + y+=d; + t+=(d+1)*scr_linelen2; + break; + } else { + tp+=2*c; + c = *control++; + while (c) { + *tp++ = pal[*pixels++]; + *tp++ = pal[*pixels++]; + c--; + } + } + } while (1); + } +} + +/* + + __asm + { + mov edi,target; + mov esi,buff; + mov ebx,paleta + + + mov ch,180 ;180 radek + mov eax,[esi] ;vem offset na delta data + lea edx,[esi+eax+4] ;ebp obsahuje tento offset + lea esi,[esi+4] ;esi obsahuje offset na delta control +shmad5: push edi ;uchovej zacatek radky +shmad3: lodsb ;vem skip hodnotu + mov ah,al ;uchovej ji ah - kvuli destruktivnimu testu + and al,not 3fh ;na posledni 2 bity + cmp al,0c0h ;C0 a vyssi znamenaji ze se preskakuje radek + jz shmad1 ;pri pozitivnim testu je preskoc + movzx eax,ah ;vem skip hodnotu do eax + shl eax,2 ;na obrazovce *2 bodu *1 zoom *2 za bod (x4) + add edi,eax ;pricti k edi + lodsb ;vem copy hodnotu + mov cl,al ;zaved counter + xchg esi,edx ;prohod ukazatele control a data +shmad2: zobraz_1 ;zobraz bod + zobraz_1 ;zobraz bod + dec cl ;opakuj tolikrat kolik je copy hodnota + jnz shmad2 + xchg esi,edx ;prohod ukazatele control a data + jmp shmad3 ;a precti dalsi skip hodnotu +shmad1: pop edi + and ah,03fh ;maskuj spodnich 6 bitu + inc ah ;+1 +shmad4: add edi,scr_linelen + dec ch ;odecti counter radek + dec ah ;odecti counter + jnz shmad4 ;a opakuj ah krat + or ch,ch ;je li counter nulovy tak padame + jnz shmad5 + }*/ + + + +void scroll_and_copy(void *pic,void *slide, void *scr, int _size,int shift, void *lineinfo) +//#pragma aux scroll_and_copy parm[esi][ebx][edi][ecx][edx][eax] +{ + + word *srcpc = (word *)pic; + word *trg = (word *)scr; + word *sld = (word *)slide; + int shiftofs = shift*scr_linelen2; + int lc = _size; + int *lnfo = (int *)lineinfo; + int y; + + for (y = 0; y < lc; y++ ) { + int left = __min(lnfo[0],lnfo[2]); + int right = __max(lnfo[1],lnfo[3]); + int x; + for (x = left; x <= right; x++) { + + word c = sld[x] = sld[x+shiftofs]; + if (c & BGSWITCHBIT) { + trg[x] = srcpc[x]; + } else { + trg[x] = c; + } + } + sld+=scr_linelen2; + trg+=scr_linelen2; + srcpc+=scr_linelen2; + lnfo+=2; + + + } +/* + + + __asm + { + mov esi,pic + mov ebx,slide + mov edi,scr + mov ecx,_size + mov edx,shift + mov eax,lineinfo + ;odscroluje a kopiruje obrazovku do screenu + ;pouzitelne pro titulky + ;0x8000 je transparentni + ;edi screen + ;ebx buffer + ;esi back_picture + ;ecx velikost bufferu (pocet_radku) + ;edx pocet bajtu o kolik je nutne posouvat (*1280) + ;eax - ukazatel na tittle lines + push ebp + mov ebp,eax ;uloz ukazatel na titlelines + mov eax,edx + imul eax,scr_linelen +sac_lp1:push ecx + push eax + mov eax,[ebp] ;nacti zac + mov ecx,[ebp+edx*8] + cmp eax,ecx + jc sac_sk1 + mov eax,ecx +sac_sk1:shl eax,1 ;adresa + add esi,eax ;pricti k pointrum + add edi,eax + add ebx,eax + add ebp,4 ;presun se na kon + shr eax,1 ;eax je zacatek v bodech + mov ecx,[ebp+edx*8] ;vem konec + cmp ecx,[ebp] + jnc sac_sk2 + mov ecx,[ebp] +sac_sk2:push ecx + sub ecx,eax ;kon-zac+1=celk pocet + xchg edx,[esp+4] +sac_lp2:mov eax,[ebx+edx] ;Vem data na dalsim radku + mov [ebx],eax ;Zapis je sem + add ebx,4 ;dalsi pozice + test eax,~BGSWITCHBIT ;je to transparentni? + jz sac_all ;pokud ano, zobraz_obrazek + bt eax,5 ;test bitu 15 + jnc sac_1 ;Neni nastaven - zobraz primo barvu + mov ax,[esi] ;jinak vem barvu z obrazku +sac_1: stosw ;zapis barvu + add esi,2 ;dalsi pozice + rol eax,16 ;presun eax na dolni slovo + bt eax,5 ;test bitu 15 + jnc sac_2 ;neni nastaven - zobraz primo barvu + mov ax,[esi] ;jinak vem barvu z obrazku +sac_2: stosw ;zapis barvu + add esi,2 ;dalsi pozice + jmp sac_end +sac_all:movsd ;presun celeho slova +sac_end:sub ecx,2 ;odecti counter + ja sac_lp2 ;je li nad opakuj + add ecx,640 ;pricti sirku, - kolik jsme prejeli + pop eax + sub ecx,eax ;odecti konec -> kolik preskocit + add ebp,4 ;aktualizuj ukazatele + shl ecx,1 ;v adresach + add esi,ecx + push edx + mov edx,scr_linelen + sub edx,1280 + add ecx,edx + add edi,ecx + add ebx,ecx + pop edx + pop eax + xchg edx,eax + pop ecx ;obnov ecx + dec ecx ;sniz citac radku + jnz sac_lp1 ;dokud neni nula + pop ebp ;obnov ebp + + } + */ +} + +#define pic_start 2+2+2+512*5+512*5 +#define ed_stack 800*4+600*4 +#define ed_stk1 600*4 + + +void enemy_draw(void *src,void *trg,int shade,int scale,int maxspace,int clip) +//#pragma aux enemy_draw parm[ESI][EDI][EBX][EDX][EAX][ECX] +{ + word *picinfo = (word *)src; + word *screen = (word *)trg; + int xtable[800]; + int ytable[1200]; + int xcount; + int ycount; + word pcx = picinfo[0]; + word pcy = picinfo[1]; + unsigned char *picdata = (unsigned char *)src + pic_start; + word *palette = picinfo+shade/2; + int clipl = clip & 0xFFFF; + int clipr = clip >> 16; + int yiter; + + if (maxspace >= 470) return; + + //prepare ytable; + { + int rwofs = pcx*(pcy-1); + int accu = 0; + int *w = ytable; + int sp = maxspace*2; + + while (sp > 0 && rwofs >= 0) { + *w++ = rwofs; + accu+=320; + while (accu >= scale && rwofs >= 0) { + accu-=scale; + rwofs-=pcx; + } + sp--; + } + ycount = w - ytable; + *w++=-1; + //ytable je hotova - obsahuje ofsety v obrazku pro kazdou radku a na konci je -1 + } + + //prepare xtable + { + int *w = xtable; + int ofs = 0; + int accu = 0; + while (ofs < pcx) { + *w++ = ofs; + accu+=320; + while (accu >= scale) { + accu-=scale; + ofs++; + } + } + xcount = w - xtable; + *w++=-1; + //xtable je hotova - obsahuje offset v obrazku pro kazdy sloupec a na konci je -1 + } + + if (clipl > xcount) return; + yiter = 0; + while (ytable[yiter] >= 0) { + int xiter = clipl; + int ofs = ytable[yiter]; + unsigned char *row = picdata+ofs; + while (xiter < clipr && xtable[xiter] >= 0 ) { + int xpos = xiter; + unsigned char p = row[xtable[xiter]]; + if (p != 0) { + if (p == 1) screen[xpos] = (screen[xpos] & 0xF7DE) >> 1; + else screen[xpos] = palette[p]; + } + ++xiter; + } + + screen-=scr_linelen2; + ++yiter; + } + +/* + + __asm + { + mov esi,src + mov edi,trg + mov ebx,shade + mov edx,scale + mov eax,maxspace + mov ecx,clip + + cmp eax,470 + jc ed_ok1 + ret +ed_ok1: push ebp + sub esp,ed_stack ;vyhrad zasobnik + mov ebp,esp + push ecx ;uchovej ecx +1 + push edi ;uchovej edi +2 + push ebx ;uchovej ebx +3 + mov ebx,eax ;volne misto je ted v ebx + mov edi,ebp ;nastav edi na zacatek tabulek + push ebp ; +4 + movzx ecx,short ptr[esi] ;precti xs + movzx eax,short ptr[esi+2] ;precti ys + imul eax,ecx ;xs*ys + sub eax,ecx ;minus 1 radek + xor ebp,ebp +ed_lp1b:stosd ;zapis hodnotu do tabulky + add ebp,320 ;zmensovani +ed_lp1a:cmp ebp,edx + jc ed_nxt1 ;pri ebp=velikosti obrazku tak konec + jc ed_lp2a + xor eax,eax + dec eax ;zapis -1 na konec tabulky + pop ebx ; +2 + stosd + mov eax,edi ;konecnou pozici pro tabulku x zapis do eax + pop edi ;obnov registry edi exc ebx+1 + add ebx,esi ;najdi adresu prekladove tabulky barev + add ebx,2 ;preskoc transparentni barvu + add esi,pic_start;presun se na zacatek obrazku + pop ecx ; +0 + movzx edx,cx ;vem levy okraj + lea edx,[ebp+edx*4] + lea edx,[edx+ed_stk1];edx ukazuje na sloupce + cmp eax,edx ;je-li levy okraj za platnou tabulkou tak konec + jbe ed_err + shr ecx,16 ;ecx ted obsahuje pravy okraj +ed_lp4: push esi ;uchovej esi +1 + push edi ;uchovej edi +2 + add esi,[ebp] ;spocitej spravnou hodnotu esi + push ecx ;uchovej pravy okraj +3 + push edx ;uchovej ukazatel na tabulku+4 +ed_lp3: mov eax,[edx] + cmp eax,-1 ;testuj konec tabulky + jz ed_end3 ;pri pozitivnim vysledku => konec radky + movzx eax,byte ptr[esi+eax];vem barvu + or al,al + jz ed_skp1 ;preskoc transparentni barvu + dec al + jz ed_shd ;1=shadow + mov eax,[ebx+eax*2];vyzvedni hicolor + stosw ;zapis barvu + jmp ed_skp2 +ed_shd: movzx eax,short ptr[edi];vem barvu + and eax,0xF7DE ;stmav + shr eax,1 + stosw ;zapis + jmp ed_skp2 ;skok na konec +ed_skp1:add edi,2 ;preskoc bod +ed_skp2:add edx,4 ;dalsi pozice + dec ecx ;dokud nedosahneme praveho okraje obrazku + jnz ed_lp3 +ed_end3:pop edx ;obnov vse ulozene + pop ecx + pop edi + pop esi ; +0 + add ebp,4 ;dalsi y souradnice + sub edi,scr_linelen ;dalsi radka + cmp dword ptr [ebp],-1 ;test na konec tabulky + jnz ed_lp4 ;jinak pokracuj +ed_err: add esp,ed_stack;vymaz tabulku + pop ebp ;obnov ebp + } + */ +} +void enemy_draw_transp(void *src,void *trg,void *shade,int scale,int maxspace,int clip) +//#pragma aux enemy_draw_transp parm[ESI][EDI][EBX][EDX][EAX][ECX] +{ + + word *picinfo = (word *)src; + word *screen = (word *)trg; + int xtable[800]; + int ytable[1200]; + int xcount; + int ycount; + word pcx = picinfo[0]; + word pcy = picinfo[1]; + word type = picinfo[2]; + unsigned char *picdata = (unsigned char *)src+(type == (512+8)?6:pic_start); + word *palette = (word *)shade; + int clipl = clip & 0xFFFF; + int clipr = clip >> 16; + int yiter; + + if (maxspace >= 470) return; + + //prepare ytable; + { + int rwofs = pcx*(pcy-1); + int accu = 0; + int *w = ytable; + int sp = maxspace*2; + + while (sp > 0 && rwofs >= 0) { + *w++ = rwofs; + accu+=320; + while (accu >= scale && rwofs >= 0) { + accu-=scale; + rwofs-=pcx; + } + sp--; + } + ycount = w - ytable; + *w++=-1; + //ytable je hotova - obsahuje ofsety v obrazku pro kazdou radku a na konci je -1 + } + + //prepare xtable + { + int *w = xtable; + int ofs = 0; + int accu = 0; + while (ofs < pcx) { + *w++ = ofs; + accu+=320; + while (accu >= scale) { + accu-=scale; + ofs++; + } + } + xcount = w - xtable; + *w++=-1; + //xtable je hotova - obsahuje offset v obrazku pro kazdy sloupec a na konci je -1 + } + + if (clipl > xcount) return; + yiter = 0; + while (ytable[yiter] >= 0) { + int xiter = clipl; + int ofs = ytable[yiter]; + unsigned char *row = picdata+ofs; + while (xiter < clipr && xtable[xiter] >= 0 ) { + int xpos = xiter -clipl; + unsigned char p = row[xtable[xiter]]; + if (p != 0) { + if (p & 0x80) screen[xpos] = ((screen[xpos] & 0xF7DE) + (palette[p] & 0xF7DE))>>1; + else screen[xpos] = palette[p]; + } + ++xiter; + } + + screen-=scr_linelen2; + ++yiter; + } + +/* __asm + { + mov esi,src + mov edi,trg + mov ebx,shade + mov edx,scale + mov eax,maxspace + mov ecx,clip + + cmp eax,470 + jc et_ok1 + ret +et_ok1: push ebp + sub esp,ed_stack ;vyhrad zasobnik + mov ebp,esp + push ecx ;uchovej ecx +1 + push edi ;uchovej edi +2 + push ebx ;uchovej ebx +3 + mov ebx,eax ;volne misto je ted v ebx + mov edi,ebp ;nastav edi na zacatek tabulek + push ebp ; +4 + movzx ecx,short ptr[esi] ;precti xs + movzx eax,short ptr[esi+2] ;precti ys + imul eax,ecx ;xs*ys + sub eax,ecx ;minus 1 radek + xor ebp,ebp +et_lp1b:stosd ;zapis hodnotu do tabulky + add ebp,320 ;zmensovani +et_lp1a:cmp ebp,edx + jc et_nxt1 ;pri ebp=velikosti obrazku tak konec + jc et_lp2a + xor eax,eax + dec eax ;zapis -1 na konec tabulky + pop ebx ; +2 + stosd + mov eax,edi ;konecnou pozici pro tabulku x zapis do eax + pop edi ;obnov registry edi exc ebx+1 + cmp byte ptr [esi+5],2 ;obrazek bez palety? + jz et_pl1 + add esi,pic_start;presun se na zacatek obrazku (za paletu) + jmp et_pl2 +et_pl1: add esi,6 ;(obrazek bez palety, presun se za hlavicku) +et_pl2: pop ecx ; +0 + movzx edx,cx ;vem levy okraj + lea edx,[ebp+edx*4] + lea edx,[edx+ed_stk1];edx ukazuje na sloupce + cmp eax,edx ;je-li levy okraj za platnou tabulkou tak konec + jbe et_err + shr ecx,16 ;ecx ted obsahuje pravy okraj +et_lp4: push esi ;uchovej esi +1 + push edi ;uchovej edi +2 + add esi,[ebp] ;spocitej spravnou hodnotu esi + push ecx ;uchovej pravy okraj +3 + push edx ;uchovej ukazatel na tabulku+4 +et_lp3: mov eax,[edx] + cmp eax,-1 ;testuj konec tabulky + jz et_end3 ;pri pozitivnim vysledku => konec radky + movzx eax,byte ptr[esi+eax];vem barvu + test al,80h + jnz et_shd + or al,al + jz et_skp1 ;preskoc transparentni barvu + mov eax,[ebx+eax*2];vyzvedni hicolor + stosw ;zapis barvu + jmp et_skp2 +et_shd: and short ptr[edi],0xF7DE ;1111 0111 1101 1110 + mov eax,[ebx+eax*2];vyzvedni hicolor + and eax,0xF7DE ;stmav + add ax,short ptr[edi] + rcr ax,1 + stosw ;zapis + jmp et_skp2 ;skok na konec +et_skp1:add edi,2 ;preskoc bod +et_skp2:add edx,4 ;dalsi pozice + dec ecx ;dokud nedosahneme praveho okraje obrazku + jnz et_lp3 +et_end3:pop edx ;obnov vse ulozene + pop ecx + pop edi + pop esi ; +0 + add ebp,4 ;dalsi y souradnice + sub edi,scr_linelen ;dalsi radka + cmp dword ptr [ebp],-1 ;test na konec tabulky + jnz et_lp4 ;jinak pokracuj +et_err: add esp,ed_stack;vymaz tabulku + pop ebp ;obnov ebp + }*/ +} + +void enemy_draw_mirror_transp(void *src,void *trg,void *shade,int scale,int maxspace,int clip) +//#pragma aux enemy_draw_mirror_transp parm[ESI][EDI][EBX][EDX][EAX][ECX] +{ + + word *picinfo = (word *)src; + word *screen = (word *)trg; + int xtable[800]; + int ytable[1200]; + int xcount; + int ycount; + word pcx = picinfo[0]; + word pcy = picinfo[1]; + word type = picinfo[2]; + unsigned char *picdata = (unsigned char *)src+(type == (512+8)?6:pic_start); + word *palette = (word *)shade; + int clipl = clip & 0xFFFF; + int clipr = clip >> 16; + int yiter; + + if (maxspace >= 470) return; + + //prepare ytable; + { + int rwofs = pcx*(pcy-1); + int accu = 0; + int *w = ytable; + int sp = maxspace*2; + + while (sp > 0 && rwofs >= 0) { + *w++ = rwofs; + accu+=320; + while (accu >= scale && rwofs >= 0) { + accu-=scale; + rwofs-=pcx; + } + sp--; + } + ycount = w - ytable; + *w++=-1; + //ytable je hotova - obsahuje ofsety v obrazku pro kazdou radku a na konci je -1 + } + + //prepare xtable + { + int *w = xtable; + int ofs = pcx-1; + int accu = 0; + while (ofs >= 0) { + *w++ = ofs; + accu+=320; + while (accu >= scale) { + accu-=scale; + ofs--; + } + } + xcount = w - xtable; + *w++=-1; + //xtable je hotova - obsahuje offset v obrazku pro kazdy sloupec a na konci je -1 + } + + if (clipl > xcount) return; + yiter = 0; + while (ytable[yiter] >= 0) { + int xiter = clipl; + int ofs = ytable[yiter]; + unsigned char *row = picdata+ofs; + while (xiter < clipr && xtable[xiter] >= 0 ) { + int xpos = xiter -clipl; + unsigned char p = row[xtable[xiter]]; + if (p != 0) { + if (p & 0x80) screen[xpos] = ((screen[xpos] & 0xF7DE) + (palette[p] & 0xF7DE))>>1; + else screen[xpos] = palette[p]; + } + ++xiter; + } + + screen-=scr_linelen2; + ++yiter; + } + + /* + __asm + { + mov esi,src + mov edi,trg + mov ebx,shade + mov edx,scale + mov eax,maxspace + mov ecx,clip + + push ebp + sub esp,ed_stack ;vyhrad zasobnik + mov ebp,esp + push ecx ;uchovej ecx +1 + push edi ;uchovej edi +2 + push ebx ;uchovej ebx +3 + mov ebx,eax ;volne misto je ted v ebx + mov edi,ebp ;nastav edi na zacatek tabulek + push ebp ; +4 + movzx ecx,short ptr[esi] ;precti xs + movzx eax,short ptr[esi+2] ;precti ys + imul eax,ecx ;xs*ys + sub eax,ecx ;minus 1 radek + xor ebp,ebp +etmlp1b:stosd ;zapis hodnotu do tabulky + add ebp,320 ;zmensovani +etmlp1a:cmp ebp,edx + jc etmnxt1 ;pri ebp konec radky + movzx eax,byte ptr[esi+eax];vem barvu + test al,80h + jnz etmshd + or al,al + jz etmskp1 ;preskoc transparentni barvu + mov eax,[ebx+eax*2];vyzvedni hicolor + stosw ;zapis barvu + jmp etmskp2 +etmshd: and short ptr[edi],0xF7DE + mov eax,[ebx+eax*2];vyzvedni hicolor + and eax,0xF7DE ;stmav + add ax,short ptr[edi] + rcr ax,1 + stosw ;zapis + jmp etmskp2 ;skok na konec +etmskp1:add edi,2 ;preskoc bod +etmskp2:add edx,4 ;dalsi pozice + dec ecx ;dokud nedosahneme praveho okraje obrazku + jnz etmlp3 +etmend3:pop edx ;obnov vse ulozene + pop ecx + pop edi + pop esi ; +0 + add ebp,4 ;dalsi y souradnice + sub edi,scr_linelen ;dalsi radka + cmp dword ptr [ebp],-1 ;test na konec tabulky + jnz etmlp4 ;jinak pokracuj +etmerr: add esp,ed_stack;vymaz tabulku + pop ebp ;obnov ebp + } + */ +} +void enemy_draw_mirror(void *src,void *trg,int shade,int scale,int maxspace,int clip) +//#pragma aux enemy_draw_mirror parm[ESI][EDI][EBX][EDX][EAX][ECX] +//clip je v poradi vpravo - vlevo (HiLo) +{ + word *picinfo = (word *)src; + word *screen = (word *)trg; + int xtable[800]; + int ytable[1200]; + int xcount; + int ycount; + word pcx = picinfo[0]; + word pcy = picinfo[1]; + unsigned char *picdata = (unsigned char *)src + pic_start; + word *palette = picinfo+shade/2; + int clipl = clip & 0xFFFF; + int clipr = clip >> 16; + int yiter; + + if (maxspace >= 470) return; + + //prepare ytable; + { + int rwofs = pcx*(pcy-1); + int accu = 0; + int *w = ytable; + int sp = maxspace*2; + + while (sp > 0 && rwofs >= 0) { + *w++ = rwofs; + accu+=320; + while (accu >= scale && rwofs >= 0) { + accu-=scale; + rwofs-=pcx; + } + sp--; + } + ycount = w - ytable; + *w++=-1; + //ytable je hotova - obsahuje ofsety v obrazku pro kazdou radku a na konci je -1 + } + + //prepare xtable + { + int *w = xtable; + int ofs = pcx-1; + int accu = 0; + while (ofs >= 0) { + *w++ = ofs; + accu+=320; + while (accu >= scale) { + accu-=scale; + ofs--; + } + } + xcount = w - xtable; + *w++=-1; + //xtable je hotova - obsahuje offset v obrazku pro kazdy sloupec a na konci je -1 + } + + if (clipl > xcount) return; + yiter = 0; + while (ytable[yiter] >= 0) { + int xiter = clipl; + int ofs = ytable[yiter]; + unsigned char *row = picdata+ofs; + while (xiter < clipr && xtable[xiter] >= 0 ) { + int xpos = xiter; + unsigned char p = row[xtable[xiter]]; + if (p != 0) { + if (p == 1) screen[xpos] = (screen[xpos] & 0xF7DE) >> 1; + else screen[xpos] = palette[p]; + } + ++xiter; + } + + screen-=scr_linelen2; + ++yiter; + } + + /* + + __asm + { + mov esi,src + mov edi,trg + mov ebx,shade + mov edx,scale + mov eax,maxspace + mov ecx,clip + + push ebp + sub esp,ed_stack ;vyhrad zasobnik + mov ebp,esp + push ecx ;uchovej ecx +1 + push edi ;uchovej edi +2 + push ebx ;uchovej ebx +3 + mov ebx,eax ;volne misto je ted v ebx + mov edi,ebp ;nastav edi na zacatek tabulek + push ebp ; +4 + movzx ecx,short ptr[esi] ;precti xs + movzx eax,short ptr[esi+2] ;precti ys + imul eax,ecx ;xs*ys + sub eax,ecx ;minus 1 radek + xor ebp,ebp +edmlp1b:stosd ;zapis hodnotu do tabulky + add ebp,320 ;zmensovani +edmlp1a:cmp ebp,edx + jc edmnxt1 ;pri ebp konec radky + movzx eax,byte ptr[esi+eax];vem barvu + or al,al + jz edmskp1 ;preskoc transparentni barvu + dec al + jz edmshd ;1=shadow + mov eax,[ebx+eax*2];vyzvedni hicolor + stosw ;zapis barvu + jmp edmskp2 +edmshd: movzx eax,short ptr[edi];vem barvu + and eax,0xF7DE ;stmav + shr eax,1 + stosw ;zapis + jmp edmskp2 ;skok na konec +edmskp1:add edi,2 ;preskoc bod +edmskp2:add edx,4 ;dalsi pozice + dec ecx ;dokud nedosahneme praveho okraje obrazku + jnz edmlp3 +edmend3:pop edx ;obnov vse ulozene + pop ecx + pop edi + pop esi ; +0 + add ebp,4 ;dalsi y souradnice + sub edi,scr_linelen ;dalsi radka + cmp dword ptr [ebp],-1 ;test na konec tabulky + jnz edmlp4 ;jinak pokracuj +edmerr: add esp,ed_stack;vymaz tabulku + pop ebp ;obnov ebp + } + */ +} \ No newline at end of file diff --git a/GAME/extras.h b/GAME/extras.h new file mode 100644 index 0000000..6b9393b --- /dev/null +++ b/GAME/extras.h @@ -0,0 +1,16 @@ +#define EX_RANDOM_BACKFIRES 1 //hotovo +#define EX_RESPAWN_MONSTERS 2 //hotovo +#define EX_ALTERNATEFIGHT 4 //hotovo +#define EX_RECOVER_DESTROYED_ITEMS 8 //hotovo +#define EX_MULTIPLE_ITEMS_IN_CURSOR 16 //zruseno +#define EX_BAG_EXTENDED 32 //hotovo +#define EX_SHIELD_BLOCKING 64 //hotovo +#define EX_FAST_TRADE 128 //hotovo +#define EX_ALWAYS_MINIMAP 256 //hotovo +#define EX_GROUP_FLEE 512 +#define EX_NOHUNGRY 1024 +#define EX_AUTOOPENBOOK 2048 +#define EX_AUTOSHOWRUNE 4096 +#define EX_WALKDIAGONAL 8192 + +extern int game_extras; \ No newline at end of file diff --git a/GAME/version.h b/GAME/version.h new file mode 100644 index 0000000..50623c8 --- /dev/null +++ b/GAME/version.h @@ -0,0 +1,13 @@ +#define VERSION_MAJOR 1 +#define VERSION_MAJORT "1" +#define VERSION_MINOR 2 +#define VERSION_MINORT "2" +#define VERSION_BUILD 17 +#define VERSION_BUILDT "17" + + +#define VERSION VERSION_MAJORT"."VERSION_MINORT" Build "VERSION_BUILDT +#define VERSIONNUM VERSION_MAJOR*1000000+VERSION_MINOR*10000+VERSION_BUILD +#define VERSIONWINSTR VERSION_MAJORT","VERSION_MINORT","0","VERSION_BUILDT +#define VERSIONWINRES(x) x VERSION_MAJOR, VERSION_MINOR, 0, VERSION_BUILD + diff --git a/GIF/Decoder.c b/GIF/Decoder.c new file mode 100644 index 0000000..617b530 --- /dev/null +++ b/GIF/Decoder.c @@ -0,0 +1,377 @@ +/* DECODE.C - An LZW decoder for GIF + * Copyright (C) 1987, by Steven A. Bennett + * + * Permission is given by the author to freely redistribute and include + * this code in any program as long as this credit is given where due. + * + * In accordance with the above, I want to credit Steve Wilhite who wrote + * the code which this is heavily inspired by... + * + * GIF and 'Graphics Interchange Format' are trademarks (tm) of + * Compuserve, Incorporated, an H&R Block Company. + * + * Release Notes: This file contains a decoder routine for GIF images + * which is similar, structurally, to the original routine by Steve Wilhite. + * It is, however, somewhat noticably faster in most cases. + * + */ + +#include +#include "std.h" +#include "errs.h" + +IMPORT TEXT *malloc(); /* Standard C library allocation */ + +/* IMPORT INT get_byte() + * + * - This external (machine specific) function is expected to return + * either the next byte from the GIF file, or a negative number, as + * defined in ERRS.H. + */ +IMPORT INT get_byte(); + +/* IMPORT INT out_line(pixels, linelen) + * UBYTE pixels[]; + * INT linelen; + * + * - This function takes a full line of pixels (one byte per pixel) and + * displays them (or does whatever your program wants with them...). It + * should return zero, or negative if an error or some other event occurs + * which would require aborting the decode process... Note that the length + * passed will almost always be equal to the line length passed to the + * decoder function, with the sole exception occurring when an ending code + * occurs in an odd place in the GIF file... In any case, linelen will be + * equal to the number of pixels passed... + */ +IMPORT INT out_line(); + +/* IMPORT INT bad_code_count; + * + * This value is the only other global required by the using program, and + * is incremented each time an out of range code is read by the decoder. + * When this value is non-zero after a decode, your GIF file is probably + * corrupt in some way... + */ +//IMPORT INT bad_code_count; +int bad_code_count; + +#define NULL 0 +#define MAX_CODES 4095 + +/* Static variables */ +LOCAL WORD curr_size; /* The current code size */ +LOCAL WORD clear; /* Value for a clear code */ +LOCAL WORD ending; /* Value for a ending code */ +LOCAL WORD newcodes; /* First available code */ +LOCAL WORD top_slot; /* Highest code for current size */ +LOCAL WORD slot; /* Last read code */ + +/* The following static variables are used + * for seperating out codes + */ +LOCAL WORD navail_bytes = 0; /* # bytes left in block */ +LOCAL WORD nbits_left = 0; /* # bits left in current byte */ +LOCAL UTINY b1; /* Current byte */ +LOCAL UTINY byte_buff[257]; /* Current block */ +LOCAL UTINY *pbytes; /* Pointer to next byte in block */ + +LOCAL LONG code_mask[13] = { + 0, + 0x0001, 0x0003, + 0x0007, 0x000F, + 0x001F, 0x003F, + 0x007F, 0x00FF, + 0x01FF, 0x03FF, + 0x07FF, 0x0FFF + }; + + +/* This function initializes the decoder for reading a new image. + */ +LOCAL WORD init_exp(size) + WORD size; + { + curr_size = size + 1; + top_slot = 1 << curr_size; + clear = 1 << size; + ending = clear + 1; + slot = newcodes = ending + 1; + navail_bytes = nbits_left = 0; + return(0); + } + +/* get_next_code() + * - gets the next code from the GIF file. Returns the code, or else + * a negative number in case of file errors... + */ +LOCAL WORD get_next_code() + { + WORD i, x; + ULONG ret; + + if (nbits_left == 0) + { + if (navail_bytes <= 0) + { + + /* Out of bytes in current block, so read next block + */ + pbytes = byte_buff; + if ((navail_bytes = get_byte()) < 0) + return(navail_bytes); + else if (navail_bytes) + { + for (i = 0; i < navail_bytes; ++i) + { + if ((x = get_byte()) < 0) + return(x); + byte_buff[i] = x; + } + } + } + b1 = *pbytes++; + nbits_left = 8; + --navail_bytes; + } + + ret = b1 >> (8 - nbits_left); + while (curr_size > nbits_left) + { + if (navail_bytes <= 0) + { + + /* Out of bytes in current block, so read next block + */ + pbytes = byte_buff; + if ((navail_bytes = get_byte()) < 0) + return(navail_bytes); + else if (navail_bytes) + { + for (i = 0; i < navail_bytes; ++i) + { + if ((x = get_byte()) < 0) + return(x); + byte_buff[i] = x; + } + } + } + b1 = *pbytes++; + ret |= b1 << nbits_left; + nbits_left += 8; + --navail_bytes; + } + nbits_left -= curr_size; + ret &= code_mask[curr_size]; + return((WORD)(ret)); + } + + +/* The reason we have these seperated like this instead of using + * a structure like the original Wilhite code did, is because this + * stuff generally produces significantly faster code when compiled... + * This code is full of similar speedups... (For a good book on writing + * C for speed or for space optomisation, see Efficient C by Tom Plum, + * published by Plum-Hall Associates...) + */ +LOCAL UTINY stack[MAX_CODES + 1]; /* Stack for storing pixels */ +LOCAL UTINY suffix[MAX_CODES + 1]; /* Suffix table */ +LOCAL UWORD prefix[MAX_CODES + 1]; /* Prefix linked list */ + +/* WORD decoder(linewidth) + * WORD linewidth; * Pixels per line of image * + * + * - This function decodes an LZW image, according to the method used + * in the GIF spec. Every *linewidth* "characters" (ie. pixels) decoded + * will generate a call to out_line(), which is a user specific function + * to display a line of pixels. The function gets it's codes from + * get_next_code() which is responsible for reading blocks of data and + * seperating them into the proper size codes. Finally, get_byte() is + * the global routine to read the next byte from the GIF file. + * + * It is generally a good idea to have linewidth correspond to the actual + * width of a line (as specified in the Image header) to make your own + * code a bit simpler, but it isn't absolutely necessary. + * + * Returns: 0 if successful, else negative. (See ERRS.H) + * + */ + +WORD decoder(linewidth) + WORD linewidth; + { + FAST UTINY *sp, *bufptr; + UTINY *buf; + FAST WORD code, fc, oc, bufcnt; + WORD c, size, ret; + + /* Initialize for decoding a new image... + */ + if ((size = get_byte()) < 0) + return(size); + if (size < 2 || 9 < size) + return(BAD_CODE_SIZE); + init_exp(size); + + /* Initialize in case they forgot to put in a clear code. + * (This shouldn't happen, but we'll try and decode it anyway...) + */ + oc = fc = 0; + + /* Allocate space for the decode buffer + */ + if ((buf = (UTINY *)malloc(linewidth + 1)) == NULL) + return(OUT_OF_MEMORY); + + /* Set up the stack pointer and decode buffer pointer + */ + sp = stack; + bufptr = buf; + bufcnt = linewidth; + + /* This is the main loop. For each code we get we pass through the + * linked list of prefix codes, pushing the corresponding "character" for + * each code onto the stack. When the list reaches a single "character" + * we push that on the stack too, and then start unstacking each + * character for output in the correct order. Special handling is + * included for the clear code, and the whole thing ends when we get + * an ending code. + */ + while ((c = get_next_code()) != ending) + { + + /* If we had a file error, return without completing the decode + */ + if (c < 0) + { + free(buf); + return(0); + } + + /* If the code is a clear code, reinitialize all necessary items. + */ + if (c == clear) + { + curr_size = size + 1; + slot = newcodes; + top_slot = 1 << curr_size; + + /* Continue reading codes until we get a non-clear code + * (Another unlikely, but possible case...) + */ + while ((c = get_next_code()) == clear) + ; + + /* If we get an ending code immediately after a clear code + * (Yet another unlikely case), then break out of the loop. + */ + if (c == ending) + break; + + /* Finally, if the code is beyond the range of already set codes, + * (This one had better NOT happen... I have no idea what will + * result from this, but I doubt it will look good...) then set it + * to color zero. + */ + if (c >= slot) + c = 0; + + oc = fc = c; + + /* And let us not forget to put the char into the buffer... And + * if, on the off chance, we were exactly one pixel from the end + * of the line, we have to send the buffer to the out_line() + * routine... + */ + *bufptr++ = c; + if (--bufcnt == 0) + { + if ((ret = out_line(buf, linewidth)) < 0) + { + free(buf); + return(ret); + } + bufptr = buf; + bufcnt = linewidth; + } + } + else + { + + /* In this case, it's not a clear code or an ending code, so + * it must be a code code... So we can now decode the code into + * a stack of character codes. (Clear as mud, right?) + */ + code = c; + + /* Here we go again with one of those off chances... If, on the + * off chance, the code we got is beyond the range of those already + * set up (Another thing which had better NOT happen...) we trick + * the decoder into thinking it actually got the last code read. + * (Hmmn... I'm not sure why this works... But it does...) + */ + if (code >= slot) + { + if (code > slot) + ++bad_code_count; + code = oc; + *sp++ = fc; + } + + /* Here we scan back along the linked list of prefixes, pushing + * helpless characters (ie. suffixes) onto the stack as we do so. + */ + while (code >= newcodes) + { + *sp++ = suffix[code]; + code = prefix[code]; + } + + /* Push the last character on the stack, and set up the new + * prefix and suffix, and if the required slot number is greater + * than that allowed by the current bit size, increase the bit + * size. (NOTE - If we are all full, we *don't* save the new + * suffix and prefix... I'm not certain if this is correct... + * it might be more proper to overwrite the last code... + */ + *sp++ = code; + if (slot < top_slot) + { + suffix[slot] = fc = code; + prefix[slot++] = oc; + oc = c; + } + if (slot >= top_slot) + if (curr_size < 12) + { + top_slot <<= 1; + ++curr_size; + } + + /* Now that we've pushed the decoded string (in reverse order) + * onto the stack, lets pop it off and put it into our decode + * buffer... And when the decode buffer is full, write another + * line... + */ + while (sp > stack) + { + *bufptr++ = *(--sp); + if (--bufcnt == 0) + { + if ((ret = out_line(buf, linewidth)) < 0) + { + free(buf); + return(ret); + } + bufptr = buf; + bufcnt = linewidth; + } + } + } + } + ret = 0; + if (bufcnt != linewidth) + ret = out_line(buf, (linewidth - bufcnt)); + free(buf); + return(ret); + } + diff --git a/GIF/Errs.h b/GIF/Errs.h new file mode 100644 index 0000000..54fa92e --- /dev/null +++ b/GIF/Errs.h @@ -0,0 +1,14 @@ +/* Various error codes used by decoder + * and my own routines... It's okay + * for you to define whatever you want, + * as long as it's negative... It will be + * returned intact up the various subroutine + * levels... + */ +#define OUT_OF_MEMORY -10 +#define BAD_CODE_SIZE -20 +#define READ_ERROR -1 +#define WRITE_ERROR -2 +#define OPEN_ERROR -3 +#define CREATE_ERROR -4 + diff --git a/GIF/GIF.H b/GIF/GIF.H new file mode 100644 index 0000000..157b9bd --- /dev/null +++ b/GIF/GIF.H @@ -0,0 +1,16 @@ +#ifndef _GIF__H +#define _GIF__H + +char gif_file [512000]; +char *gif_picture; +char gif_palette [768]; +int x_0, x_1, y_0, y_1, gif_size; +long int gif_pozice=0; +int RaW=0; + +int gif_to_buffer (char *filename); + +#define LENGHTGIF 512000 + +#endif + diff --git a/GIF/GIF2.C b/GIF/GIF2.C new file mode 100644 index 0000000..6ff4c64 --- /dev/null +++ b/GIF/GIF2.C @@ -0,0 +1,147 @@ +#include +#include +#include +#include +#include "..\types.h" +#include "decoder.c" +#include "..\bgraph.h" + + +char *gif_buffer,*gif_ptr; +char *decomp_buff,*decomp_ptr; +char *comp_buff,*comp_ptr; + +int g_xsize,g_ysize; +char paleta[768]; + +int get_byte() + { + return(*gif_ptr++); + } + +int curline; +char *obrazovka; + +int out_line(char *data,int linelen) + { + memcpy(obrazovka,data,linelen); + memcpy(decomp_ptr,data,linelen); + decomp_ptr+=linelen; + obrazovka+=640; + if (++curline>=g_ysize) return (curline); + return 0; + } + +void setpalette(char *paleta) + { + int i; + + for (i=0;i<256;i++) + { + outp(0x3c6,0xff); + outp(0x3c8,i); + outp(0x3c9,*paleta++>>2); + outp(0x3c9,*paleta++>>2); + outp(0x3c9,*paleta++>>2); + } + } + + +void load_gif(char *filename) + { + FILE *pic; + long lengif; + + + pic=fopen(filename,"rb"); + if (pic==NULL) return; + fseek(pic,0,SEEK_END); + lengif=ftell(pic); + gif_buffer=(char *)malloc(lengif);gif_ptr=gif_buffer; + fseek(pic,6,SEEK_SET); + fread(&g_xsize,2,1,pic); + fread(&g_ysize,2,1,pic); + decomp_buff=(char *)malloc(g_xsize*g_ysize);decomp_ptr=decomp_buff; + fseek (pic, 0x0d, SEEK_SET); + fread(&paleta,768,1,pic); + setpalette(paleta); + fseek (pic, 0x317, SEEK_SET); + lengif-=0x317; + fread(gif_buffer,lengif,1,pic); + curline=0; + decoder(g_xsize); + fclose(pic); + free(gif_buffer); + } + +#define save_nibble(x) if (nibble_sel) {*(comp_ptr++)|=(x)<<4;nibble_sel=!nibble_sel;} else {*(comp_ptr)=(x);nibble_sel=!nibble_sel;} + +int Hi_coder_1() + { + char palette[8]; + long state[8]; + char nibble_sel=0; + long picsize,cntr=0; + long r_size=0; + + memset(palette,0x0,8); + memset(state,0x0,4*8); + picsize=g_xsize*g_ysize; + + while (picsize) + { + char i,b; + + b=*decomp_ptr++;cntr++; + for (i=0;i<8;i++) if (palette[i]==b) break; + if (i!=8) + { + save_nibble(i); + state[i]=cntr; + r_size++; + } + else + { + long min=0x7fffffff;char sl=0; + + for (i=0;i<8;i++) + if (state[i]> 4); + r_size+=3; + } + picsize--; + } + r_size>>=1; + return r_size; + } + + +void prepare_compress() + { + comp_buff=(char *)malloc(512000); + comp_ptr=comp_buff; + decomp_ptr=decomp_buff; + } + + +int main() + { + initmode256("..\xlat256.pal"); + memset(lbuffer,0xff,640*480); + getchar(); + obrazovka=(char *)lbuffer; + load_gif("desk_d.gif"); + prepare_compress(); + Hi_coder_1(); + getchar(); + return 0; + } + + diff --git a/GIF/GIF2XED.C b/GIF/GIF2XED.C new file mode 100644 index 0000000..e0864ac --- /dev/null +++ b/GIF/GIF2XED.C @@ -0,0 +1,39 @@ +#include +#include +#include "gif.h" + +unsigned short new_palette [256]; + +void main (int argc, char *argv[]) +{ + FILE *xed; + char gif[13]; + int x,y; + + memmove (gif, argv[1], 13); + xed=fopen("new.xed","wb"); + + gif_to_buffer (gif); + + y=0; + for (x=0; x<=767; x+=3) + { + new_palette[y]=gif_palette[(x+2)]; + new_palette[y]|=gif_palette[(x+1)]<<5; //*32; + new_palette[y]|=gif_palette[x]<<10; //*1024; + y++; + } + + fputc (x_0,xed); + fputc (x_1,xed); + fputc (y_0,xed); + fputc (y_1,xed); + fputc (8,xed); + fputc (0,xed); + + fwrite (new_palette, 256, 2, xed); + fwrite (gif_picture, gif_size, 1, xed); + + fclose (xed); +} + diff --git a/GIF/Gif.c b/GIF/Gif.c new file mode 100644 index 0000000..e551905 --- /dev/null +++ b/GIF/Gif.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include +#include "decoder.c" +#include "gif.h" + +int get_byte () +{ + int x; + x=gif_file[gif_pozice]; + gif_pozice++; + if (gif_pozice==LENGHTGIF) return (READ_ERROR); else return (x); +} + +int out_line (char *pixels, int linelen) +{ + memmove ((gif_picture+linelen*RaW), pixels, linelen); + RaW++; + if (RaW<=480) return (RaW); else return (0); +} + +int gif_to_buffer (char *filename) +{ + FILE *picture; + int x; + char mezi[4]; + +//------------------------------------------------------------------------- +// Nacteni GIFu +//------------------------------------------------------------------------- + picture=fopen(filename,"rb"); + +// Read size and alloc memory + fseek (picture, 6, SEEK_SET); + fread (mezi, 4, 1, picture); + gif_size=(mezi[0]+mezi[1]*256)*(mezi[2]+mezi[3]*256); + x_0=mezi[0]; + x_1=mezi[1]; + y_0=mezi[2]; + y_1=mezi[3]; + gif_picture=(char*)malloc( (gif_size*sizeof(gif_picture)) ); + +// Read and prepare palette + fseek (picture, 0x0d, SEEK_SET); + fread (gif_palette, 768, 1, picture); + for (x=0; x<=768; x++) gif_palette[x]>>=3; + +// Read coded picture + fseek (picture, 0x317, SEEK_SET); + fread (gif_file, LENGHTGIF, 1, picture); + +// Decode picture + RaW=0; + decoder (640); + fclose (picture); +//------------------------------------------------------------------------- + +return (0); +} + diff --git a/GIF/STD.H b/GIF/STD.H new file mode 100644 index 0000000..ba7c0d7 --- /dev/null +++ b/GIF/STD.H @@ -0,0 +1,16 @@ +/* STD.H - My own standard header file... + */ + +#define LOCAL static +#define IMPORT extern + +#define FAST register + +typedef short WORD; +typedef unsigned short UWORD; +typedef char TEXT; +typedef unsigned char UTINY; +typedef long LONG; +typedef unsigned long ULONG; +typedef int INT; + diff --git a/INST/SETUP.C b/INST/SETUP.C new file mode 100644 index 0000000..6a305f2 --- /dev/null +++ b/INST/SETUP.C @@ -0,0 +1,1427 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "setup.h" +#include "setvideo.h" +#include "setuplib.h" +#include "setupcpy.h" + +#define TEST_MUSIC "\\SNDTEST.MUS" +#define SETUP_BATCH "SETUP.BAT" +#define _SOURCE_ copy_source_path +#define ER_NAME "c:\\skeldal.!!!" +#define VEL_RAMECEK 8 + +#define VMODE "VMODE" +#define SOUND_DEVICE "SOUND_DEVICE" + +#define SETUP_NAME "SETUP.EXE" + +word *ramecky[VEL_RAMECEK]; + +#define SKELDAL "SKELDAL" +#define SKELDAL_INI SKELDAL".INI" +#define CONCAT(t,s1,s2) strcat(strcpy(t=alloca(strlen(s1)+strlen(s2)+1),s1),s2) +void *bbutt; + +char *copy_source_path; +char *test_sound_name; +char *program_data_path=NULL; +char setup_mode=0; + +char *pgm_name; + +TSTR_LIST setup_ini; + +typedef struct tsound + { + int device,port,irq,dma; + }TSOUND; + + +FILE *ini; +word *vga_font; +word *icones; +word icone_color[7]={0x2108,0x7fff,0x000f,0x4210,0x6f7b}; +//static char target_path[256]="E:\HRY\SKELDAL\"; +char *source_path; +char target_path[2049]; +static TSOUND sound_info={0,0,0,0}; +static int vmode=0; +static char mixer_running=0; +static char back=0; +static char install_type; +static long install_sizes[3]; +static long maxcopy=1; +TSTR_LIST handbook=NULL; +TSTR_LIST dirlist=NULL; +TSTR_LIST disklist=NULL; +int win_handbook=-1; +char rescue_mode=0; +char *inifile=NULL; + +#pragma off (stack_checking) + +static char home_path(char *source_path) + { + unsigned x,z; + _dos_setdrive(source_path[0]-'@',&x); + _dos_getdrive(&z); + if (z!=source_path[0]-'@') return 1; + chdir("\\"); + chdir(source_path); + return 0; + } +char error_device(word a,char b,char c) + { + a,b,c; + + errno=-1; + return _ERR_FAIL; + } + +int create_er_file() + { + FILE *f; + if (!access(ER_NAME,F_OK)) return 0; + + f=fopen(ER_NAME,"w"); + fprintf(f,"7925536\n"); + fprintf(f,"Toto je zachranny soubor pro instalacni program ke hre BRANY SKELDALU. Pokud se posledni instalace nezdarila, nemazte tento soubor!"); + fclose(f); + return 1; + } + +void remove_er_file() + { + FILE *f; + + f=fopen(ER_NAME,"r"); + if (f!=NULL) + { + long l=0; + fscanf(f,"%d",&l); + fclose(f); + if (l==7925536) remove(ER_NAME); + } + } + + +static conv_ramecek(word *ram) + { + int i; + word xs,ys; + char *ptr; + word *targ; + + xs=ram[0]; + ys=ram[1]/VEL_RAMECEK; + ptr=(char *)(ram+3+256); + for(i=0;i"); + } + for(i=0;i"); + set_value(0,20,""); + } + else + { + sprintf(s,"VESA %d.%02d",si.version/256,si.version%256); + set_value(0,10,s); + set_value(0,20,si.oemstr); + } + set_value(0,30,gr_mody[vmode]);do_events(); + sound_detect(&sound_info.device,&sound_info.port,&sound_info.dma,&sound_info.irq); + set_value(0,40,device_name(sound_info.device)); + if (sound_info.device==DEV_WSS || sound_info.device==DEV_ULTRA) + sprintf(s,"Port %X Dma %X",sound_info.port,sound_info.dma); + else sprintf(s,"Port %X Dma %X Irq %X",sound_info.port,sound_info.dma,sound_info.irq); + set_value(0,50,s); + set_value(0,60,get_cdrom()); + set_enable(0,6,1); + set_enable(0,5,1); + } + +static EVENT_PROC(esc_mode2) + { + GET_USER_PTR(); + WHEN_MSG(E_KEYBOARD) + { + if (GET_DATA(char)==27) + { + donegr(); + if (vmode==0)initgr_low();else initgr_spec(vmode); + zobraz_mysku(); + redraw_desktop(); + goto_control(0); + terminate(); + } + } + } + +static char test_mode() + { + char i,j,c; + + if (msg_box("Test grafiky",'\x1', + "Instaltor nyn vyzkou zvolen grafick reim. " + "Pokud obrazovka zstane ern, nebo zobraz nesmysly, stisknte " + "ESC a instaltor obnov pvodn reim.","Start","Zruit",NULL)==2) return 0; + send_message(E_ADD,E_KEYBOARD,esc_mode2); + donegr(); + i=initgr_spec(f_get_value(0,9)); + if (!i) + { + zobraz_mysku(); + redraw_desktop(); + } + if (!i && (j=msg_box("Test grafiky",'\x2',"Vidi prosted instaltoru sprvn?","Ano","Ne",NULL))==1) + { + vmode=f_get_value(0,9); + if (vmode==0) initgr_low(); + zobraz_mysku(); + c=1; + } + else + { + c_set_value(0,9,vmode); + if (j!=0) + { + donegr(); + if (vmode==0) initgr_low();else initgr_spec(vmode); + zobraz_mysku(); + redraw_desktop(); + } + c=0; + } + send_message(E_DONE,E_KEYBOARD,esc_mode2); + return c; + } + +static TSTR_LIST video_ls=NULL; + +static void create_video_ls() + { + int i; + if (video_ls==NULL) + { + video_ls=create_list(3); + for(i=0;i<3;i++) str_add(&video_ls,gr_mody[i]); + } + } + +static void select_vga() + { + default_font=&font6x9; + def_dialoge(20,300,156,156,"Kvalita grafiky",2); + define(9,0,20,156,80,0,listbox,video_ls,0x03ff,0);c_default(vmode); + property(NULL,vga_font,NULL,WINCOLOR); + define(20,38,5,80,20,3,button,"Zmnit te");on_change(test_mode); + property(bbutt,NULL,NULL,BUTTONCOLOR); + redraw_window(); + } + + +static void change_dma() + { + int i,j; + + i=f_get_value(0,30); + j=f_get_value(0,35)+3; + if (o_aktual->id==30) + { + c_set_value(0,30,i); + c_set_value(0,35,i-3); + } + else + { + c_set_value(0,30,j); + c_set_value(0,35,j-3); + } + } + +static void select_mode_win() + { + def_dialoge(224,270,192,156,"Instalovat",2); + default_font=&font6x9; + define(10,30,40,132,30,0,button,"Automaticky");property(bbutt,NULL,NULL,BUTTONCOLOR);on_change(terminate); + define(30,30,80,132,30,0,button,"Podle pn");property(bbutt,NULL,NULL,BUTTONCOLOR);on_change(terminate); + define(40,50,15,92,20,3,button,"Konec");property(bbutt,NULL,NULL,BUTTONCOLOR);on_change(stop_copy); + redraw_window(); + } + +static void select_mode_win_setup() + { + def_dialoge(224,270,192,156,"Monosti:",2); + default_font=&font6x9; + define(10,30,40,132,30,0,button,"Nastaven");property(bbutt,NULL,NULL,BUTTONCOLOR);on_change(terminate); + define(30,30,80,132,30,0,button,"Odinstalovn");property(bbutt,NULL,NULL,BUTTONCOLOR);on_change(terminate); + define(40,50,15,92,20,3,button,"Konec");property(bbutt,NULL,NULL,BUTTONCOLOR);on_change(stop_setup); + redraw_window(); + } + + + +static void device_select() + { + int i,p; + i=f_get_value(0,9); + set_enable(0,40,i!=DEV_ULTRA && i!=DEV_WSS && i!=DEV_NOSOUND && i!=DEV_DAC); + p=i==DEV_SB16 || i==DEV_ULTRA; + set_enable(0,35,p); + if (p==0) + { + c_set_value(0,30,1); + c_set_value(0,35,1-3); + } + set_enable(0,20,i!=DEV_NOSOUND); + set_enable(0,30,i!=DEV_NOSOUND && i!=DEV_DAC); + set_enable(0,50,i!=DEV_NOSOUND); + } + +static void device_select2() + { + int i; + + device_select(); + i=f_get_value(0,9); + if (i==DEV_DAC) + { + char c; + def_dialoge(270,240,100,100,device_name(i),3); + define(10,10,25,60,40,0,radio_butts,3,"LPT 1","LPT 2","PC Speaker");c_default(0); + define(20,10,5,80,20,2,button,"Ok");property(bbutt,&font6x9,NULL,BUTTONCOLOR);on_change(terminate); + redraw_window(); + escape(); + c=f_get_value(0,10); + close_current(); + if (c==0) set_value(0,20,"378");else + if (c==1)set_value(0,20,"278"); + else set_value(0,20,"042"); + } + if (i==DEV_SB16 || i==DEV_ULTRA || i==DEV_SBPRO || i==DEV_SB20 || i==DEV_SB10) + set_value(0,20,"220"); + if (i==DEV_WSS) set_value(0,20,"530"); + } + +static void select_sound(); +static void detect_sound() + { + if (msg_box("Rozpoznn zvukov karty",'\x2',"Opravdu chce nechat rozpoznat zvukovou kartu? Na nkterch potach me automatick rozpoznvn zpsobit zatuhnut potae.","Ano","Ne",NULL)==2) return; + if (mixer_running) stop_mixing(); + mixer_running=0; + set_enable(0,70,mixer_running); + sound_detect(&sound_info.device,&sound_info.port,&sound_info.dma,&sound_info.irq); + close_current(); + select_sound(); + } + +static int sound_win=-1; + +static char sound_scan() + { + char buffer[20]; + char dmas[]={0,1,3,5,6,7}; + char irqs[]={2,3,5,7}; + + sound_info.device=f_get_value(sound_win,9); + if (sound_info.device!=DEV_NOSOUND) + { + if (sound_info.device==DEV_DAC) + if (msg_box("Varovn!",'\x1',"Vybran zvukov zazen pouv nestandardn pstupy a vyuv " + "nkterch skrytch trik systmu. Na nkterch potach nemus pracovat sprvn. " + "Toto zazen nedoke pracovat pod WINDOWS95 nebo jinm OS vjma DOSu. " + "Pro zrychlen prce odinstalujte ze systmu jakkoliv EMM manager (EMM386, QEMM, apod.) " + "Chcete pokraovat?","Ano","Ne",NULL)==2) return 1; + get_value(sound_win,20,buffer); + if (sscanf(buffer,"%x",&sound_info.port)!=1) + { + msg_box("Pozor!",'\x1',"Mus vyplnit sprvn Port","Ok",NULL); + return 1; + } + } + sound_info.dma=dmas[f_get_value(sound_win,30)]; + sound_info.irq=irqs[f_get_value(sound_win,40)]; + return 0; + } + + +static void test_sound() + { + if (mixer_running) stop_mixing(); + if (sound_scan()) return; + set_mixing_device(sound_info.device,22050,sound_info.port,sound_info.dma,sound_info.irq); + start_mixing(); + change_music(test_sound_name); + mix_back_sound(2); + mix_back_sound(0); + mixer_running=1; + set_enable(0,70,mixer_running); + } + +static void stop_sound() + { + if (mixer_running) + { + stop_mixing(); + mixer_running=0; + set_enable(sound_win,70,mixer_running); + } + } + +void select_sound() + { + TSTR_LIST ls; + int i; + char buff[30]; + + ls=create_list(8); + default_font=&font6x9; + for(i=0;i<8;i++) str_add(&ls,device_name(i)); + str_replace(&ls,0,""); + sound_win=def_dialoge(200,300,300,156,"Zvukov karta",2); + define(9,2,20,170,85,0,listbox,ls,0x03ff,0);c_default(sound_info.device);on_change(device_select2); + property(def_border(0,0x4210),vga_font,NULL,WINCOLOR); + define(-1,180,20,1,1,0,label,"Port:"); + define(20,10,20,30,12,1,input_line,3);property(def_border(0,0x4210),vga_font,NULL,WINCOLOR); + set_default(itoa(sound_info.port,buff,16)); + define(-1,180,40,1,1,0,label,"DMA:"); + i=sound_info.dma;i-=(i>2)+(i>4); + define(30,40,40,30,30,1,radio_butts,3,"0","1","3");c_default(i);on_change(change_dma); + define(35,10,40,30,30,1,radio_butts,3,"5","6","7");c_default(i-3);on_change(change_dma); + define(-1,180,80,1,1,0,label,"IRQ:"); + i=sound_info.irq;i-=2*(i>1)+(i>4)+(i>6); + define(40,40,80,30,40,1,radio_butts,4,"2","3","5","7");c_default(i); + define(50,10,5,80,20,2,button,"Test");property(bbutt,&font6x9,NULL,BUTTONCOLOR);on_change(test_sound); + define(60,100,5,80,20,2,button,"Rozpoznat");property(bbutt,&font6x9,NULL,BUTTONCOLOR);on_change(detect_sound); + define(70,190,5,80,20,2,button,"Stop");property(bbutt,&font6x9,NULL,BUTTONCOLOR);on_change(stop_sound); + redraw_window(); + set_enable(0,70,mixer_running); + device_select(); + } + +static void back_start() + { + back=1; + stop_sound(); + sound_scan(); + while (waktual!=NULL) close_current(); + terminate(); + } + +static void control_window(void *forward,void *back,void *help); +static void control_next1(); + +static void control_back1() + { + close_current(); + get_value(0,60,target_path); + while (waktual!=NULL) close_current(); + exit_wait=0; + select_vga(); + select_sound(); + control_window(control_next1,back_start,open_help); + } + +static trace_chdir(char *what) + { + char *c; + char *d; + + c=alloca(strlen(what)+1); + strcpy(c,what); + d=strrchr(c,'\\'); + while (d!=NULL) + { + if (chdir(c)==0) + { + home_path(c); + return; + } + *d=0; + d=strrchr(c,'\\'); + } + strcat(c,"\\"); + home_path(c); + } + + +void static show_space(char device) + { + char buff[100]; + static long lastvalue; + static char lastdevice; + + device=toupper(device); + if (device>='A' && device<='Z') + { + if (device!=lastdevice) lastvalue=get_disk_free(device-'@')/1024; + sprintf(buff,"Na disku %c: je volnch %d Kb",device,lastvalue); + lastdevice=device; + set_value(0,80,buff); + } + } + +static open_load_window() + { + char c; + get_value(0,60,target_path); + trace_chdir(target_path); + getcwd(target_path,2047); + load_window(); + escape(); + home_path(source_path); + c=o_aktual->id==150; + if (c) + { + get_value(0,10,target_path); + } + close_current(); + if (c) + set_value(0,60,target_path); + else + get_value(0,60,target_path); + show_space(target_path[0]); + } + +static char create_ini(char *path,char *name) + { + + if (inifile!=NULL) + { + fclose(ini); + remove(inifile); + free(inifile); + } + inifile=NewArr(char,strlen(path)+strlen(name)+2); + sprintf(inifile,"%s\\%s",path,name); + ini=fopen(inifile,"w"); + if (ini==NULL) return 1; + add_to_list(inifile); + fprintf(ini,"vmode %d\n", vmode); + fprintf(ini,"sound_device %d %x %d %d\n",sound_info.device,sound_info.port,sound_info.dma,sound_info.irq); + fprintf(ini,"sound_mixfreq 22049\n"); + fprintf(ini,"default_map lespred.map\n"); + fprintf(ini,"preload 1\n"); + fprintf(ini,"game_speed 5\n"); + return 0; + } + /* +static char create_setup_batch(char *path,char *name) + { + char *st; + FILE *batch; + + st=alloca(strlen(path)+strlen(name)+2); + sprintf(st,"%s\\%s",path,name); + batch=fopen(st,"w"); + if (batch==NULL) return 1; + fputs( + "@Echo off\n" + ":skok\n" + "Echo Vloz CD \"Brany Skeldalu\" do mechaniky\n" + "Echo a stiskni jakoukoliv klavesu. \n" + "Echo.\n" + "Echo Kombinace CNTR+C prerusi program....\n" + "Pause > NUL\n",batch); + fprintf(batch,"if not exist %s goto skok\n",pgm_name); + fprintf(batch,"%s -s \n",pgm_name); + fclose(batch); + return 0; + } + */ +static void close_ini() + { + if (ini!=NULL) fclose(ini); + } + +static void copy_self(char alloc) + { + static char *t; + + if (alloc) + { + t=NewArr(char,strlen(target_path)+strlen(SETUP_NAME)+2); + sprintf(t,"%s\\%s",target_path,SETUP_NAME); + cpy_file(pgm_name,t); + } + else free(t); + } + +static long self_size() + { + struct find_t f; + + _dos_findfirst(pgm_name,_A_NORMAL,&f); + return f.size; + } + +static void start_install() + { + long diskfree; + char error=0,autostart; + get_value(0,60,target_path); + if (find_object(waktual,70)!=NULL) autostart=f_get_value(0,70); else autostart=1; + strupr(target_path); + if (validate_path(target_path)==0) + { + msg_box("Cesta je patn",'\x1',"Cesta s clovm adresem je chybn zadna. Nepouvejte dlouh nzvy z WINDOWS 95!","OK",NULL); + return; + } + get_script(_SOURCE_,target_path); + switch (o_aktual->id) + { + case 10:install_type=INST_MIN;break; + case 20:install_type=INST_MED;break; + case 30:install_type=INST_MAX;break; + } + maxcopy=install_sizes[install_type]; + diskfree=get_disk_free(target_path[0]-'@'); + if (maxcopy>diskfree) + { + if (msg_box("Nedostatek msta!",'\x1',"Instaltor vypotal, e BS zaberou vce msta ne mte na svm disku. " + "Pokud vak pouvate kompriman program jako je teba DRVSPACE, pak mohou bt daje o " + "volnm mstu nepesne. I pes to, e nen voln msto chcete pokraovat?","Ano","Ne",NULL)==2) return; + } + else if (maxcopy+1024*1024>diskfree) + { + if (msg_box("Mlo msta",'\x2',"Po nainstalovn by mlo zbt alespo 1MB pro bh. Souasn prostor" + "umouje hru nainstalovat, avak hru nebude mon spustit. Pokraovat?","Ano","Ne",NULL)==2) return; + } + maxcopy=maxcopy<<1; + while (waktual!=NULL) close_current(); + cascade_mkdir(target_path); + if (create_ini(target_path,SKELDAL_INI)) + { + msg_box(PRG_HEADER,'\x1',"Nemohu vytvoit konfiguran soubor. Zkontroluj spravnost zpisu cesty","Ok",NULL); + clean_up(); + return; + } +// create_setup_batch(target_path,SETUP_BATCH); + display_progress(); + stop_sound(); + switch (install_type) + { + case INST_MIN:if (do_script(0) || do_script(-1) || do_script(-2) || do_script(-3)) error=1;break; + case INST_MED:if (do_script(0) || do_script(1) || do_script(-2) || do_script(-3)) error=1;break; + case INST_MAX:if (do_script(0) || do_script(1) || do_script(2) || do_script(3)) error=1; + break; + } + copy_self(1); + cpy_flush(); + copy_self(0); + close_ini(); + if (error) shutdown(),exit(1); + close_current(); + do_events(); + if (!autostart) msg_box("Hotovo",' ',"Hra 'Brny Skeldalu' je spn nainstalovna. Sputn provete z pkazov dky napsnm 'SKELDAL'","Konec",NULL); + purge_file_list(); + shutdown(); + home_path(target_path); + if (autostart) + { + puts("Chvilicku strpeni..."); + exit(254); + } + else exit(0); + } + +static EVENT_PROC (show_space_event) + { + OBJREC *o; + + o=(OBJREC *)user_ptr; + if (msg->msg==E_KEYBOARD || msg->msg==E_CURSOR_TICK) + { + char *c; + + c=o->data; + if (c[1]==':') + show_space(c[0]); + if (msg->msg==E_KEYBOARD) + *(char *)msg->data=toupper(*(char *)msg->data); + } + } + +static show_space_exit() + { + EVENT_MSG msg; + + msg.msg=E_KEYBOARD; + show_space_event(&msg,(void **)o_aktual); + } + + + +static void rozsah_window() + { + char buff[100]; + char *text="Velikost na HD zhruba %d KB"; + + exit_wait=0; + default_font=&font6x9; + def_dialoge(146,160,348,264,"Rozsah instalace",2); + define(10,10,30,70,30,0,button,"Minimln");property(bbutt,&font6x9,NULL,BUTTONCOLOR);on_change(start_install); + define(-1,90,30,1,1,0,label,"Instaluje jen nejdleitj soubory na HD"); + define(-1,90,40,1,1,0,label,"Ve ostatn se pak nat pmo z CD"); + sprintf(buff,text,install_sizes[0]/1024); + define(-1,90,50,1,1,0,label,buff); + define(20,10,80,70,30,0,button,"Stedn");property(bbutt,&font6x9,NULL,BUTTONCOLOR);on_change(start_install); + define(-1,90,80,1,1,0,label,"Instaluje vechny datov soubory na HD"); + define(-1,90,90,1,1,0,label,"Hudba a video se tou pmo z CD"); + sprintf(buff,text,install_sizes[1]/1024); + define(-1,90,100,1,1,0,label,buff); + define(30,10,130,70,30,0,button,"Maximln");property(bbutt,&font6x9,NULL,BUTTONCOLOR);on_change(start_install); + define(-1,90,130,1,1,0,label,"Instaluje ve na v HD vetn hudby"); + define(-1,90,140,1,1,0,label,"a videa. Z CD se nenat vbec nic."); + sprintf(buff,text,install_sizes[2]/1024); + define(-1,90,150,1,1,0,label,buff); + define(40,10,180,70,20,0,button,"Sloka");property(bbutt,&font6x9,NULL,BUTTONCOLOR);on_change(open_load_window); + define(60,90,185,250,11,0,input_line,2048);property(def_border(1,0x4210),&font6x9,NULL,0x7fff); + set_default(target_path); + on_event(show_space_event);on_exit(show_space_exit); + define(70,40,220,200,10,0,check_box,"Po nainstalovn hru automaticky spustit.");c_default(1); + define(80,10,10,250,11,2,view_line,100);set_default(""); + show_space(target_path[0]); + } + +static void automatic_window() + { + char buff[100]; + char *text="Hra zabere zhruba %d KB msta"; + + exit_wait=0; + default_font=&font6x9; + def_dialoge(110,200,420,80,"Instalovat kam?",2); + define(40,10,33,70,15,0,button,"Najt");property(bbutt,&font6x9,NULL,BUTTONCOLOR);on_change(open_load_window); + define(60,90,35,310,11,0,input_line,2048);property(def_border(1,0x4210),&font6x9,NULL,0x7fff); + set_default(target_path); + on_event(show_space_event);on_exit(show_space_exit); + define(10,10,10,70,20,2,button,"Start");property(bbutt,&font6x9,NULL,BUTTONCOLOR);on_change(start_install); + define(20,90,10,70,20,2,button,"<< Zpt");property(bbutt,&font6x9,NULL,BUTTONCOLOR);on_change(back_start); + sprintf(buff,text,install_sizes[0]/1024); + define(90,180,20,200,10,2,view_line,100);set_default(buff); + define(80,180,10,200,10,2,view_line,100);set_default(""); + show_space(target_path[0]); + redraw_window(); + } + + + +static void control_next1() + { + sound_scan(); + while (waktual!=NULL) close_current(); + rozsah_window(); + control_window(NULL,control_back1,open_help); + } + +static void control_window(void *forward,void *back,void *help) + { + def_dialoge(524,300,96,156,"Monosti",2); + define(10,8,30,80,20,0,button,"Dal >>");property(bbutt,&font6x9,NULL,BUTTONCOLOR);on_change(forward); + define(20,8,60,80,20,0,button,"<< Zpt");property(bbutt,&font6x9,NULL,BUTTONCOLOR);on_change(back); + define(30,8,90,80,20,0,button,"? Pomoc");property(bbutt,&font6x9,NULL,BUTTONCOLOR);on_change(help); + define(40,8,10,80,20,3,button,"Konec");property(bbutt,&font6x9,NULL,BUTTONCOLOR); + if (setup_mode) on_change(stop_setup);else on_change(stop_copy); + set_enable(0,10,forward!=NULL); + set_enable(0,20,back!=NULL); + set_enable(0,30,help!=NULL); + redraw_window(); + } + +static void run_setup() + { + int id; + + while (waktual!=NULL) close_current(); + get_script(_SOURCE_,""); + { + int minus[3]; + minus[1]=check_size(-2)+check_size(-3); + minus[0]=minus[1]+check_size(-1); + install_sizes[0]=check_size(0)+self_size(); + install_sizes[1]=install_sizes[0]+check_size(1); + install_sizes[2]=install_sizes[1]+check_size(2)+check_size(3); + install_sizes[0]+=minus[0]; + install_sizes[1]+=minus[1]; + id; + } + if (all_finder()) + { + char *c; + getcwd(&target_path,2047); + c=strchr(target_path,0); + c--; + if (*c=='\\') *c=0; + strcat(target_path,"\\"SKELDAL); + } + else + { + target_path[0]=select_disk()+'@'; + target_path[1]=':'; + target_path[2]='\\'; + strcpy(target_path+3,SKELDAL); + } + do + { + home_path(source_path); + back=0; + select_mode_win(); + about_window(); + id=o_aktual->id; + close_current(); + close_current(); + exit_wait=0; + if (id==10) + { + autodetect(); + automatic_window(); + } + if (id==30) + { + if (msg_box("Autodetekce?",'\x1',"Chcete nejprve provest autodetekci hardware?","Ano","Ne",NULL)==1) autodetect(); + select_vga(); + select_sound(); + control_window(control_next1,back_start,open_help); + } + if (id!=40) escape(); + } + while (back); + } + +static void save_ini() + { + char c[50]; + char d; + char err=1; + + if (sound_scan()) return; + d=msg_box("Potvrzen?",'\x2',"Chce zapsat zmny do konfiguranho souboru hry?","Ano","Ne","Zruit",NULL); + if (d==3) return; + if (d==1) + { + sprintf(c,"%d %x %d %d",sound_info.device, + sound_info.port, + sound_info.dma, + sound_info.irq); + add_field_txt(&setup_ini,SOUND_DEVICE,c); + add_field_num(&setup_ini,VMODE,vmode); + home_path(target_path); + err=save_config(setup_ini,SKELDAL_INI); + } + shutdown(); + home_path(target_path); + switch (err) + { + case -1:puts("Pri ukladani se objevila neocekavana chyba. Soubor "SKELDAL_INI" nebyl ulozen");break; + case 0:puts("Nastaveni bylo ulozeno..."); break; + case 1:puts("Nastaveni nebylo zmeneno..."); break; + } + exit(0); + } + +static void deinstall() + { + char ig; + int x,y; + def_dialoge(200,200,250,156,"Odinstalovat?",2); + define(-1,10,30,200,100,0,label,"Tato volba odstran hru z vaeho disku."); + define(-1,10,40,200,100,0,label,"Pot ji nebude mone hru spustit"); + define(-1,10,50,200,100,0,label,"do novho nainstalovn z CD."); + define(10,30,80,150,10,0,check_box,"Zachovat uloen pozice");c_default(1); + define(20,10,10,80,30,3,button,"Ano");property(bbutt,&font6x9,NULL,BUTTONCOLOR);on_change(terminate); + define(30,10,10,80,30,2,button,"Proboha NE");property(bbutt,&font6x9,NULL,BUTTONCOLOR);on_change(terminate); + redraw_window(); + escape(); + if (o_aktual->id==30) + { + close_current(); + return; + } + ig=f_get_value(0,10); + set_enable(0,30,0); + set_enable(0,20,0); + set_enable(0,10,0); + do_events(); + home_path(target_path); + cascade_delete(ig); + chdir(".."); + rmdir(target_path); + home_path(source_path); + curcolor=0; + for(x=319;x>-1;x-=2) + { + y=x*240/320;bar(x,y,639-x,479-y);showview(0,0,0,0); + } + shutdown(); + exit(0); + } + +static void run_resetup() + { + int id; + + while (waktual!=NULL) close_current(); + do + { + home_path(source_path); + back=0; + select_mode_win_setup(); + about_window(); + id=o_aktual->id; + close_current(); + close_current(); + exit_wait=0; + if (id==30) + { + deinstall(); + back=1; + } + if (id==10) + { + select_vga(); + select_sound(); + control_window(save_ini,back_start,NULL); + } + if (id!=40) escape(); + } + while (back); + } + + +#define REPEAT(i,cnt) for(i=0;i=2 && argv[1][0]=='-' && toupper(argv[1][1])=='S') || access(SKELDAL_INI,F_OK)==0) + { + char *c; + char *d; + setup_mode=1; + getcwd(target_path,PATH_MAX+1); + setup_ini=read_config(SKELDAL_INI); + if (setup_ini==NULL) + { + printf("The file %s has not been found. You must reinstall the game\n" + "Insert the CD into driver and run INSTALL.EXE\n",SKELDAL_INI); + printf("Nemohu najit soubor %s. Budes muset hru znovu nainstalovat\n" + "Z CD \"Brany Skeldalu\" spust program INSTALL.EXE\n",SKELDAL_INI); + exit(0); + } + get_num_field(setup_ini,VMODE,&vmode); + c=get_text_field(setup_ini,"CESTA_CD"); + program_data_path=NewArr(char,strlen(c)+1);strcpy(program_data_path,c); + c=strchr(program_data_path,0); + if (c>program_data_path && c[-1]=='\n') c[-1]=0,c--; + if (c>program_data_path && c[-1]=='\\') c[-1]=0; + c=get_text_field(setup_ini,SOUND_DEVICE); + sscanf(c,"%d %x %d %d",&sound_info.device, + &sound_info.port, + &sound_info.dma, + &sound_info.irq); + c=alloca(strlen(argv[0])+1); + strcpy(c,argv[0]); + d=strrchr(c,'\\'); + if (d!=NULL) + { + d[d-c<=2]=0; + home_path(c); + } + } + } + +main(int argc,char **argv) + { + char s; + char *c; + + pgm_name=argv[0]; + check_setup_mode(argc,argv); + if (argc==2 && !setup_mode) copy_source_path=argv[1];else copy_source_path=NULL; + if (!setup_mode) + { + _setvideomode(_TEXTC80); + rescue_mode=!(s=create_er_file()); + if (s && !setup_mode) warning(),getche(); + } + else + s=0; + init_setup(s); + create_video_ls(); + set_mixing_device(0,22050,0,0,0); + c=test_sound_name=NewArr(char, strlen(program_data_path)+strlen(TEST_MUSIC)+1); + sprintf(c,"%s%s",program_data_path,TEST_MUSIC); + if (access(c,F_OK)!=0) + { + shutdown(); + printf("Vloz CD \"Brany Skeldalu\" do jednotky CD-ROM a spust znova instalaci\n" + "Insert CD \"The Gates of the Skeldal\" into CD-ROM and try to run INSTALL again.\n"); + abort(); + } + konec_skladby=skladba_konec; + change_music(c); + mix_back_sound(2); + if (setup_mode) run_resetup(); + else + { + if (!rescue_mode) run_setup(); + if (rescue_mode) + { + ask_video(); + escape(); + } + } + shutdown(); + } diff --git a/INST/SETUP.H b/INST/SETUP.H new file mode 100644 index 0000000..14263b1 --- /dev/null +++ b/INST/SETUP.H @@ -0,0 +1,18 @@ +extern word ikones; +extern word boldcz; +extern word sipka; +extern word font6x9; +extern void *bbutt; +extern word *vga_font; +extern word *icones; +extern word icone_color[]; +extern word ramecek; +extern word *ramecky[]; + +//#define WINCOLOR 0x6318 +#define WINCOLOR (31*1024+31*32+26) +#define LABELCOLOR (11*1024+11*32+06) +#define BUTTONCOLOR (28*1024+24*32+3) +#define PRG_HEADER "Brny Skeldalu Setup v1."VERSION + +extern FILE *ini; diff --git a/INST/SETUPCPY.C b/INST/SETUPCPY.C new file mode 100644 index 0000000..eebedaf --- /dev/null +++ b/INST/SETUPCPY.C @@ -0,0 +1,165 @@ +#include +#include +#include +#include +#include "setupcpy.h" + +#define DATASIZE 32768 +#define INFOBLOCK 1 +#define DATABLOCK 2 +#define ERRORBLOCK 3 + +typedef struct tdatablock + { + void *next; + char block_type; + unsigned short load_size; + char data[DATASIZE]; + }TDATABLOCK; + +typedef struct tinfoblock + { + void *next; + char block_type; + char pathname[2]; + }TINFOBLOCK; + +static void *start=NULL; +static void *end=NULL; +static FILE *cpyout=NULL; +static long progress=0; + +void (*cpy_error)(int,char *); +void (*mem_error_next)(long); + +void (*cpy_progress)(long); + + +static void *alloc_file(char *target_name) + { + TINFOBLOCK *p; + + p=(TINFOBLOCK *)getmem(sizeof(TINFOBLOCK)+strlen(target_name)); + strcpy(p->pathname,target_name); + p->next=NULL; + p->block_type=INFOBLOCK; + return p; + } + +static void *alloc_data() + { + TDATABLOCK *p; + + p=New(TDATABLOCK); + p->next=NULL; + p->load_size=0; + p->block_type=DATABLOCK; + return p; + } + + +static void *load_data(FILE *f) + { + TDATABLOCK *p; + int rc; + int retry=0; + void *end_line; + + p=end_line=alloc_data(); + again: + errno=0; + rc=fread(p->data,1,sizeof(p->data),f); + p->load_size=rc; + if (ferror(f) || rc!=sizeof(p->data) && errno!=0) + { + if (retry) retry--; + else cpy_error(CPERR_READ,NULL); + fseek(f,-rc,SEEK_CUR); + errno=0; + goto again; + } + progress+=p->load_size; + cpy_progress(progress); + return end_line; + } + +static error_mem(long size) + { + TDATABLOCK *p; + TINFOBLOCK *q; + int rc; + + size; + if (start==NULL) mem_error_next(size); + while (start!=NULL) + { + p=start; + q=start; + if (q->block_type==INFOBLOCK) + { + if (cpyout!=NULL) fclose(cpyout); + again: + cpyout=fopen(q->pathname,"wb"); + if (cpyout==NULL) + { + cpy_error(CPERR_OPEN,q->pathname); + goto again; + } + start=q->next; + free(q); + } + else if (p->block_type==DATABLOCK) + { + again2: + rc=fwrite(p->data,1,p->load_size,cpyout); + if (rc!=p->load_size) + { + cpy_error(CPERR_WRITE,q->pathname); + fseek(cpyout,-rc,SEEK_CUR); + goto again2; + } + progress+=p->load_size; + cpy_progress(progress); + start=p->next; + free(p); + } + } + end=NULL; + } + +void cpy_file(char *source,char *target) + { + FILE *f; + TDATABLOCK *p; + TINFOBLOCK *q; + + again: + errno=0; + f=fopen(source,"rb"); + if (f==NULL) + { + cpy_error(CPERR_OPEN,source); + goto again; + } + q=alloc_file(target); + if (start==NULL) start=end=q;else end=(((TDATABLOCK *)end)->next=q); + while (!feof(f)) + { + p=load_data(f); + if (start==NULL) start=end=p;else end=(((TDATABLOCK *)end)->next=p); + } + fclose(f); + } + +void cpy_flush() + { + if (start!=NULL)error_mem(0); + if (cpyout!=NULL)fclose(cpyout); + cpyout=NULL; + } + +void install_cpy() + { + mem_error_next=mem_error; + mem_error=error_mem; + } diff --git a/INST/SETUPCPY.H b/INST/SETUPCPY.H new file mode 100644 index 0000000..e46a382 --- /dev/null +++ b/INST/SETUPCPY.H @@ -0,0 +1,9 @@ +#define CPERR_OPEN 1 +#define CPERR_WRITE 2 +#define CPERR_READ 3 + +extern void (*cpy_error)(int,char *); +extern void (*cpy_progress)(long); +void cpy_file(char *source,char *target); +void cpy_flush(); +void install_cpy(); diff --git a/INST/SETUPLIB.C b/INST/SETUPLIB.C new file mode 100644 index 0000000..936cc70 --- /dev/null +++ b/INST/SETUPLIB.C @@ -0,0 +1,505 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "setuplib.h" +#include "setupcpy.h" +#include "setup.h" + +#define COPY "COPY" +#define MKDIR "MKDIR" +#define INI "INI" + +#define DIR_NAMES 6 +char *dirnames[]= + { + "GAMES.*", + "GAME*.*", + "HRY.*", + "ZABAVA.*", + "SKELDAL", + "NAPOLEON", + }; + +TSTR_LIST file_list=NULL; + +static void done_bar_init(OBJREC *o,long *params) + { + o->userptr=New(long); + *(long *)o->userptr=*params; + } + +static void done_bar_draw(int x1,int y1,int x2,int y2,OBJREC *o) + { + long value,max,x3; + + value=*(long *)o->data; + max=*(long *)o->userptr; + x3=x1+(x2-x1)*value/max; + if (x3<=x1) x3=x1; + if (x3>=x2) x3=x2; + bar(x3,y1,x2,y2); + curcolor=o->f_color[1]; + bar(x1,y1,x3,y2); + } + +void done_bar(OBJREC *o) //define(...done_bar,max); + { + o->runs[0]=done_bar_init; + o->runs[1]=done_bar_draw; + o->datasize=4; + } + + + +char select_disk() + { + char last=3; + struct diskfree_t ds; + int max=0,i; + long now; + + for(i=('C'-'@');i<('Z'-'@');i++) + { + if (_dos_getdiskfree(i,&ds)==0) + { + now=ds.avail_clusters*ds.sectors_per_cluster*ds.bytes_per_sector; + if (now>max) + { + max=now; + last=i; + } + } + } + return last; + } + +char dir_finder() + { + struct find_t ft; + int i; + int rc; + + for(i=0;imax && sz[j]datasize=(*len)+1; + } + +static void view_line_draw(int x1,int y1, int x2, int y2, OBJREC *o) + { + char *c; + + bar(x1,y1,x2,y2); + c=(char *)o->data; + if (!*c) return; + set_aligned_position(x2,y1,2,0,c); + outtext(c); + } + + +void view_line(OBJREC *o) + { + o->runs[0]=view_line_init; + o->runs[1]=view_line_draw; + } + + +char get_max_res() + { + if (vesasupport(0x110)) return 2; + if (vesasupport(0x100)) return 1; + return 0; + } + +void add_to_list(char *name) + { + if (file_list==NULL) file_list=create_list(256); + str_add(&file_list,name); + } + +static void copy_1_file(char *init_mask,char *filename,char *target) + { + char *c,*d; + + c=alloca(strlen(init_mask)+strlen(filename)+1); + strcpy(c,init_mask); + d=strrchr(c,'\\'); + d++; + strcpy(d,filename); + d=alloca(strlen(target)+strlen(filename)+10); + strcpy(d,target); + if (d[0]==0 || d[strlen(d)-1]!='\\') strcat(d,"\\"); + strcat(d,filename); + set_value(0,20,filename); + add_to_list(d); + cpy_file(c,d); + } + +static void copy_files(char *param) + { + struct find_t ft; + char *source_mask; + char *target; + int rc; + + target=strchr(param,' '); + if (target==NULL) return; + source_mask=alloca(target-param); + source_mask[target-param]=0; + strncpy(source_mask,param,target-param); + target++; + rc=_dos_findfirst(source_mask,_A_NORMAL,&ft); + while (rc==0) + { + copy_1_file(source_mask,ft.name,target); + rc=_dos_findnext(&ft); + } + _dos_findclose(&ft); + } + +char cascade_mkdir(char *path) + { + char *c; + char d; + + if (path[0]==0||path[1]==':' && path[2]==0) return 0; + if (!access(path,F_OK)) return 0; + c=strrchr(path,'\\'); + if (c==NULL) return 0; + *c=0; + d=cascade_mkdir(path); + *c='\\'; + if (d==1) return 1; + if (mkdir(path)!=0) return 1; + add_to_list(path); + return 0; + } + + +static char add_to_ini(char *params) + { + return fprintf(ini,"%s\n",params)<0; + } + +static char *commands[]= + { + COPY, + MKDIR, + INI, + }; + +static char (*calls[])(char *params)= + { + copy_files, + cascade_mkdir, + add_to_ini, + }; + + + +static char command_match(char *cmd,char *test,char **params) + { + while (*test) if (toupper(*cmd++)!=toupper(*test++)) return 0; + if (*cmd!=' ') return 0; + *params=cmd+1; + return 1; + } + + +char do_script(int section) + { + int pos; + int num; + int str_siz=str_count(script); + char *command; + + for(pos=0;pos"); + } + return s; + } + +char validate_path(char *path) + { + unsigned disk; + unsigned cdisk,lastdrv; + char *c,ll=0,tt=0,d; + + static char valid[]="$%'_@{}~`#()&-"; + + if (path==NULL || path[0]==0 || path[1]!=':' || path[2]!='\\') return 0; + disk=toupper(path[0]); + if (disk<'A' || disk>'Z') return 0; + _dos_getdrive(&cdisk); + disk-='@';_dos_setdrive(disk,&lastdrv); + _dos_getdrive(&lastdrv); + disk=(disk==lastdrv); + _dos_setdrive(cdisk,&lastdrv); + if (!disk) return 0; + c=path+2;ll=0; + while (*c) + { + d=toupper(*c); + if (d=='\\') + if (ll) return 0;else ll=1,tt=0; + else + if (d>='A' && d<='Z' || d>='0' && d<='9' || strchr(valid,d)!=NULL || d>127) ll=0; + else if (d=='.') if (tt) return 0;else tt=1; + else return 0; + c++; + } + if (ll) return 0; + return 1; + } + +void clean_up() + { + int i,cnt; + if (file_list==NULL) return; + cnt=str_count(file_list); + for(i=cnt-1;i>=0;i--) if (file_list[i]!=NULL) + { + if (remove(file_list[i])) rmdir(file_list[i]); + } + release_list(file_list); + file_list=NULL; + } + +void purge_file_list() + { + if (file_list==NULL) return; + release_list(file_list); + file_list=NULL; + } + +char cascade_delete(char ignore_sav) + { + struct find_t f; + int rc; + + rc=_dos_findfirst("*.*",_A_SUBDIR,&f); + while (rc==0) + { + if (f.attrib & _A_SUBDIR) + { + if (f.name[0]!='.') + { + chdir(f.name); + cascade_delete(ignore_sav); + chdir(".."); + rmdir(f.name); + } + } + else + { + char *c=strchr(f.name,'.'); + + if (c!=NULL) + { + strupr(c); + if (!ignore_sav || strncmp(c,".SAV",4)) remove(f.name); + } + else remove(f.name); + } + rc=_dos_findnext(&f); + } + return 0; + } diff --git a/INST/SETUPLIB.H b/INST/SETUPLIB.H new file mode 100644 index 0000000..7928d30 --- /dev/null +++ b/INST/SETUPLIB.H @@ -0,0 +1,22 @@ +char all_finder(); +char select_disk(); +char read_script(char *filename,char *source_path,char *target_path); +long check_size(int gr); +long get_disk_free(char disk); +void view_line(OBJREC *o); +char *get_cdrom(); +char get_max_res(); +char do_script(int); +void done_bar(); //define(...done_bar,max); +char cascade_mkdir(char *path); +char validate_path(char *path); +char cascade_delete(char ignore_sav); //maze soubory a podadresare. Pripadne ignoruje soubory SAV + +void clean_up(); //maze zkopirovane soubory a adresare +void purge_file_list(); +void add_to_list(char *name); + + +#define INST_MIN 0 +#define INST_MED 1 +#define INST_MAX 2 diff --git a/INST/SETVIDEO.C b/INST/SETVIDEO.C new file mode 100644 index 0000000..c5505b3 --- /dev/null +++ b/INST/SETVIDEO.C @@ -0,0 +1,197 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "setup.h" + +static void *xlat256=NULL; +static void *xlat16=NULL; + +static void create_xlats() + { + if (xlat256==NULL) xlat256=create_special_palette(); + if (xlat16==NULL) xlat16=create_blw_palette16(); + } + + +static void initgr_common() + { + register_ms_cursor(&sipka); + init_mysky(); + hranice_mysky(0,0,639,479); + update_mysky(); + schovej_mysku(); + bar(0,0,639,479); + showview(0,0,0,0); + } + +int initgr_auto() + { + int vmode; + create_xlats(); + vmode=2; + if (initmode32()) + { + vmode=1; + if (initmode256(xlat256)) + { + vmode=0; + initmode16(xlat16); + } + } + initgr_common(); + return vmode; + } + +int initgr_spec(int vmode) + { + int i=-1; + create_xlats(); + switch (vmode) + { + case 0:i=initmode_lo(xlat256);break; + case 1:i=initmode256(xlat256);break; + case 2:i=initmode32();break; + } + initgr_common(); + return i; + } + +void initgr_low() + { + create_xlats(); + initmode16(xlat16); + initgr_common(); + } + +void donegr() + { + closemode(); + done_mysky(); + } + +void kresli_okno(WINDOW *w) + { + int x,y; + int xs,ys,xsr,ysr; + int x1,y1,xs1,ys1; + int i,j; + + xsr=ramecky[0][0]; + ysr=ramecky[0][1]; + x1=w->x-12; + y1=w->y-12; + xs1=w->xs+24; + ys1=w->ys+24; + xs=xs1/xsr; + ys=ys1/ysr; + curcolor=w->color; + bar(w->x,w->y,w->x+w->xs,w->y+w->ys); + for(j=0,y=y1;jx; + y=waktual->y; + } + name; + highlight(&ctl,WINCOLOR); + ctl.bsize=2;ctl.ctldef=0; + x+=20;y+=20; + memcpy(fc,flat_color(0x7fe0),sizeof(FC_TABLE)); + fc[0]=0x0000; + if (x+xs>MAX_X-2) x=MAX_X-2-xs; + if (y+ys>MAX_Y-2) y=MAX_Y-2-ys; + p=create_window(x,y,xs,ys,WINCOLOR,&ctl); + q=desktop_add_window(p); + define(0,2,2,xs-5-20*(xs>=70),14,0,win_label,name); + ctl.bsize=1;ctl.ctldef=1; + o_end->autoresizex=1; + property(&ctl,vga_font,&fc,LABELCOLOR); + if (xs>=70) + { + define(1,1,1,19,16,1,button,"\x0f"); + property(NULL,icones,&icone_color,WINCOLOR);on_change(close_current); + } + return q; + } + +int def_dialoge(word x,word y,word xs, word ys, char *name,char modal) + { + CTL3D ctl; + FC_TABLE fc; + WINDOW *p; + int i; + + memcpy(fc,flat_color(0x7fe0),sizeof(FC_TABLE)); + if (modal & 0x2) + { + ctl.bsize=12; + xs=((xs+6)/12)*12; + ys=((ys+6)/12)*12; + } + else + memcpy(&ctl,def_border(2,WINCOLOR),sizeof(CTL3D)); + p=create_window(x,y,xs,ys,WINCOLOR,&ctl); + i=desktop_add_window(p); + if (modal & 1) set_window_modal(); + memcpy(&ctl,def_border(5,WINCOLOR),sizeof(CTL3D)); + if (name!=NULL) + { + define(0,2,2,xs-4,14,0,win_label,name); + o_end->autoresizex=1; + property(&ctl,vga_font,&fc,LABELCOLOR); + } + if (modal & 0x2) p->draw_event=kresli_okno; + return i; + } + +void def_listbox(int id,word x,word y,word xs,word ys,TSTR_LIST ls,int ofs,int color) + { + CTL3D b1,b2; + word black[]={0,0,0,0,0,0}; + + memcpy(&b1,def_border(1,0),sizeof(CTL3D)); + memcpy(&b2,def_border(5,WINCOLOR),sizeof(CTL3D)); + define(id+1,x+xs+4,y+18,15,ys-35,0,scroll_bar_v,0,10,1,0x0200); + property(&b2,NULL,NULL,WINCOLOR); + define(id+2,x+xs+4,y,14,14,0,scroll_button,-1,0,"\x4"); + property(&b1,icones,black,WINCOLOR);on_change(scroll_support); + define(id+3,x+xs+4,y+ys-14,14,14,0,scroll_button,1,10,"\6"); + property(&b1,icones,black,WINCOLOR);on_change(scroll_support); + define(id,x,y,xs,ys,0,listbox,ls,color,ofs); + property(&b2,NULL,NULL,WINCOLOR); + } + diff --git a/INST/SETVIDEO.H b/INST/SETVIDEO.H new file mode 100644 index 0000000..dce03e5 --- /dev/null +++ b/INST/SETVIDEO.H @@ -0,0 +1,6 @@ +int initgr_auto(); +void initgr_low(); +int initgr_spec(int vmode); +void donegr(); +int def_dialoge(word x,word y,word xs, word ys, char *name,char modal); +void def_listbox(int id,word x,word y,word xs,word ys,TSTR_LIST ls,int ofs,int color); diff --git a/INST/STUB.C b/INST/STUB.C new file mode 100644 index 0000000..c059d9b --- /dev/null +++ b/INST/STUB.C @@ -0,0 +1,53 @@ +#include +#include +#include +#include +#include +#define QUIET x + +/* Add environment strings to be searched here */ +char *paths_to_check[] = { + "DOS4GPATH", + "PATH"}; + +char *dos4g_path() +{ + static char fullpath[80]; + int i; + + for( i = 0; + i < sizeof( paths_to_check ) / sizeof( paths_to_check[0] ); i++ ) { + _searchenv( "dos4gw.exe", paths_to_check[i], fullpath ); + if( fullpath[0] ) return( &fullpath ); + } + for( i = 0; + i < sizeof( paths_to_check ) / sizeof( paths_to_check[0] ); i++ ) { + _searchenv( "dos4g.exe", paths_to_check[i], fullpath ); + if( fullpath[0] ) return( &fullpath ); + } + return( "dos4gw.exe" ); +} + +main( int argc, char *argv[] ) +{ + char *av[4]; + auto char cmdline[128]; + int i; + av[0] = dos4g_path(); /* Locate the DOS/4G loader */ + av[1] = argv[0]; /* name of executable to run */ + av[2] = getcmd( cmdline ); /* command line */ + av[3] = NULL; /* end of list */ +#ifdef QUIET + putenv( "DOS4G=QUIET" ); /* disables DOS/4G Copyright banner */ +#endif + printf("Instalator Brny Skeldalu (C)1997 Napoleon gameS Nahrvm... \n"); + i=spawnvp(P_WAIT, av[0], av ); + if (i==254) + execl(av[0],av[0],"SKELDAL.EXE",NULL);else exit(0); + puts( "Chyba pri nacitani extenderu:" ); + puts( av[0] ); + puts( "\nZkontrolujte zda-li je k dosazeni na aktualnim adresari\n" + "popripade specifikujte jeho v cestu v systemove promenne:\n" + "SET DOS4GPATH=disk:\\cesta\n"); + exit( 1 ); /* indicate error */ +} diff --git a/INST/TEXTLIB.ASM b/INST/TEXTLIB.ASM new file mode 100644 index 0000000..3ec6511 --- /dev/null +++ b/INST/TEXTLIB.ASM @@ -0,0 +1,101 @@ +.model small +.386 + +SEGB800 equ 0b8000h + +_TEXT segment byte public 'CODE' use32 + assume CS:_TEXT + assume DS:DGROUP + +public load_font_ +load_font_: ;esi font + mov esi,offset fonttable + mov edx,3c4h + mov eax,0402h + out dx,ax + mov eax,0704h + out dx,ax + Mov edx,3ceh + mov eax,0204h + out dx,ax + mov eax,0005h + out dx,ax + mov eax,0406h + out dx,ax + mov edi,0xA0000h + mov edx,256 +lfOpk: mov ecx,16 + rep movsb + add edi,16 + dec edx + jne lfopk + mov edx,3c4h + mov eax,0302h + out dx,ax + mov eax,0304h + out dx,ax + Mov edx,3ceh + mov eax,0004h + out dx,ax + mov eax,1005h + out dx,ax + mov eax,0E06h + out dx,ax + ret + +public set_font_8x8_ +set_font_8x8_: + cli + mov edx,3d4h + mov eax,0100h + out dx,ax + mov edx,3c4h + mov al,1 + out dx,al + inc edx + in al,dx + or al,1 + out dx,al + mov edx,03dah + in al,dx + mov edx,03c0h + mov al,13h + out dx,al + mov al,0 + out dx,ax + mov al,32 + out dx,al + mov edx,3d4h + mov eax,0300h + out dx,ax + sti + ret + +public turn_flashing_ ;ebx - ON/OFF +turn_flashing_: + mov eax,1003h + int 10h + ret + + +public get_window_size_ ;eax,edx-velikost +get_window_size_: + imul eax,edx + shl eax,1 + add eax,4 + ret + +public save_window_ ;eax,edx-pozice + ;ecx,ebx-velikost + ;edi - buffer +save_window_ + stosb + imul eax,160 + lea eax,[eax+edx*2] + lea esi,[eax+SEGB800] + mov al,dl + stosb + mov al,bl + mov ah,cl + stosw + mov edx,ebx diff --git a/INST/TEXTLIB.C b/INST/TEXTLIB.C new file mode 100644 index 0000000..fd40910 --- /dev/null +++ b/INST/TEXTLIB.C @@ -0,0 +1,4 @@ + + + + diff --git a/LIBS/ADDTEXT.C b/LIBS/ADDTEXT.C new file mode 100644 index 0000000..14b9222 --- /dev/null +++ b/LIBS/ADDTEXT.C @@ -0,0 +1,120 @@ +#include +#include +#include "memman.c" +#include "strlite.c" + + +TSTR_LIST ls_origin=NULL; +TSTR_LIST ls_new=NULL; + +static void load_error_msg(int err,char *filename) + { + switch (err) + { + case -1: puts ("Source or target file not found");break; + case -2: puts ("Unexcepted EOF");break; + case -3: puts ("Internal error in strlite.c");break; + default: printf("Error in string table at line %d.\n",err); + } + printf("File:%s\n",filename); + exit(1); + } + +void load_lists(char *filename1,char *filename2) + { + int err; + + err=load_string_list(&ls_new,filename1); + if (err) load_error_msg(err,filename1); + err=load_string_list(&ls_origin,filename2); + if (err) load_error_msg(err,filename2); + } + + +char *create_backup(char *filename) + { + char *c,*d; + + c=getmem(strlen(filename)+5);strcpy(c,filename); + d=strrchr(c,'.');if (d==NULL) d=strchr(c,0); + strcpy(d,".bak"); + remove(c); + rename(filename,c); + return c; + } + +void spoj_stringtable() + { + int i; + int cnt=str_count(ls_new); + for(i=0;i +#include +#include +#include +#include +#include +#include + +char copy_path[500]; +char *adv_name; + +char _change_disk(unsigned znak) + { + unsigned total; + znak-='@'; + _dos_setdrive(znak,&total); + _dos_getdrive(&total); + return total==znak; + } + +char disk_finder() + { + static struct find_t ft; + int err; + + if (!access("SKELDAL.EXE",F_OK) && !access("ADV",F_OK)) return 1; + err=_dos_findfirst("*.*",_A_SUBDIR,&ft); + while (!err) + { + if (ft.attrib & _A_SUBDIR && strcmp(ft.name,".") && strcmp(ft.name,"..")) + { + chdir(ft.name); + if (disk_finder()) return 1; + chdir(".."); + } + err=_dos_findnext(&ft); + } + return 0; + } + +char find_path(char *path) + { + char *oldpath; + unsigned pismeno='C'; + + cputs("Hledam...\r"); + oldpath=getcwd(NULL,PATH_MAX); + for(pismeno='C';pismeno<='Z';pismeno++) + { + _change_disk(pismeno); + chdir(".."); + if (disk_finder()==1) + { + getcwd(path,PATH_MAX); + chdir(oldpath);_change_disk(oldpath[0]); + free(oldpath); + return 1; + } + } + chdir(oldpath);_change_disk(oldpath[0]); + free(oldpath); + return 1; + } + + +void main(int argc,char **argv) + { + char temp[550]; + char rep; + if (argc<2) + { + puts("Nespravne parametry!\n" + "\n" + "Pouziti ADVINST [jmeno]\n" + "\n" + "jmeno = Nazev dobrodruzstvi bez pripony"); + return; + } + adv_name=argv[1]; + sprintf(temp,"%s.adv",adv_name); + if (access(adv_name,F_OK) && access(temp,F_OK)) + { + printf("Nemohu najit zadne dobrodruzstvi s timto jmenem (%s)!\n",adv_name); + return; + } + do + { + printf("Vypiste celou cestu, kde lezi hra (napr: c:\\hry\\skeldal)\n" + "Pokud vlozte otaznik (?), instalator se pokusi hru na disku vyhledat\n" + "Pokud stisknete pouze , instalator se ukonci\n" + ">"); + gets(copy_path); + if (copy_path[0]=='?') + { + find_path(copy_path); + printf("\nInstalator nasel hru na ceste: %s\n\n",copy_path); + } + if (copy_path[0]==0) return; + sprintf(temp,"%s\\skeldal.exe",copy_path); + rep=access(temp,F_OK); + if (rep) puts("Vami vlozena cesta neni spravna!\n"); + else + { + sprintf(temp,"%s\\adv\\%s",copy_path,adv_name); + if (access(temp,F_OK))if (mkdir(temp)!=0) printf("Nedokazal jsem vytvorit adresar %s\n\n\n",temp),rep=1; + } + } + while(rep); + sprintf(temp,"copy %s.adv %s > nul",adv_name,copy_path); + puts(temp); + system(temp); + sprintf(temp,"copy %s\\*.* %s\\adv\\%s > nul",adv_name,copy_path,adv_name); + puts(temp); + system(temp); + sprintf(temp,"%s.bat",adv_name); + if (access(temp,F_OK)==0) + { + sprintf(temp,"%s.bat %s",adv_name,copy_path); + puts(temp); + system(temp); + } + chdir(copy_path); + puts("Instalace uspesna!"); + printf("Nove dobrodruzstvi spustis prikazem SKELDAL %s.adv\n",adv_name); + puts("Chces si nyni nove dobrodruzstvi vyzkouset? ANO/NE (cokoliv/N)"); + if (toupper(getche())=='N') return; + sprintf(temp,"SKELDAL %s.adv",adv_name); + system(temp); + } + + + diff --git a/LIBS/BASICOBJ.C b/LIBS/BASICOBJ.C new file mode 100644 index 0000000..4a06672 --- /dev/null +++ b/LIBS/BASICOBJ.C @@ -0,0 +1,1332 @@ +#include +// toto je include soubor, jenz je pouzit v knihovne GUI.C + +#include "types.h" +#include +#include +#include +#include +#include "memman.h" +#include "event.h" +#include "devices.h" +#include "bmouse.h" +#include "bgraph.h" +#include "gui.h" +#include "basicobj.h" + +#define MEMTEXT "Pamt: " + +#define E_STATUS_LINE 60 + +//FC_TABLE f_bila={0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}; + +void highlight(CTL3D *c,word color) + { + c->light=color<<1; + if (c->light & 0x0020) {c->light&=~RGB555(0,0,31);c->light|=RGB555(0,0,31);} + if (c->light & 0x0400) {c->light&=~RGB555(0,31,0);c->light|=RGB555(0,31,0);} + if (c->light & 0x8000) {c->light&=~RGB555(31,0,0);c->light|=RGB555(31,0,0);} + c->shadow=color; + c->shadow&=RGB555(30,30,31); + c->shadow>>=1; + } + + +CTL3D *def_border(int btype,int color) + { + static CTL3D ctl; + + highlight(&ctl,color); + switch (btype) + { + case 0:ctl.bsize=0; + case 1:ctl.light=color;ctl.shadow=color;ctl.bsize=1;break; + case 2:ctl.bsize=2;ctl.ctldef=0;break; + case 3:ctl.bsize=2;ctl.ctldef=3;break; + case 4:ctl.bsize=1;ctl.ctldef=0;break; + case 5:ctl.bsize=1;ctl.ctldef=1;break; + case 6:ctl.bsize=2;ctl.ctldef=1;break; + case 7:ctl.bsize=2;ctl.ctldef=2;break; + } + return &ctl; + } + +void sample_init(OBJREC *o,char *title) + { + title=get_title(title); + o->userptr=(void *)getmem(strlen(title)+1); + strcpy((char *)o->userptr,title); + } + + +void sample_draw(int x1,int y1,int x2,int y2,OBJREC *o) + { + x2;y2; + position(x1,y1); + outtext((char *)o->userptr); + } + +void mid_label_draw(int x1,int y1,int x2, int y2,OBJREC *o) + { + x2;y2; + set_aligned_position((x1+x2)/2,y1,1,0,(char *)o->userptr); + outtext((char *)o->userptr); + } + + +void sample_event(EVENT_MSG *msg,OBJREC *o) + { + MS_EVENT *ms; + + o; + if (msg->msg==E_MOUSE) + { + ms=get_mouse(msg); + if (ms->tl1) exit_wait=1; + } + } + + +void sample(OBJREC *o) + { + o->runs[0]=sample_init; + o->runs[1]=sample_draw; + o->runs[2]=sample_event; + //o->runs[3]=sample_done; + } + +//------------------------------------------ +void button_init(OBJREC *o,char *title) + { + char *v; + title=get_title(title); + o->userptr=(void *)getmem(strlen(title)+1); + strcpy((char *)o->userptr,title); + v=(char *)o->data; + *v=0; + } + +void button_draw(int x1,int y1,int x2,int y2,OBJREC *o) + { + CTL3D x; + char w; + + bar(x1,y1,x2,y2); + highlight(&x,o->color); + w=*(char *)o->data; + x.bsize=2-w; + x.ctldef=(w<<1)+w; + draw_border(x1+2,y1+2,x2-x1-4,y2-y1-4,&x); + set_aligned_position(((x1+x2)>>1)+(w<<1),((y1+y2)>>1)+(w<<1),1,1,(char *)o->userptr); + outtext((char *)o->userptr); + } + +void button_draw2(int x1,int y1,int x2,int y2,OBJREC *o) + { + CTL3D x; + char w; + + bar(x1,y1,x2,y2); + highlight(&x,o->color); + w=*(char *)o->data; + x.bsize=1; + x.ctldef=(w<<1)+w; + draw_border(x1+1,y1+1,x2-x1-2,y2-y1-2,&x); + if (!w) + { + curcolor=x.light;hor_line(x1,y1,x2);hor_line(x1,y1+1,x2); + curcolor=x.shadow;hor_line(x1,y2,x2);hor_line(x1,y2-1,x2); + } + set_aligned_position(((x1+x2)>>1)+(w<<1),((y1+y2)>>1)+(w<<1),1,1,(char *)o->userptr); + outtext((char *)o->userptr); + } + + +void button_event(EVENT_MSG *msg,OBJREC *o) + { + MS_EVENT *ms; + + if (msg->msg==E_MOUSE) + { + ms=get_mouse(msg); + if (ms->event_type & 0x06) + { + if (ms->tl1) + { + *(char *)o->data=1; + redraw_object(o); + } + else if (*(char *)o->data) + { + *(char *)o->data=0; + redraw_object(o); + set_change(); + } + } + } + + if (msg->msg==E_GET_FOCUS || msg->msg==E_LOST_FOCUS) + { + *(char *)o->data=0; + redraw_object(o); + } + } + + + +void button(OBJREC *o) + { + o->runs[0]=button_init; + o->runs[1]=button_draw; + o->runs[2]=button_event; + //o->runs[3]=button_done; + o->datasize=1; + } + +void button2(OBJREC *o) + { + o->runs[0]=button_init; + o->runs[1]=button_draw2; + o->runs[2]=button_event; + //o->runs[3]=button_done; + o->datasize=1; + } + + +//------------------------------------------ + +void draw_status_line(char *c) + { + static word *font; + static FC_TABLE color; + static word backgr; + static word ysmax=0,y; + word ysize; + CTL3D ctl; + + if (c==NULL) + { + backgr=curcolor; + memcpy(&color,&charcolors,sizeof(charcolors)); + font=curfont; + return; + } + + schovej_mysku(); + curfont=font; + ysize=text_height(c); + if (ysmax>ysize) ysize=ysmax;else + ysmax=ysize; + + highlight(&ctl,backgr); + ctl.bsize=2; + ctl.ctldef=0; + curcolor=backgr; + memcpy(&charcolors,&color,sizeof(charcolors)); + y=SCR_WIDTH_Y-ysize-3; + desktop_y_size=y-3; + bar(0,y,SCR_WIDTH_X-1,SCR_WIDTH_Y-1); + draw_border(2,y,SCR_WIDTH_X-5,ysize,&ctl); + while (text_width(c)>SCR_WIDTH_X) + { + char *p; + + p=strchr(c,'\0'); + *(--p)='\0'; + if (p=c) break; + } + position(5,y);outtext(c); + ukaz_mysku(); + showview(0,y-2,SCR_WIDTH_X-1,ysize+5); + } + +void *status_mem_info(EVENT_MSG *msg) + { + char *c; + long l; + static char memtext[]=MEMTEXT; + MEMORYSTATUS mem; + + if (msg->msg==E_INIT) return &status_mem_info; + c=(char *)msg->data; + strcpy(c,memtext); + c+=strlen(memtext); + get_mem_info(&mem); + l=mem.dwAvailPageFile; + sprintf(c,"%d KB ",l/1024); + c=strchr(c,'\0'); + msg->data=(void *)c; + return NULL; + } + +void *status_idle(EVENT_MSG *msg) + { + if (msg->msg==E_INIT) return &status_idle; + send_message(E_STATUS_LINE,msg->msg); + return NULL; + } + +void status_line(EVENT_MSG *msg,T_EVENT_ROOT **user_data) + { + T_EVENT_ROOT **p; + static char st_line[256],oldline[256]={"\0"}; + EVENT_MSG tg; + static char recurse=1; + + if(msg->msg==E_INIT) + if (recurse) + { + T_EVENT_ROOT *p; + recurse=0; + send_message(E_ADD,E_IDLE,status_idle); + send_message(E_ADD,E_REDRAW,status_idle); + p=NULL; + *user_data=p; + draw_status_line(NULL); + recurse=1; + return; + } + else return; + shift_msg(msg,tg); + if (tg.msg==E_REDRAW) + { + draw_status_line(oldline); + return; + } + p=user_data; + if (tg.msg==E_IDLE) + { + EVENT_MSG msg; + + msg.msg=E_IDLE; + msg.data=&st_line; + enter_event(p,&msg); + if (strcmp(st_line,oldline)) + { + draw_status_line(st_line); + strcpy(oldline,st_line); + } + } + else + tree_basics(p,&tg); + return; + } + +void *mouse_xy(EVENT_MSG *msg) + { + char *c; + + if (msg->msg==E_INIT) return &mouse_xy; + c=(char *)msg->data; + sprintf(c," X: %d Y: %d",ms_last_event.x,ms_last_event.y); + c=strchr(c,'\0'); + msg->data=(void *)c; + return NULL; + } + +void *show_time(EVENT_MSG *msg) + { + char *c; + time_t t; + struct tm cas; + + if (msg->msg==E_INIT) return &show_time; + c=(char *)msg->data; + t=time(NULL); + cas=*localtime(&t); + + sprintf(c,"%02d:%02d:%02d ",cas.tm_hour,cas.tm_min,cas.tm_sec); + c=strchr(c,'\0'); + msg->data=(void *)c; + return NULL; + } +//------------------------------------------ + +void win_label_draw(int x1,int y1,int x2,int y2,OBJREC *o) + { + bar(x1,y1,x2,y2); + set_aligned_position(x1+5,(y1+y2)/2,0,1,(char *)o->userptr); + outtext((char *)o->userptr); + } + +void xor_rectangle(int x,int y,int xs,int ys) + { + curcolor=RGB555(31,31,31); + if (x<0) x=0; + if (y<0) y=0; + if (x+xs>=SCR_WIDTH_X) xs=SCR_WIDTH_X-x-1; + if (y+ys>=SCR_WIDTH_Y) ys=SCR_WIDTH_Y-y-1; + schovej_mysku(); + hor_line_xor(x,y,x+xs); + ver_line_xor(x,y,y+ys); + if (xs && ys) + { + hor_line_xor(x,y+ys,x+xs); + ver_line_xor(x+xs,y,y+ys); + } + ukaz_mysku(); + showview(x,y,x+xs,4); + showview(x,y,4,ys+4); + if (xs && ys) + { + showview(x,y+ys,x+xs,4); + showview(x+xs,y,4,ys+4); + } + } + +void win_label_move(EVENT_MSG *msg,OBJREC *o) + { + MS_EVENT *ms; + static char run=0; + static word xref,yref; + static WINDOW w; + static moved=0; + static drawed=0; + + o; + if (msg->msg==E_INIT) return; + if (msg->msg==E_TIMER) + { + send_message(E_TIMER); + if (!drawed) + if (!moved) + { + drawed=1; + redraw_desktop(); + moved=0; + } + else + { + drawed=0; + moved=0; + } + } + if (msg->msg==E_MOUSE) + { + ms=get_mouse(msg); + if (run) + { + //xor_rectangle(w.x,w.y,w.xs,w.ys); + if (ms->event_type & 4) + { + run=0; + redraw_desktop(); + send_message(E_DONE,E_MOUSE,win_label_move); + msg->msg=-1; + return; + } + w.x=ms->x-xref; + w.y=ms->y-yref; + check_window(&w); + //xor_rectangle(w.x,w.y,w.xs,w.ys); + waktual->x=w.x; + waktual->y=w.y; + waktual->xs=w.xs; + waktual->ys=w.ys; + moved=1;drawed=0; + redraw_window(); + redraw_desktop(); + } + else + if (ms->event_type & 2) + { + run=1; + memcpy(&w,waktual,sizeof(WINDOW)); + //xor_rectangle(w.x,w.y,w.xs,w.ys); + xref=ms->x-waktual->x; + yref=ms->y-waktual->y; + send_message(E_ADD,E_MOUSE,win_label_move); + freeze_on_exit=1; + } + } + if (msg->msg==E_LOST_FOCUS && run) + { + run=0; + redraw_desktop(); + send_message(E_DONE,E_MOUSE,win_label_move); + msg->msg=-1; + return; + } +msg->msg=-1; +return; + } + + +void win_label(OBJREC *o) + { + o->runs[0]=sample_init; + o->runs[1]=win_label_draw; + o->runs[2]=win_label_move; + //o->runs[3]=button_done; + o->datasize=0; + } + +//------------------------------------------ + +void check_box_draw(int x1,int y1, int x2, int y2,OBJREC *o) + { + int x3; + + x1+=1;y1+=1;x2-=1;y2-=1; + x3=x1+(y2-y1); + draw_border(x1,y1,x3-x1,y2-y1,def_border(4,curcolor)); + bar(x1,y1,x3,y2); + if (*(char *)o->data & 1) + { + curcolor=0x0000; + line(x1,y1,x3,y2);line(x1+1,y1,x3,y2-1);line(x1,y1+1,x3-1,y2); + line(x1,y2,x3,y1);line(x1+1,y2,x3,y1+1);line(x1,y2-1,x3-1,y1); + } + if (*(char *)o->data & 0x80) + { + curcolor=0x0000; + hor_line(x1,y1,x3);ver_line(x3,y1,y2); + ver_line(x1,y1,y2);hor_line(x1,y2,x3); + } + else + { + set_aligned_position(x3+5,(y2+y1)/2,0,1,(char *)o->userptr); + outtext((char *)o->userptr); + } + } + +void check_box_event(EVENT_MSG *msg,OBJREC *o) + { + MS_EVENT *ms; + + if (msg->msg==E_MOUSE) + { + ms=get_mouse(msg); + if (ms->event_type & 0x06) + { + if (ms->tl1) + { + *(char *)o->data|=0x80; + redraw_object(o); + } + else if (*(char *)o->data) + { + *(char *)o->data^=0x1; + *(char *)o->data&=0x1; + redraw_object(o); + set_change(); + } + } + } + + if (msg->msg==E_GET_FOCUS || msg->msg==E_LOST_FOCUS) + { + *(char *)o->data&=0x1; + redraw_object(o); + } + } + + +void check_box(OBJREC *o) + { + o->runs[0]=sample_init; + o->runs[1]=check_box_draw; + o->runs[2]=check_box_event; + o->datasize=4; + } + +//------------------------------------------ +void radio_butts_init(OBJREC *o,long *params) + { + char *c,*z; + long cnt=0,*q,*d; + int i; + + d=params; + for (i=0;i<*params;i++) + { + d+=1; + c=get_title(d); + cnt+=strlen(c);cnt++; + } + q=(long *)getmem(cnt+8); + o->userptr=(void *)q; + *q++=1;*q++=*params; + d=params; + z=(char *)q; + for (i=0;i<*params;i++) + { + d+=1; + c=get_title(d); + strcpy(z,c); + z=strchr(z,'\0');z++; + } + } + +void radio_butts_draw(int x1,int y1,int x2,int y2,OBJREC *o) + { + int step,size,sizpul,i,cr; + long *params; + char *texts; + CTL3D ctl; + + cr=curcolor; + highlight(&ctl,curcolor); + params=(long *)o->userptr; + if (*params) bar(x1,y1,x2,y2); + step=(y2-y1)/(*(params+1)); + size=(step*9)/10; + sizpul=size>>1; + + texts=(char *)(params+2); + for (i=0;i<*(params+1);i++,y1+=step) + { + int j; + curcolor=ctl.shadow; + line(x1+sizpul,y1,x1,y1+sizpul); + line(x1,y1+sizpul,x1+sizpul,y1+size-1); + curcolor=ctl.light; + line(x1+sizpul+1,y1,x1+size,y1+sizpul); + line(x1+size,y1+sizpul,x1+sizpul+1,y1+size-1); + if (*(long *)o->data==i) curcolor=0;else curcolor=cr; + for (j=0;j<3;j++) + { + hor_line(x1+sizpul-j,y1+sizpul-2+j,x1+sizpul+j); + hor_line(x1+sizpul-j,y1+sizpul+2-j,x1+sizpul+j); + } + if (*params) + { + set_aligned_position(x1+size+5,y1+sizpul,0,1,texts); + outtext(texts); + texts=strchr(texts,'\0')+1; + } + + } + } + +void radio_butts_event(EVENT_MSG *msg,OBJREC *o) + { + MS_EVENT *ms; + int sel; + + if (msg->msg==E_MOUSE) + { + ms=get_mouse(msg); + if (ms->event_type & 0x02) + { + sel=(ms->y-o->locy)/(o->ys/(*((long *)o->userptr+1))); + if (sel>=*((long *)o->userptr+1)) sel=*((long *)o->userptr+1)-1; + *(long *)o->data=sel; + *(long *)o->userptr=0; + redraw_object(o); + *(long *)o->userptr=1; + set_change(); + } + } + + } + + +void radio_butts(OBJREC *o) + { + o->runs[0]=radio_butts_init; + o->runs[1]=radio_butts_draw; + o->runs[2]=radio_butts_event;; + o->datasize=4; + } + +//------------------------------------------ + + + +void toggle_button_event(EVENT_MSG *msg,OBJREC *o) + { + MS_EVENT *ms; + static char toggle_exit=0; + + if (msg->msg==E_MOUSE) + { + ms=get_mouse(msg); + if (ms->event_type & 0x06) + { + if (ms->tl1) + { + *(char *)o->data^=1; + redraw_object(o); + toggle_exit=1; + } + else if (toggle_exit) + { + set_change(); + toggle_exit=0; + } + } + } + + if ((msg->msg==E_GET_FOCUS || msg->msg==E_LOST_FOCUS)&&toggle_exit) + { + *(char *)o->data^=1; + redraw_object(o); + toggle_exit=0; + } + } + + + +void toggle_button(OBJREC *o) + { + o->runs[0]=button_init; + o->runs[1]=button_draw; + o->runs[2]=toggle_button_event; + o->datasize=1; + } + +//------------------------------------------ + +void input_line_init(OBJREC *o,int *len) + { + o->datasize=(*len)+1; + o->userptr=malloc(20); + memset(o->userptr,0,20); + memcpy(o->userptr,len,4); + memcpy((int *)o->userptr+2,len+1,12); + } + +void input_line_draw(int x1,int y1, int x2, int y2, OBJREC *o) + { + char d[2]=" \0"; + int x; + char *c; + int len; + int shift; + + bar(x1,y1,x2,y2); + position(x1,y1); + c=(char *)o->data; + if (!*c) return; + len=strlen(c); + shift=*((int *)o->userptr+1); + if (shift>=len) shift=0; + c+=shift; + d[0]=*c++;x=x1+text_width(d); + while (xuserptr; + start=len+1; + c=(char *)o->data; + slen=strlen(c); + switch (msg->msg) + { + case E_GET_FOCUS:cursor=0;save=(char *)getmem(*len+1); + strcpy(save,c);clear_kontext=1;break; + case E_LOST_FOCUS:cursor=0;*start=0;free(save);redraw_object(o);break; + case E_CURSOR_TICK: + { + int xpos,i,j=-1,d; + + do + { + xpos=0;j++; + for (i=*start;i=o->xs) (*start)+=1; + if (xpos==0) (*start)-=1; + if (*start<0) *start=0; + } + while ((xpos==0 || xpos>=o->xs)&& cursor); + if (j) redraw_object(o); + xor_rectangle(o->locx+xpos,o->locy,1,o->ys); + };break; + case E_MOUSE: + { + MS_EVENT *ms;int msx; + + ms=get_mouse(msg); + msx=ms->x-o->locx; + if (ms->event_type & 2) + { + int xpos; + + xpos=0; + for (cursor=*start;cursormsx) break; + } + redraw_object(o); + } + } + break; + case E_KEYBOARD: + { + char key; + + cancel_event(); + key=(*(int *)msg->data) & 0xff; + if (!key) + switch (*(int *)msg->data >> 8) + { + case 'M':if (cursor0) cursor--;break; + case 'S':if (cursor0) {strcpy(&c[cursor-1],&c[cursor]);cursor--;}break; + case 0:break; + case 13:break; + case 27:strcpy(c,save);slen=strlen(c);if (cursor>slen) cursor=slen;break; + default:if (key>=' ') if (slen<*len || clear_kontext) + { + int i; + + if (clear_kontext) + {*c='\0';cursor=0;slen=0;} + for (i=slen+1;i>cursor;i--) c[i]=c[i-1]; + c[cursor++]=key; + } + } + if (!cursor) *start=0; + redraw_object(o); + msg->msg=E_CURSOR_TICK; + input_line_event(msg,o); + clear_kontext=0; + msg->msg=-1; + } + } + } + + + + + +void input_line(OBJREC *o) + { + o->runs[0]=input_line_init; + o->runs[1]=input_line_draw; + o->runs[2]=input_line_event; + } + + +//------------------------------------------------------------- +void label(OBJREC *o) + { + o->runs[0]=sample_init; + o->runs[1]=sample_draw; + } + +void mid_label(OBJREC *o) + { + o->runs[0]=sample_init; + o->runs[1]=mid_label_draw; + } +//------------------------------------------------------------- + +typedef struct scr_button + { + int step; + int maxvalue; + char *title; + }SCR_BUTTON; + +void scroll_button_init(OBJREC *o,int *param) + { // int step, int maxvalue,char *title + char *v; + SCR_BUTTON *p; + + o->userptr=getmem(sizeof(SCR_BUTTON)); + p=(SCR_BUTTON *)o->userptr; + p->step=*param++; + p->maxvalue=*param++; + p->title=(char *)*param++; + v=(char *)o->data; + *v=0; + } + + + +void scroll_button_draw(int x1,int y1,int x2,int y2,OBJREC *o) + { + CTL3D x; + char w; + SCR_BUTTON *param; + + param=(SCR_BUTTON *)o->userptr; + bar(x1,y1,x2,y2); + highlight(&x,o->color); + w=*(char *)o->data; + x.bsize=2-w; + x.ctldef=(w<<1)+w; + draw_border(x1+2,y1+2,x2-x1-4,y2-y1-4,&x); + set_aligned_position(((x1+x2)>>1)+(w<<1),((y1+y2)>>1)+(w<<1),1,1,param->title); + outtext(param->title); + } + +void scroll_button_event(EVENT_MSG *msg,OBJREC *o) + { + MS_EVENT *ms; + + if (msg->msg==E_MOUSE) + { + ms=get_mouse(msg); + if (ms->event_type & 0x0e) + { + if (ms->tl1 || ms->event_type & 0x8) + { + *(char *)o->data=1; + redraw_object(o); + set_change(); + } + } + } + if (msg->msg==E_TIMER && *(char *)o->data ) + if (ms_last_event.tl1) set_change(); + else if (!ms_last_event.tl2) + { + *(char *)o->data=0; + redraw_object(o); + } + + if (msg->msg==E_GET_FOCUS || msg->msg==E_LOST_FOCUS) + { + *(char *)o->data=0; + redraw_object(o); + } + } + +void scroll_button(OBJREC *o) + { + o->runs[0]=scroll_button_init; + o->runs[1]=scroll_button_draw; + o->runs[2]=scroll_button_event; + o->datasize=1; + } + + +//------------------------------------------------------------- +typedef struct scr_bar + { + int minvalue; + int maxvalue; + int parview; + int bgcolor; + int barsize; + int stepsize; + }SCR_BAR; + +void scroll_bar_init(OBJREC *o,int *param) + { + SCR_BAR *p; + + o->userptr=getmem(sizeof(SCR_BAR)); + p=(SCR_BAR *)o->userptr; + p->minvalue=*param++; + p->maxvalue=*param++; + p->parview=*param++; + p->bgcolor=*param++; + p->barsize=10; + p->stepsize=10; + } + +void scroll_bar_v_draw(int x1,int y1,int x2,int y2,OBJREC *o) + { + int barsize; + int wsize; + int valsize; + SCR_BAR *p; + int *d; + CTL3D ctl; + int y; + + + p=(SCR_BAR *)o->userptr; + d=(int *)o->data; + valsize=p->maxvalue-p->minvalue+p->parview; + wsize=y2-y1; + barsize=valsize?wsize*p->parview/valsize:10; if (barsize<2) barsize=2; + if (barsize>wsize) barsize=wsize; + wsize-=barsize; + curcolor=p->bgcolor; + bar(x1,y1,x2,y2); + curcolor=o->color; + highlight(&ctl,o->color);ctl.bsize=2;ctl.ctldef=0; + y=valsize?(*d-p->minvalue)*(wsize+barsize)/valsize:0; + p->stepsize=valsize?wsize/valsize:0; + if (y>wsize) y=wsize; + if (y<0) y=0; + y+=y1; + draw_border(x1+2,y+2,(x2-x1)-4,barsize-4,&ctl); + if (barsize>4)bar(x1+2,y+2,x2-2,y+barsize-2); + p->barsize=barsize; + } + +void scroll_bar_v_event(EVENT_MSG *msg,OBJREC *o) + { + SCR_BAR *p; + int *d; + int _d; + + p=(SCR_BAR *)o->userptr; + d=(int *)o->data; + switch (msg->msg) + { + case E_MOUSE: + { + int y; + MS_EVENT *ms; + + ms=get_mouse(msg); + y=(ms->y+(p->stepsize>>1)-o->locy-(p->barsize>>1)); + if (ms->tl1) + { + if (o->ys<=p->barsize) _d=p->minvalue; else + _d=y*(p->maxvalue-p->minvalue)/(o->ys-p->barsize)+p->minvalue; + if (_d>p->maxvalue) _d=p->maxvalue; + if (_dminvalue) _d=p->minvalue; + if (_d!=*d) + { + *d=_d; + redraw_object(o); + set_change(); + } + } + } + break; + case E_CONTROL: + { + int *q; + + q=msg->data; + p->minvalue=*q++; + p->maxvalue=*q++; + p->parview=*q++; + } + break; + + } + } + +void scroll_bar_v(OBJREC *o) + { + o->runs[0]=scroll_bar_init; + o->runs[1]=scroll_bar_v_draw; + o->runs[2]=scroll_bar_v_event; + o->datasize=4; + } + +//------------------------------------------------------------- +void scroll_support() + { + int id,x; + SCR_BAR *p; + SCR_BUTTON *q; + OBJREC *o,*r; + + + id=o_aktual->id; + id=(id/10)*10; + o=find_object(waktual,id); + p=(SCR_BAR *)o->userptr; + q=(SCR_BUTTON*)o_aktual->userptr; + x=f_get_value(0,id); + x+=q->step; + if (q->step<0) + if (xminvalue) x=p->minvalue; + if (q->step>0) + if (x>p->maxvalue) x=p->maxvalue; + set_value(0,id,&x); + r=o_aktual; + o_aktual=o; + o->events[3](); + o_aktual=r; + } +//------------------------------------------------------------- + +void scroll_bar_h_draw(int x1,int y1,int x2,int y2,OBJREC *o) + { + int barsize; + int wsize; + int valsize; + SCR_BAR *p; + int *d; + CTL3D ctl; + int x; + + + p=(SCR_BAR *)o->userptr; + d=(int *)o->data; + valsize=p->maxvalue-p->minvalue; + wsize=x2-x1; + barsize=wsize*p->parview/valsize; + if (barsize>wsize) barsize=wsize;if (barsize<2) barsize=2; + wsize-=barsize; + curcolor=p->bgcolor; + bar(x1,y1,x2,y2); + curcolor=o->color; + highlight(&ctl,o->color);ctl.bsize=2;ctl.ctldef=0; + x=(*d-p->minvalue)*wsize/valsize; + p->stepsize=wsize/valsize; + if (x>wsize) x=wsize; + if (x<0) x=0; + x+=x1; + draw_border(x+2,y1+2,barsize-4,(y2-y1)-4,&ctl); + if (barsize>4)bar(x+2,y1+2,x+barsize-2,y2-2); + p->barsize=barsize; + } + +void scroll_bar_h_event(EVENT_MSG *msg,OBJREC *o) + { + SCR_BAR *p; + int *d; + int _d; + + p=(SCR_BAR *)o->userptr; + d=(int *)o->data; + switch (msg->msg) + { + case E_MOUSE: + { + int x; + MS_EVENT *ms; + + ms=get_mouse(msg); + x=(ms->x+(p->stepsize>>1)-o->locx-(p->barsize>>1)); + if (ms->tl1) + { + if (o->xs<=p->barsize) _d=p->minvalue; else + _d=x*(p->maxvalue-p->minvalue)/(o->xs-p->barsize)+p->minvalue; + if (_d>p->maxvalue) _d=p->maxvalue; + if (_dminvalue) _d=p->minvalue; + if (_d!=*d) + { + *d=_d; + redraw_object(o); + set_change(); + } + } + } + } + } + + + + + + void scroll_bar_h(OBJREC *o) + { + o->runs[0]=scroll_bar_init; + o->runs[1]=scroll_bar_h_draw; + o->runs[2]=scroll_bar_h_event; + o->datasize=4; + + } + + +//------------------------------------------------------------- + + + +#define MSG_SIZE (SCR_WIDTH_X*3/4) +#define MSG_L_MARGIN 10 +#define MSG_R_MARGIN 50 +#define MSG_A_MARGIN (MSG_L_MARGIN+MSG_R_MARGIN) +#define MSG_COLOR RGB555(15,0,0) +#define MSG_F_COLOR RGB555(31,31,0) + +word *msg_box_font; +word *msg_icn_font; + + +int msg_box(char *title, char icone, char *text, ... ) + { + int winx,winy,xp,yp,txt_h; + int txt_max,temp1,temp2,i; + char buf[256]; + char *p; + CTL3D *ctl; + char **c; + FC_TABLE cl; + + curfont=msg_box_font; + ctl=def_border(2,MSG_COLOR); + winx=text_width(text)+MSG_A_MARGIN; + winy=30; + desktop_add_window(create_window(0,0,winx,300,MSG_COLOR,ctl)); + buf[1]='\0';buf[0]=icone; + xp=text_width(buf); + define(-1,(MSG_R_MARGIN>>1)-(xp>>1),20,xp,text_height(buf),1,label,buf); + cl[1]=ctl->light; + cl[0]=ctl->shadow; + property(NULL,msg_icn_font,&cl,MSG_COLOR); + curfont=msg_box_font; + default_font=curfont; + if (winx>MSG_SIZE) winx=MSG_SIZE; + c=&text;c++; + temp1=0;temp2=0; + while (*c) + {temp1+=text_width(*c++)+10;temp2++;} + if (temp1>winx-2*MSG_L_MARGIN) winx=temp1+2*MSG_L_MARGIN; + txt_max=winx-MSG_A_MARGIN; + txt_h=0; + while (*text) + { + memset(buf,0,sizeof(buf)); + p=buf; + while (text_width(buf)txt_max) while (*(--p)!=' ') text--; + if (*text=='\n') text++; + *p='\0'; + txt_h=text_height(buf); + define(-1,MSG_L_MARGIN,winy,txt_max,txt_h,0,label,&buf); + property(NULL,NULL,flat_color(MSG_F_COLOR),MSG_COLOR); + o_end->f_color[0]=0; + winy+=txt_h; + } + winy+=40; + xp=(SCR_WIDTH_X>>1)-(winx>>1); + yp=(SCR_WIDTH_Y>>1)-(winy>>1); + waktual->x=xp;waktual->y=yp;waktual->xs=winx;waktual->ys=winy; + define(0,1,1,winx-2,text_height(title)+2,0,win_label,title); + ctl=def_border(5,MSG_COLOR); + property(ctl,NULL,flat_color(MSG_F_COLOR),0x10); + ctl=def_border(1,0); + c=&text;c++; + for (i=1;i<=temp2;i++) + { + int sz; + + sz=(winx/(temp2+1))>>1; + if (sz>1),10,sz+5,20,3,button,*c); + property(ctl,NULL,flat_color(0),RGB555(24,24,24));on_change(terminate); + c++; + } + set_window_modal(); + redraw_window(); + escape(); + temp2=o_aktual->id; + close_window(waktual); + return temp2; + } + + +//------------------------------------------------------------- + + +void resizer_draw(int x1,int y1,int x2,int y2,OBJREC *o) + { + CTL3D ctl; + + highlight(&ctl,o->color); + curcolor=o->color; + bar(x1,y1,x2,y2); + curcolor=ctl.light; + line(x2-1,y1+1,x1+1,y2-1); + line(x2-1,(y1+y2)>>1,(x1+x2)>>1,y2-1); + curcolor=ctl.shadow; + line(x2-1,y1+4,x1+4,y2-1); + line(x2-1,y1+2,x2-1,y1+4); + line(x1+2,y2-1,x1+4,y2-1); + line(x2-1,((y1+y2)>>1)+4,((x1+x2)>>1)+4,y2-1); + line(x2-1,((y1+y2)>>1)+2,x2-1,((y1+y2)>>1)+4); + line(((x1+x2)>>1)+2,y2-1,((x1+x2)>>1)+4,y2-1); + } + +void resizer_event(EVENT_MSG *msg,OBJREC *o) + { + MS_EVENT *ms; + static char run=0; + static word xref,yref; + static WINDOW w; + static moved=0; + static drawed=0; + + o; + if (msg->msg==E_INIT) return; + if (msg->msg==E_TIMER && !drawed) + if (!moved) + { + drawed=1; + redraw_desktop(); + moved=0; + } + else + { + drawed=0; + moved=0; + } + if (msg->msg==E_MOUSE) + { + ms=get_mouse(msg); + if (run) + { + char force_redraw=0; + int new; + //xor_rectangle(w.x,w.y,w.xs,w.ys); + if (ms->event_type & 4) + { + run=0; + redraw_desktop(); + send_message(E_DONE,E_MOUSE,resizer_event); + msg->msg=-1; + return; + } + new=ms->x-waktual->x+xref;if (newy-waktual->y+yref;if (newevent_type & 2) + { + run=1; + memcpy(&w,waktual,sizeof(WINDOW)); + //xor_rectangle(w.x,w.y,w.xs,w.ys); + xref=waktual->xs-(ms->x-waktual->x); + yref=waktual->ys-(ms->y-waktual->y); + send_message(E_ADD,E_MOUSE,resizer_event); + freeze_on_exit=1; + } + } + if (msg->msg==E_LOST_FOCUS && run) + { + run=0; + redraw_desktop(); + send_message(E_DONE,E_MOUSE,resizer_event); + msg->msg=-1; + return; + } +if (msg->msg!=E_TIMER) msg->msg=-1; + return; + } + + + +void resizer(OBJREC *o) + { + //o->runs[0]=resizer_init; + o->runs[1]=resizer_draw; + o->runs[2]=resizer_event; + } diff --git a/LIBS/BASICOBJ.H b/LIBS/BASICOBJ.H new file mode 100644 index 0000000..fde90ee --- /dev/null +++ b/LIBS/BASICOBJ.H @@ -0,0 +1,38 @@ +#define MEMTEXT "Pamt: " + +#define E_STATUS_LINE 60 + +extern word *msg_box_font; +extern word *msg_icn_font; + +int msg_box(char *title, char icone, char *text, ... ); + + +void highlight(CTL3D *c,word color); +CTL3D *def_border(int btype,int color); +void xor_rectangle(int x,int y,int xs,int ys); + +// status lines +void status_line(EVENT_MSG *msg,T_EVENT_ROOT **user_data); +void *status_mem_info(EVENT_MSG *msg); +void *mouse_xy(EVENT_MSG *msg); +void *show_time(EVENT_MSG *msg); + +// objects +//void sample(OBJREC *o); +void button(OBJREC *o); +void win_label(OBJREC *o); +void check_box(OBJREC *o); +void radio_butts(OBJREC *o); +void toggle_button(OBJREC *o); +void input_line(OBJREC *o); +void label(OBJREC *o); +void mid_label(OBJREC *o); +void scroll_bar_v(OBJREC *o); +void scroll_button(OBJREC *o); +void scroll_support(); +void scroll_bar_h(OBJREC *o); +void button2(OBJREC *o); +void resizer(OBJREC *o); + + diff --git a/LIBS/BGRAPH.C b/LIBS/BGRAPH.C new file mode 100644 index 0000000..c4a74b2 --- /dev/null +++ b/LIBS/BGRAPH.C @@ -0,0 +1,261 @@ +#include "types.h" +//#include +#include +#include +#include +#include +#include +#include +#include "bgraph.h" + +word *lbuffer; +word *screen; +word curcolor,charcolors[7] = {0x0000,0x03E0,0x0380,0x0300,0x0280,0x0000,0x0000}; +longint linelen; +word *curfont,*writepos,writeposx; +byte fontdsize=0; +byte *palmem,*xlatmem; +void (*showview)(word,word,word,word); +char line480=0; +long screen_buffer_size=512000; + +void *mscursor,*mssavebuffer=NULL; +integer mscuroldx=0,mscuroldy=0; +integer msshowx=0,msshowy=0; +long pictlen; // Tato promenna je pouze pouzita v BGRAPH1.ASM + +void line32(word x1,word y1, word x2, word y2) + { + line_32(x1,y1,(x2-x1),(y2-y1)); + } + +void position(word x,word y) + { + writeposx=x; + writepos=getadr32(x,y); + } + +void outtext(char *text) + { + byte pos; + + if (fontdsize) + while (*text) + { + char2_32(writepos,curfont,*text); + pos=(charsize(curfont,*text) & 0xff)<<1; + writepos+=pos; + writeposx+=pos;text++; + } + else + while (*text) + { + char_32(writepos,curfont,*text); + pos=charsize(curfont,*text) & 0xff; + writepos+=pos; + writeposx+=pos;text++; + } + } + + + + +int initmode32() + { + MODEinfo data; + + getmodeinfo(&data,0x11e-line480*0xe); + if (!(data.modeattr & MA_SUPP)) return -1; + if (!(data.modeattr & MA_LINEARFBUF)) return -2; + setvesamode(0x411e-line480*0xe,-1); + lbuffer=(word *)physicalalloc((long)data.linearbuffer,screen_buffer_size); + screen=lbuffer; + linelen=640*2; + showview=showview32; + screen=(void *)malloc(screen_buffer_size); + return 0; + } +int initmode256(void *paletefile) + { + MODEinfo data; + + getmodeinfo(&data,0x100+line480); + if (!(data.modeattr & MA_SUPP)) return -1; + if (!(data.modeattr & MA_LINEARFBUF)) return -2; + setvesamode(0x4100+line480,-1); + lbuffer=(word *)physicalalloc((long)data.linearbuffer,screen_buffer_size>>1); + screen=lbuffer; + linelen=640*2; + palmem=(char *)paletefile; + xlatmem=palmem+768; + setpal((void *)palmem); + showview=showview256; + screen=(void *)malloc(screen_buffer_size); + return 0; + } + + +int initmode_lo(void *paletefile) + { + _setvideomode(_MRES256COLOR); + palmem=(char *)paletefile; + xlatmem=palmem+768; + setpal((void *)palmem); + linelen=640*2; + lbuffer=(void *)0xa0000; + showview=showview_lo; + screen=(void *)malloc(512000); + return 0; + } + +void closemode() + { + free(screen); + _setvideomode(0x3); + } + +void showview32(word x,word y,word xs,word ys) + { + register longint a; + + if (x>640 || y>400) return; + if (xs==0) xs=640; + if (ys==0) ys=400; + if (x+xs>640) xs=640-x; + if (y+ys>400) ys=400-y; + if (xs>500 && ys>320) + { + redraw32(screen,lbuffer,NULL); + return; + } + a=(x<<1)+linelen*y; + redrawbox32(xs,ys,(void *)((char *)screen+a),(void *)((char *)lbuffer+a)); + } + +void showview256(word x,word y,word xs,word ys) + { + register longint a; + + if (xs==0) xs=640; + if (ys==0) ys=400; + x&=0xfffe;y&=0xfffe;xs+=2;ys+=2; + if (x>640 || y>400) return; + if (x+xs>640) xs=640-x; + if (y+ys>400) ys=400-y; + if (xs>500 && ys>320) + { + redraw256(screen,lbuffer,xlatmem); + return; + } + a=(x<<1)+linelen*y; + redrawbox256(xs,ys,(void *)((char *)screen+a),(void *)((char *)lbuffer+(a>>1)),xlatmem); + } + +void showview_lo(word x,word y,word xs,word ys) + { + register longint a,b; + + if (xs==0) xs=640; + if (ys==0) ys=400; + x&=0xfffe;y&=0xfffe;xs+=2;ys+=2; + if (ys==0) ys=400; + if (x+xs>640) xs=640-x; + if (y+ys>400) ys=400-y; + if (xs>500 && ys>320) + { + redraw_lo(screen,lbuffer,xlatmem); + return; + } + a=(x<<1)+linelen*y; + b=(x>>1)+320*(y>>1); + redrawbox_lo(xs,ys,(void *)((char *)screen+a),(void *)((char *)lbuffer+b),xlatmem); + } + + + + +void show_ms_cursor(char copy,integer x, integer y) + { + integer xs,ys; + + xs=*(integer *)mscursor; + ys=*((integer *)mscursor+1); + get_picture(x,y,xs,ys,mssavebuffer); + put_picture(x,y,mscursor); + if (copy) + { + mscuroldx=x; + mscuroldy=y; + } + } + +void hide_ms_cursor() + { + put_picture(mscuroldx,mscuroldy,mssavebuffer); + } + +void *register_ms_cursor(void *cursor) + { + integer xs,ys; + + mscursor=cursor; + xs=*(integer *)mscursor; + ys=*((integer *)mscursor+1); + if (mssavebuffer!=NULL) free(mssavebuffer); + mssavebuffer=malloc(xs*ys*2+10);//5 bajtu pro strejcka prihodu + return mssavebuffer; + } + +void move_ms_cursor(integer newx,integer newy) + { + integer xs,ys; + + if (newx<0) newx=0; + if (newy<0) newy=0; + if (newx>639) newx=639; + if (newy>399) newy=399; + xs=*(integer *)mscursor; + ys=*((integer *)mscursor+1); + put_picture(mscuroldx,mscuroldy,mssavebuffer); + show_ms_cursor(0,newx,newy); + showview(msshowx,msshowy,xs,ys); + mscuroldx=newx;mscuroldy=newy; + msshowx=newx;msshowy=newy; + showview(msshowx,msshowy,xs,ys); + } + +int text_height(char *text) + { + char max=0,cur; + + while (*text) + if ((cur=charsize(curfont,*text++)>>8)>max) max=cur; + return max<>1;break; + case 2:x-=text_width(text);break; + } + switch (aligny) + { + case 1:y-=text_height(text)>>1;break; + case 2:y-=text_height(text);break; + } + position(x,y); + } + + diff --git a/LIBS/BGRAPH.H b/LIBS/BGRAPH.H new file mode 100644 index 0000000..d1e8021 --- /dev/null +++ b/LIBS/BGRAPH.H @@ -0,0 +1,155 @@ +#include "types.h" +#define line line32 +#define hor_line hor_line32 +#define ver_line ver_line32 +#define bar bar32 +#define point point32 + +word *GetScreenAdr(); +word *GetBuffer2nd(); +void RedirectScreen(word *newaddr); +void RestoreScreen(); +void RedirectScreenBufferSecond(); + + +extern word curcolor,charcolors[7]; +extern long scr_linelen; +extern long scr_linelen2; +extern long dx_linelen; +extern word *curfont,*writepos,writeposx; +extern byte fontdsize; +extern byte *palmem,*xlatmem; +extern void (*showview)(word,word,word,word); +extern char line480; +extern long screen_buffer_size; +extern char banking; +extern char __skip_change_line_test; +extern char no_restore_mode; + +static __inline word *getadr32(longint x,longint y) + { + return GetScreenAdr()+scr_linelen2*y+x; + } + +static __inline void point32(longint x,longint y, word color) + { + *getadr32(x,y)=color; + } +void bar32(int x1,int y1, int x2, int y2); +//#pragma aux bar32 parm [eAX] [eBX] [eCX] [eDX] modify [ESI EDI]; +void hor_line32(int x1,int y1,int x2); +//#pragma aux hor_line32 parm [eSi] [eAX] [eCX] modify [eDI eDX]; +void ver_line32(int x1,int y1,int y2); +//#pragma aux ver_line32 parm [eSi] [eAX] [eCX] modify [eDX]; +void hor_line_xor(int x1,int y1,int x2); +//#pragma aux hor_line_xor parm [eSi] [eAX] [eCX] modify [eDI eDX]; +void ver_line_xor(int x1,int y1,int y2); +//#pragma aux ver_line_xor parm [eSi] [eAX] [eCX] modify [eDX]; +void line_32(int x,int y,int xs,int ys); +//#pragma aux line_32 parm [esi] [eax] [ecx] [ebx] modify [edx edi] +void char_32(word *posit,word *font,char znak); +//#pragma aux char_32 parm [edi] [esi] [eax] modify [eax ebx ecx edx] +void char2_32(word *posit,word *font,char znak); +//#pragma aux char2_32 parm [edi] [esi] [eax] modify [eax ebx ecx edx] +word charsize(word *font,char znak); +//#pragma aux charsize parm [esi] [eax] +void put_picture(word x,word y,void *p); +//#pragma aux put_picture parm [esi] [eax] [edi] modify [ebx ecx edx] +void get_picture(word x,word y,word xs,word ys,void *p); +//#pragma aux get_picture parm [esi] [eax] [ebx] [ecx] [edi] modify [edx] +void setpal(void *paleta); +//#pragma aux setpal parm [esi] modify [eax edx] +void redraw_lo(void *screen,void *lbuffer,byte *xlat); +//#pragma aux redraw_lo parm [esi][edi][ebx] modify[eax ecx edx] +void redraw256(void *screen,void *lbuffer,byte *xlat); +//#pragma aux redraw256 parm [esi][edi][ebx] modify [eax ecx edx] +void redraw256b(void *screen,void *lbuffer,byte *xlat); +//#pragma aux redraw256b parm [esi][edi][ebx] modify [eax ecx edx] +void redraw32(void *screen,void *lbuffer,byte *xlat); +//#pragma aux redraw32 parm [esi][edi][ebx] modify [ecx] +void redraw32b(void *screen,void *lbuffer,byte *xlat); +//#pragma aux redraw32b parm [esi][edi][ebx] modify [ecx eax] +void redraw64(void *screen,void *lbuffer,byte *xlat); +//#pragma aux redraw64 parm [esi][edi][ebx] modify [ecx eax] +void redraw64b(void *screen,void *lbuffer,byte *xlat); +//#pragma aux redraw64b parm [esi][edi][ebx] modify [ecx eax] +void redraw32bb(void *screen,void *lbuffer,byte *xlat); +//#pragma aux redraw32bb parm [esi][edi][ebx] modify [ecx eax] +void redrawbox_lo(word xs,word ys,void *screen,void *lbuffer,byte *xlat); +//#pragma aux redrawbox_lo parm [ecx][edx][esi][edi][ebx] modify [eax edx] +void redrawbox256(word xs,word ys,void *screen,void *lbuffer,byte *xlat); +//#pragma aux redrawbox256 parm [edx][ecx][esi][edi][ebx] modify [eax edx] +void redrawbox256b(word xs,word ys,void *screen,void *lbuffer,byte *xlat); +//#pragma aux redrawbox256b parm [edx][ecx][esi][edi][ebx] modify [eax edx] +void redrawbox32(word xs,word ys,void *screen,void *lbuffer); +//#pragma aux redrawbox32 parm [ebx][edx][esi][edi] modify [ecx eax] +void redrawbox32b(word xs,word ys,void *screen,void *lbuffer); +//#pragma aux redrawbox32b parm [ebx][edx][esi][edi] modify [ecx eax] +void redrawbox64(word xs,word ys,void *screen,void *lbuffer,byte *xlat); +//#pragma aux redrawbox64 parm [ecx][edx][esi][edi][ebx] modify [eax] +void redrawbox64b(word xs,word ys,void *screen,void *lbuffer,byte *xlat); +//#pragma aux redrawbox64b parm [ecx][edx][esi][edi][ebx]modify [eax] +void redrawbox32bb(word xs,word ys,void *screen,void *lbuffer); +//#pragma aux redrawbox32bb parm [ebx][edx][esi][edi] modify [ecx] +void redraw16(void *screen,void *lbuffer,byte *xlat); +void redrawbox16(word xs,word ys,void *screen,void *lbuffer,byte *xlat); +//#pragma aux redrawbox16 parm [edx][ecx][esi][edi][ebx] modify [eax edx] +//#pragma aux redraw16 parm [esi][edi][ebx] modify [ecx] +void showview32(word x,word y,word xs,word ys); +void showview256(word x,word y,word xs,word ys); +void showview_lo(word x,word y,word xs,word ys); +void outtext(char *text); +int initmode_dx(char inwindow, char zoom, char monitor, int refresh); +int initmode32(); +int initmode32b(); +int initmode256(void *paletefile); +int initmode256b(void *paletefile); +int initmode_lo(void *paletefile); +int initmode16(void *paletefile); +int initmode64(void *paletefile); +int initmode64b(void *paletefile); +void *create_hixlat(); +void closemode(); +void line32(word x1,word y1, word x2, word y2); +void position(word x,word y); +void outtext(char *text); +void show_ms_cursor(integer x,integer y); +void *register_ms_cursor(void *cursor); +void move_ms_cursor(integer newx,integer newy,char nodraw); +void hide_ms_cursor(); +int text_height(char *text); +int text_width(char *text); +void set_aligned_position(int x,int y,char alignx, char aligny,char *text); +void wait_retrace(); +void pal_optimize(); +void rectangle(int x1,int y1,int x2,int y2,int color); +word *mapvesaadr1(word *a); +void *create_special_palette(); +void *create_special_palette2(); +void *create_blw_palette16(); +void rel_position_x(word x); +int init_empty_mode(); + +void put_8bit_clipped(void *src,void *trg,int startline,int velx,int vely); +//#pragma aux put_8bit_clipped parm [ESI][EDI][EAX][EBX][EDX] modify [ECX]; +void put_textured_bar_(void *src,void *trg,int xsiz,int ysiz,int xofs,int yofs); +//#pragma aux put_textured_bar_ parm [EBX][EDI][EDX][ECX][ESI][EAX]; +void put_textured_bar(void *src,int x,int y,int xs,int ys,int xofs,int yofs); +void trans_bar(int x,int y,int xs,int ys,int barva); +//#pragma aux trans_bar parm [EDI][ESI][EDX][ECX][EBX] modify [EAX]; +void trans_bar25(int x,int y,int xs,int ys); +//#pragma aux trans_bar25 parm [EDI][ESI][EDX][ECX] modify [EAX EBX]; +void trans_line_x(int x,int y,int xs,int barva); +//#pragma aux trans_line_x parm [EDI][ESI][ECX][EDX] modify [EAX]; +void trans_line_y(int x,int y,int ys,int barva); +//#pragma aux trans_line_y parm [EDI][ESI][ECX][EDX] modify [EAX]; +void draw_placed_texture(short *txtr,int celx,int cely,int posx,int posy,int posz,char turn); + +void put_image(word *image,word *target,int start_line,int sizex,int sizey); +//#pragma aux put_image parm [ESI][EDI][EAX][EBX][EDX] modify [ECX] +void put_picture2picture(word *source,word *target,int xp,int yp); +//#pragma aux put_picture2picture parm [ESI][EDI][EAX][EDX] modify [ECX] + + + +#define swap_int(a,b) do {int c=a;a=b;b=c;} while (0); diff --git a/LIBS/BGRAPH1.ASM b/LIBS/BGRAPH1.ASM new file mode 100644 index 0000000..f779849 --- /dev/null +++ b/LIBS/BGRAPH1.ASM @@ -0,0 +1,658 @@ +.model small +.386 + + +DGROUP group _DATA +extrn _linelen:dword +extrn _screen:dword +extrn _curcolor:word +extrn _charcolors:word[7] +extrn _pictlen:dword +extrn _screen_buffer_size:dword + +SEGA000 equ 0a0000h + +_TEXT segment byte public 'CODE' use32 + assume CS:_TEXT + assume DS:DGROUP + + public getadr32_ +getadr32_: +getadr_:mul _linelen ;EAX - y; ESI - X; + shl esi,1 + add eax,esi + add eax,_screen + ret + + + public point32_ ;EAX - Y; ESI - X; ECX - COLOR +point32_: call getadr_ + mov [eax],cx + ret + + + + public bar32_ ;AX - X1, BX - Y1, CX - X2, DX - Y2 +bar32_: cmp cx,ax ;x1x1 + jnc horlin1 + xchg ecx,esi ;jestli ne tak je prohod +horlin1:sub ecx,esi ;xs=x2-x1+1 + inc ecx ; + mov si,ds ;ds -> es + mov es,si + mov edi,eax ;esi je adresa + mov ax,_curcolor ;nacti barvu + shl eax,16 + mov ax,_curcolor + shr ecx,1 + rep stosd ;nakresli caru + rcl ecx,1 + rep stosw ;popripade jeste jeden bod + pop es ;obnov es + ret + +public ver_line32_ +ver_line32_: ;EAX - Y1 ESI - X ECX - Y2 + cmp ecx,eax ;y2>y1 + jnc verlin1 + xchg ecx,eax ;jestli ne tak je prohod +verlin1:sub ecx,eax + inc ecx + call getadr_ ;eax obsahuje adresu bodu + mov esi,eax + mov ax,_curcolor ;nacti barvu +verlin2:mov [esi],ax ;kresli caru po bodech + add esi,_linelen + dec ecx + jnz verlin2 + ret + + public line_32_ +line_32_: ;eax - Y, esi - X, ecx - xs, ebx - ys (xs,ys muze byt zaporne) + or ecx,ecx + jns line1 ;kdyz je ecx (xs) zaporny je nutne otocit smer a presunout se na druhy konec linky + add esi,ecx + add eax,ebx + neg ebx + neg ecx +line1: push es ;uchovej es + or ecx,ecx ;kdyz je ecx=0 pak je to specialni pripad + inc ecx + jz lnext + call getadr_ ;zjisti adresu prvnihi bodu + mov edi,eax ;vloz ji do di + mov ax,ds ;ds -> es + mov es,ax + mov ax,_curcolor ;nacti aktualni barvu + or ebx,ebx ;kontrola zda je ebx>=0 + js lineup ;neni pak bude se kreslit nahoru + xor esi,esi ;vynuluj esi - pocitadlo mezikroku + mov edx,ecx ;delku cary na ose x do porovnavaciho registru + inc ebx +lined3: add esi,ebx ;do mezikroku pricti ys + cmp esi,edx ;kdyz to prekrocilo poronavaci registr + jc lined1 ;zacnes kreslit dolu, jinak v pravo +lined2: mov [edi],ax;zapis bod + add edi,_linelen ;a posun dolu + sub esi,edx ;odect od mezikroku hodnotu v porovnavacim registru + cmp esi,edx ;je stale preteceni? + jnc lined2 ;pokud ano opakuj zapsani bodu + add edi,2 ;dalsi xs + dec ecx ;sniz citac Xs + jnz lined3 ;pokracuj pro dalsi Xs + jmp linee ;pokud to byl posledni, pak konec +lined1: stosw ;zapis bod a posun v pravo + dec ecx ;pokracuj pro dalsi ys + jnz lined3 ;dokud neni konec + jmp linee ;pak jdi na lineEnd +lineup: neg ebx ;neguj ebx + xor esi,esi ;vynuluj esi - pocitadlo mezikroku + mov edx,ecx ;delku cary na ose x do porovnavaciho registru + inc ebx +lineu3: add esi,ebx ;do mezikroku pricti ys + cmp esi,edx ;kdyz to prekrocilo poronavaci registr + jc lineu1 ;zacnes kreslit nahoru, jinak v pravo +lineu2: mov [edi],ax;zapis bod + sub edi,_linelen ;a posun nahoru + sub esi,edx ;odect od mezikroku hodnotu v porovnavacim registru + cmp esi,edx ;je stale preteceni? + jnc lineu2 ;pokud ano opakuj zapsani bodu + add edi,2 ;dalsi xs + dec ecx ;sniz citac Xs + jnz lineu3 ;pokracuj pro dalsi Xs + jmp linee ;pokud to byl posledni, pak konec +lineu1: stosw ;zapis bod a posun v pravo + dec ecx ;pokracuj pro dalsi ys + jnz lineu3 ;dokud neni konec + jmp linee +lnext: mov ecx,ebx + add ecx,eax + call ver_line32_ +linee: pop es + ret + + public char_32_ +char_32_: ;edi - pozice na obrazovce + ;esi - ukazatel na font + ;al - znak + and eax,0ffh + mov ax,[esi][eax*2] + or ax,ax + jz chrend + add esi,eax + lodsw + xor dl,dl ;dl - je citac transparetnich pozic + mov cx,ax ;cl - XRES, ch - YRES +chr6: mov ebx,edi ;ebx - ukazuje po radcich v jednom sloupci + mov dh,ch ;dh - bude citac radku +chr5: or dl,dl ;pokud je dl = 0 pak se cte dalsi bajt + jnz chr1 ;jinak je dalsi bod jenom transparetni + lodsb ;cti barvu + or al,al ;pokud je 0 pak je transparetni + jz chr2 ;preskoc kresleni + cmp al,8 ;8 a vice jsou informace o opakovanych transparetnich bodech + jnc chr3 ;(viz FONTEDIT.DOC). Pak se podle toho zarid + and eax,0ffh;v eax jen dolnich 8 bitu + dec al + mov ax,_charcolors[EAX*2] ;vyjmi barvu + cmp ax,0ffffh;0xffff je barva ktera se nekresli; + jz chr4 ; + mov [ebx],ax;zobraz ji na obrazovce + jmp chr4 ;a skoc na konec smycky +chr3: cmp al,0ffh ;pokud je al=255 pak jsme narazily na terminator. + jz chrend ;V tom pripade KONEC + sub al,6 ;odecti do al 6. Ziskas pocet transparetnich pozic + mov dl,al ;uloz je do citace +chr1: dec dl ;pro kazdou pozici to dl odecti dokud neni 0 +chr2: +chr4: add ebx,_linelen;dalsi radka + dec dh ;odecti citac radek + jnz chr5 ;dokud neni nula + add edi,2 ;dalsi sloupec + dec cl ;odecti citac sloupcu + jnz chr6 ;dokud neni nula +chrend: ret ;konec + + public char2_32_ +char2_32_: ;edi - pozice na obrazovce + ;esi - ukazatel na font + ;al - znak + and eax,0ffh + mov ax,[esi][eax*2] + or ax,ax + jz chr2end + add esi,eax + lodsw + xor dl,dl ;dl - je citac transparetnich pozic + mov cx,ax ;cl - XRES, ch - YRES +chr26: mov ebx,edi ;ebx - ukazuje po radcich v jednom sloupci + mov dh,ch ;dh - bude citac radku +chr25: or dl,dl ;pokud je dl = 0 pak se cte dalsi bajt + jnz chr21 ;jinak je dalsi bod jenom transparetni + lodsb ;cti barvu + or al,al ;pokud je 0 pak je transparetni + jz chr22 ;preskoc kresleni + cmp al,8 ;8 a vice jsou informace o opakovanych transparetnich bodech + jnc chr23 ;(viz FONTEDIT.DOC). Pak se podle toho zarid + and eax,0ffh;v eax jen dolnich 8 bitu + dec al + mov ax,_charcolors[EAX*2] ;vyjmi barvu + push ebx + mov [ebx],ax;zobraz ji na obrazovce + mov [ebx+2],ax;zobraz ji na obrazovce + add ebx,_linelen + mov [ebx],ax;zobraz ji na obrazovce + mov [ebx+2],ax;zobraz ji na obrazovce + pop ebx + jmp chr24 ;a skoc na konec smycky +chr23: cmp al,0ffh ;pokud je al=255 pak jsme narazily na terminator. + jz chr2end ;V tom pripade KONEC + sub al,6 ;odecti do al 6. Ziskas pocet transparetnich pozic + mov dl,al ;uloz je do citace +chr21: dec dl ;pro kazdou pozici to dl odecti dokud neni 0 +chr22: +chr24: add ebx,_linelen;dalsi radka + add ebx,_linelen + dec dh ;odecti citac radek + jnz chr25 ;dokud neni nula + add edi,4 ;dalsi sloupec + dec cl ;odecti citac sloupcu + jnz chr26 ;dokud neni nula +chr2end: ret ;konec + + public charsize_ +charsize_: ;esi - ukazatel na font + ;al - znak + and eax,0ffh + mov ax,[esi][eax*2] + or ax,ax + jz chsend + add esi,eax + lodsw +chsend: and eax,0ffffh + ret + + public put_picture_ +put_picture_: ;esi - X + ;eax - Y + ;edi - obrazek + mov ecx,esi ;uchovej x v ecx + mov ebx,eax ;uchovej y v ebx + call getadr_ ;zjisti adresu bodu + mov esi,eax ;vloz ji do esi + xchg esi,edi ;prohod esi a edi aby obsahovali zpravne informace + xor eax,eax ;vynuluj pripadne bajty v horni polovine eax + lodsw ;nacti xs + mov _pictlen,eax + mov edx,eax ;z kopiruj jeste do pracovniho dx + add edx,ecx ;pricti k nemu souradnici + cmp edx,640 ;je-li vetsi nez max velikost obrazovky x + jc ppok1 ; + mov eax,640 ;pak za eax dosad plnou velikost + sub eax,ecx ;odecti souradnici +ppok1: mov ecx,eax ;vloz do ecx + lodsw ;totez pro y + mov edx,eax + add edx,ebx + cmp edx,400 + jc ppok2 + mov eax,400 + sub eax,ebx +ppok2: mov edx,eax + lodsw + mov ebx,edi + cmp al,15 + jnz pp_next + jmp pp15bit +pp_next:cmp al,8 + jnz pp_nxt2 + jmp pp8bit +pp_nxt2:ret + +pp15bit:mov eax,ecx +pp15bi1:shr ecx,1 + rep movsd + rcl ecx,1 + rep movsw + mov ecx,_pictlen + sub ecx,eax + shl ecx,1 + add esi,ecx + mov ecx,eax + add ebx,_linelen + mov edi,ebx + dec edx + jnz pp15bi1 + ret + +pp8bit: push ebp + mov ebp,ecx + mov ebx,esi + add esi,512 +pp8bit1:xor eax,eax + lodsb + or al,al + jz pp8bit2 + mov eax,[ebx+eax*2] + stosw +pp8bit4:dec ecx + jnz pp8bit1 + mov ecx,ebp + sub edi,ecx + sub edi,ecx + add edi,_linelen + sub esi,ebp + add esi,_pictlen + dec edx + jnz pp8bit1 + pop ebp + ret +pp8bit2:add edi,2 + jmp pp8bit4 + + public setPal_ +setPal_:mov edx,3c6h + mov al,255 + out dx,al + xor ah,ah +setpal1:mov edx,3c8h + mov al,ah + out dx,al + mov edx,3c9h + lodsb + out dx,al + lodsb + out dx,al + lodsb + out dx,al + inc ah + jne setPal1 + ret + + + public Redraw_lo_ +Redraw_lo_: ;esi 512Kb obrazovka + ;edi lbuffer + ;ebx xlattable + test ebx,1 + jz rdrwlo3 + inc ebx +rdrwlo3:push ebp + mov ebp,200 shl 16 + xor eax,eax + xor ecx,ecx + xor edx,edx +rdrwlo2:mov bp,160 +rdrwlo1:mov ecx,[esi] + mov edx,[esi+1280] + and ecx,7bdf7bdfh + and edx,7bdf7bdfh + add ecx,edx + shr ecx,1 + shrd ecx,edx,16 + and edx,7bdfh + and ecx,7bdfh + add edx,ecx + shr edx,1 + mov al,[ebx+edx*2] + xor ebx,1 + add esi,4 + mov ecx,[esi] + mov edx,[esi+1280] + and ecx,7bdf7bdfh + and edx,7bdf7bdfh + add ecx,edx + shr ecx,1 + shrd ecx,edx,16 + and edx,7bdfh + and ecx,7bdfh + add edx,ecx + shr edx,1 + mov ah,[ebx+edx*2] + stosw + xor ebx,1 + add esi,4 + dec bp + jnz rdrwlo1 + xor ebx,1 + add esi,1280 + sub ebp,65536 + jnz rdrwlo2 + pop ebp + ret + + public Redraw256_ +Redraw256_: ;esi - source + ;edi - target + ;ebx - xlat + + test ebx,1 + jz rdrwlo7 + inc ebx +rdrwlo7:xor eax,eax +rdrwlo4:mov ecx,400*65536 +rdrwlo6:mov cx,320 +rdrwlo5:mov edx,[esi] + add esi,4 + mov ax,dx + mov al,[ebx+eax*2] + shr edx,16 + xor ebx,1 + mov ah,[ebx+edx*2] + stosw + xor ebx,1 + dec cx + jnz rdrwlo5 + xor ebx,1 + sub ecx,65536 + jnz rdrwlo6 + ret + + public redraw32_ +redraw32_: ;esi source + ;edi target + ;ebx notused (xlat) + mov ecx,128000 + rep movsd + ret + + + public redrawbox_lo_ +redrawbox_lo_: ;esi source + ;edi target + ;ebx xlat + ;ecx xs + ;edx,ys + shr ecx,1 + shr edx,1 + dec edx + test ebx,1 + jz rboxlo3 + inc ebx +rboxlo3:push ebp + mov ebp,edx + shl ebp,16 + mov bp,cx + xor eax,eax + xor ecx,ecx + xor edx,edx +rboxlo2:push ebp + push esi + push edi +rboxlo1:mov ecx,[esi] + mov edx,[esi+1280] + and ecx,7bdf7bdfh + and edx,7bdf7bdfh + add ecx,edx + shr ecx,1 + shrd ecx,edx,16 + and edx,7bdfh + and ecx,7bdfh + add edx,ecx + shr edx,1 + mov al,[ebx+edx*2] + stosb + xor ebx,1 + add esi,4 + dec bp + jnz rboxlo1 + pop edi + pop esi + pop ebp + xor ebx,1 + add esi,_linelen + add esi,_linelen + add edi,320 + sub ebp,65536 + jnc rboxlo2 + pop ebp + ret + + public Redrawbox256_ +Redrawbox256_: ;esi - source + ;edi - target + ;ebx - xlat + ;ecx - ys + ;edx - xs + + shl ecx,16 + shr edx,1 + mov cx,dx + test ebx,1 + jz rboxlo7 + inc ebx +rboxlo7:xor eax,eax +rboxlo6:push ecx + push esi + push edi +rboxlo5:mov edx,[esi] + add esi,4 + mov ax,dx + mov al,[ebx+eax*2] + shr edx,16 + xor ebx,1 + mov ah,[ebx+edx*2] + stosw + xor ebx,1 + dec cx + jnz rboxlo5 + pop edi + pop esi + pop ecx + add esi,_linelen + add edi,640 + xor ebx,1 + sub ecx,65536 + test ecx,0ffff0000h + jnz rboxlo6 + ret + + public redrawbox32_ +redrawbox32_: ;esi source + ;edi target + ;ebx xs + ;edx ys + shr ebx,1 +rbox32: mov ecx,ebx + rep movsd + mov ecx,ebx + shl ecx,2 + sub esi,ecx + sub edi,ecx + add esi,_linelen + add edi,_linelen + dec edx + jnz rbox32 + ret + + public get_picture_ +get_picture_: ;esi - X + ;eax - Y + ;ebx - xs + ;ecx - ys + ;edi - obrazek + mov [edi],ebx ;zapis velikost obrazku + mov [edi+2],ecx + mov ecx,esi ;uchovej x v ecx + mov ebx,eax ;uchovej y v ebx + call getadr_ ;zjisti adresu bodu + mov esi,eax ;vloz ji do esi + xor eax,eax ;vynuluj pripadne bajty v horni polovine eax + mov ax,[edi];vem velikost x + add edi,2 + mov _pictlen,eax + mov edx,eax ;z kopiruj jeste do pracovniho dx + add edx,ecx ;pricti k nemu souradnici + cmp edx,640 ;je-li vetsi nez max velikost obrazovky x + jc gpok1 ; + mov eax,640 ;pak za eax dosad plnou velikost + sub eax,ecx ;odecti souradnici +gpok1: mov ecx,eax ;vloz do ecx + mov ax,[edi];vem velikost y + add edi,2 + mov edx,eax + add edx,ebx + cmp edx,400 + jc gpok2 + mov eax,400 + sub eax,ebx +gpok2: mov edx,eax + mov ax,15 ;nastav typ 15 + stosw ;zapis + mov ebx,esi ;uloz esi jeste do ebx +gp15bit:mov eax,ecx ;uloz ecx jeste do eax +gp15bi1:shr ecx,1 ;pocet dvojic bodu + rep movsd ;presun do pameti + rcl ecx,1 ;pokud zbyl jeste jeden + rep movsw ;tak ted + mov ecx,_pictlen + sub ecx,eax + shl ecx,1 + add edi,ecx ;jdi na dalsi radku v obrazku + mov ecx,eax ;obnov counter + add ebx,_linelen ;jdi na dalsi radku na obrazovce + mov esi,ebx ;obnov esi + dec edx ;dokud neni konec + jnz gp15bi1 + ret + + public hor_line_xor_ +Hor_line_xor_: ;EAX - Y ESI - X1 ECX - X2 + call getadr_ ;eax obsahuje adresu bodu + shr esi,1 + cmp ecx,esi ;x2>x1 + jnc xhorlin1 + xchg ecx,esi ;jestli ne tak je prohod +xhorlin1:sub ecx,esi ;xs=x2-x1+1 + inc ecx ; + mov edi,eax ;esi je adresa + mov ax,_curcolor ;nacti barvu +xhorlin2:xor [edi],ax + add edi,2 + dec ecx + jnz xhorlin2 + ret + +public ver_line_xor_ +ver_line_xor_: ;EAX - Y1 ESI - X ECX - Y2 + cmp ecx,eax ;y2>y1 + jnc xverlin1 + xchg ecx,eax ;jestli ne tak je prohod +xverlin1:sub ecx,eax + inc ecx + call getadr_ ;eax obsahuje adresu bodu + mov esi,eax + mov ax,_curcolor ;nacti barvu +xverlin2:xor [esi],ax ;kresli caru po bodech + add esi,_linelen + dec ecx + jnz xverlin2 + ret + + +_TEXT ends + +END diff --git a/LIBS/BGRAPH2A.ASM b/LIBS/BGRAPH2A.ASM new file mode 100644 index 0000000..f548846 --- /dev/null +++ b/LIBS/BGRAPH2A.ASM @@ -0,0 +1,1132 @@ +.model small +.386 + + +DGROUP group _DATA +extrn _linelen:dword +extrn _screen:dword +extrn _curcolor:word +extrn _charcolors:word[7] +extrn _pictlen:dword +extrn _screen_buffer_size:dword +extrn _lastbank:dword +extrn _granuality:dword +extrn _gran_mask:dword + +SEGA000 equ 0a0000h + +_TEXT segment byte public 'CODE' use32 + assume CS:_TEXT + assume DS:DGROUP + +extrn switchvesabank_:proc + + + public getadr32_ +getadr32_: +getadr_:mul _linelen ;EAX - y; ESI - X; + shl esi,1 + add eax,esi + add eax,_screen + ret + + + public point32_ ;EAX - Y; ESI - X; ECX - COLOR +point32_: call getadr_ + mov [eax],cx + ret + + + + public bar32_ ;AX - X1, BX - Y1, CX - X2, DX - Y2 +bar32_: cmp cx,ax ;x1x1 + jnc horlin1 + xchg ecx,esi ;jestli ne tak je prohod +horlin1:sub ecx,esi ;xs=x2-x1+1 + inc ecx ; + mov si,ds ;ds -> es + mov es,si + mov edi,eax ;esi je adresa + mov ax,_curcolor ;nacti barvu + shl eax,16 + mov ax,_curcolor + shr ecx,1 + rep stosd ;nakresli caru + rcl ecx,1 + rep stosw ;popripade jeste jeden bod + pop es ;obnov es + ret + +public ver_line32_ +ver_line32_: ;EAX - Y1 ESI - X ECX - Y2 + cmp ecx,eax ;y2>y1 + jnc verlin1 + xchg ecx,eax ;jestli ne tak je prohod +verlin1:sub ecx,eax + inc ecx + call getadr_ ;eax obsahuje adresu bodu + mov esi,eax + mov ax,_curcolor ;nacti barvu +verlin2:mov [esi],ax ;kresli caru po bodech + add esi,_linelen + dec ecx + jnz verlin2 + ret + + public line_32_ +line_32_: ;eax - Y, esi - X, ecx - xs, ebx - ys (xs,ys muze byt zaporne) + or ecx,ecx + jns line1 ;kdyz je ecx (xs) zaporny je nutne otocit smer a presunout se na druhy konec linky + add esi,ecx + add eax,ebx + neg ebx + neg ecx +line1: push es ;uchovej es + or ecx,ecx ;kdyz je ecx=0 pak je to specialni pripad + inc ecx + jz lnext + call getadr_ ;zjisti adresu prvnihi bodu + mov edi,eax ;vloz ji do di + mov ax,_curcolor ;nacti aktualni barvu + or ebx,ebx ;kontrola zda je ebx>=0 + js lineup ;neni pak bude se kreslit nahoru + mov esi,edx ;vynuluj esi - pocitadlo mezikroku + shr esi,1 + mov edx,ecx ;delku cary na ose x do porovnavaciho registru + inc ebx +lined3: add esi,ebx ;do mezikroku pricti ys + cmp esi,edx ;kdyz to prekrocilo poronavaci registr + jc lined1 ;zacnes kreslit dolu, jinak v pravo +lined2: mov [edi],ax;zapis bod + add edi,_linelen ;a posun dolu + sub esi,edx ;odect od mezikroku hodnotu v porovnavacim registru + cmp esi,edx ;je stale preteceni? + jnc lined2 ;pokud ano opakuj zapsani bodu + add edi,2 ;dalsi xs + dec ecx ;sniz citac Xs + jnz lined3 ;pokracuj pro dalsi Xs + jmp linee ;pokud to byl posledni, pak konec +lined1: stosw ;zapis bod a posun v pravo + dec ecx ;pokracuj pro dalsi ys + jnz lined3 ;dokud neni konec + jmp linee ;pak jdi na lineEnd +lineup: neg ebx ;neguj ebx + mov esi,edx ;vynuluj esi - pocitadlo mezikroku + shr esi,1 + mov edx,ecx ;delku cary na ose x do porovnavaciho registru + inc ebx +lineu3: add esi,ebx ;do mezikroku pricti ys + cmp esi,edx ;kdyz to prekrocilo poronavaci registr + jc lineu1 ;zacnes kreslit nahoru, jinak v pravo +lineu2: mov [edi],ax;zapis bod + sub edi,_linelen ;a posun nahoru + sub esi,edx ;odect od mezikroku hodnotu v porovnavacim registru + cmp esi,edx ;je stale preteceni? + jnc lineu2 ;pokud ano opakuj zapsani bodu + add edi,2 ;dalsi xs + dec ecx ;sniz citac Xs + jnz lineu3 ;pokracuj pro dalsi Xs + jmp linee ;pokud to byl posledni, pak konec +lineu1: stosw ;zapis bod a posun v pravo + dec ecx ;pokracuj pro dalsi ys + jnz lineu3 ;dokud neni konec + jmp linee +lnext: mov ecx,ebx + add ecx,eax + call ver_line32_ +linee: pop es + ret + + public char_32_ +char_32_: ;edi - pozice na obrazovce + ;esi - ukazatel na font + ;al - znak + and eax,0ffh + mov ax,[esi][eax*2] + or ax,ax + jz chrend + add esi,eax + lodsw + xor dl,dl ;dl - je citac transparetnich pozic + mov cx,ax ;cl - XRES, ch - YRES +chr6: mov ebx,edi ;ebx - ukazuje po radcich v jednom sloupci + mov dh,ch ;dh - bude citac radku +chr5: or dl,dl ;pokud je dl = 0 pak se cte dalsi bajt + jnz chr1 ;jinak je dalsi bod jenom transparetni + lodsb ;cti barvu + or al,al ;pokud je 0 pak je transparetni + jz chr2 ;preskoc kresleni + cmp al,8 ;8 a vice jsou informace o opakovanych transparetnich bodech + jnc chr3 ;(viz FONTEDIT.DOC). Pak se podle toho zarid + and eax,0ffh;v eax jen dolnich 8 bitu + dec al + mov ax,_charcolors[EAX*2] ;vyjmi barvu + cmp ax,0ffffh;0xffff je barva ktera se nekresli; + jz chr4 ; + mov [ebx],ax;zobraz ji na obrazovce + jmp chr4 ;a skoc na konec smycky +chr3: cmp al,0ffh ;pokud je al=255 pak jsme narazily na terminator. + jz chrend ;V tom pripade KONEC + sub al,6 ;odecti do al 6. Ziskas pocet transparetnich pozic + mov dl,al ;uloz je do citace +chr1: dec dl ;pro kazdou pozici to dl odecti dokud neni 0 +chr2: +chr4: add ebx,_linelen;dalsi radka + dec dh ;odecti citac radek + jnz chr5 ;dokud neni nula + add edi,2 ;dalsi sloupec + dec cl ;odecti citac sloupcu + jnz chr6 ;dokud neni nula +chrend: ret ;konec + + public char2_32_ +char2_32_: ;edi - pozice na obrazovce + ;esi - ukazatel na font + ;al - znak + and eax,0ffh + mov ax,[esi][eax*2] + or ax,ax + jz chr2end + add esi,eax + lodsw + xor dl,dl ;dl - je citac transparetnich pozic + mov cx,ax ;cl - XRES, ch - YRES +chr26: mov ebx,edi ;ebx - ukazuje po radcich v jednom sloupci + mov dh,ch ;dh - bude citac radku +chr25: or dl,dl ;pokud je dl = 0 pak se cte dalsi bajt + jnz chr21 ;jinak je dalsi bod jenom transparetni + lodsb ;cti barvu + or al,al ;pokud je 0 pak je transparetni + jz chr22 ;preskoc kresleni + cmp al,8 ;8 a vice jsou informace o opakovanych transparetnich bodech + jnc chr23 ;(viz FONTEDIT.DOC). Pak se podle toho zarid + and eax,0ffh;v eax jen dolnich 8 bitu + dec al + mov ax,_charcolors[EAX*2] ;vyjmi barvu + push ebx + mov [ebx],ax;zobraz ji na obrazovce + mov [ebx+2],ax;zobraz ji na obrazovce + add ebx,_linelen + mov [ebx],ax;zobraz ji na obrazovce + mov [ebx+2],ax;zobraz ji na obrazovce + pop ebx + jmp chr24 ;a skoc na konec smycky +chr23: cmp al,0ffh ;pokud je al=255 pak jsme narazily na terminator. + jz chr2end ;V tom pripade KONEC + sub al,6 ;odecti do al 6. Ziskas pocet transparetnich pozic + mov dl,al ;uloz je do citace +chr21: dec dl ;pro kazdou pozici to dl odecti dokud neni 0 +chr22: +chr24: add ebx,_linelen;dalsi radka + add ebx,_linelen + dec dh ;odecti citac radek + jnz chr25 ;dokud neni nula + add edi,4 ;dalsi sloupec + dec cl ;odecti citac sloupcu + jnz chr26 ;dokud neni nula +chr2end: ret ;konec + + public charsize_ +charsize_: ;esi - ukazatel na font + ;al - znak + and eax,0ffh + mov ax,[esi][eax*2] + or ax,ax + jz chsend + add esi,eax + lodsw +chsend: and eax,0ffffh + ret + + public put_picture_ +put_picture_: ;esi - X + ;eax - Y + ;edi - obrazek + mov ecx,esi ;uchovej x v ecx + mov ebx,eax ;uchovej y v ebx + call getadr_ ;zjisti adresu bodu + mov esi,eax ;vloz ji do esi + xchg esi,edi ;prohod esi a edi aby obsahovali zpravne informace + xor eax,eax ;vynuluj pripadne bajty v horni polovine eax + lodsw ;nacti xs + mov _pictlen,eax + mov edx,eax ;z kopiruj jeste do pracovniho dx + add edx,ecx ;pricti k nemu souradnici + cmp edx,640 ;je-li vetsi nez max velikost obrazovky x + jc ppok1 ; + mov eax,640 ;pak za eax dosad plnou velikost + sub eax,ecx ;odecti souradnici +ppok1: mov ecx,eax ;vloz do ecx + lodsw ;totez pro y + mov edx,eax + add edx,ebx + cmp edx,480 + jc ppok2 + mov eax,480 + sub eax,ebx +ppok2: mov edx,eax + lodsw + mov ebx,edi + cmp al,15 + jnz pp_next + jmp pp15bit +pp_next:cmp al,8 + jnz pp_nxt2 + jmp pp8bit +pp_nxt2:ret + +pp15bit:mov eax,ecx +pp15bi1:shr ecx,1 + rep movsd + rcl ecx,1 + rep movsw + mov ecx,_pictlen + sub ecx,eax + shl ecx,1 + add esi,ecx + mov ecx,eax + add ebx,_linelen + mov edi,ebx + dec edx + jnz pp15bi1 + ret + +pp8bit: push ebp + mov ebp,ecx + mov ebx,esi + add esi,512 +pp8bit1:xor eax,eax + lodsb + or al,al + jz pp8bit2 + mov eax,[ebx+eax*2] + stosw +pp8bit4:dec ecx + jnz pp8bit1 + mov ecx,ebp + sub edi,ecx + sub edi,ecx + add edi,_linelen + sub esi,ebp + add esi,_pictlen + dec edx + jnz pp8bit1 + pop ebp + ret +pp8bit2:add edi,2 + jmp pp8bit4 + + public setPal_ +setPal_:mov edx,3c6h + mov al,255 + out dx,al + xor ah,ah +setpal1:mov edx,3c8h + mov al,ah + out dx,al + mov edx,3c9h + lodsb + out dx,al + lodsb + out dx,al + lodsb + out dx,al + inc ah + jne setPal1 + ret + +xvga_data: + DB 62h,4fh,50h,85h,56h,80h,0bh,3eh + DB 00h,40h,00h,00h,00h,00h,00h,28h + Db 0EAh,0ch,0DFh,28h,00h,0e7h,04h,0c3h,0ffh + + + + public init_lo_ +init_lo_: + mov eax,13h + int 10h ;{Inicializace modu 320x200x256} + + mov edx,3c4h ;{Zpristupneni Memory Mode reg.} + mov al,04h ;{04h -> 3c4h} + out dx,al + ;{Cte port 3c5h a modifikuje ho:} + mov bl,0f7h ;{Spristupni video ram pomoci} + inc edx ;{bitovych map - Map Mask Reg.} + in al,dx ;{rozdeleni na 4 bitove mapy} + and al,bl ;{jedna adresa reprezentuje 4 pixely} + out dx,al ;{(kazdy je v jedne ze 4 bitovych map)} + + mov ecx,0ffffh ;{Vynulovani segmentu 0A000h} + mov edi,0a0000h + mov al,00h + +int_lo1:rep stosb + + cli + + mov edx,3c4h ;{Port 3c4h -> Index Reset Reg.} + mov al,00h ;{Spristupni Reset Register} + out dx,al + + inc edx ;{Synchronizujici reset} + inc al + out dx,al ;{Port 3c2h ->} + mov edx,3c2h ;{VGA Miscellaneous Output Reg.} + mov al,0c7h ;{Nastavi 480 radku -bit 7,8=1,1} + out dx,al ;{ 28.322 MHz -bit 3,2=0,1} + + mov edx,3c5h ;{A opet reset} + mov al,03h + out dx,al + + sti + ;{Spristupni Color/VGA Data Reg.} + mov edx,3d4h ;{Port 3d4h} + mov al,11h + out dx,al + + inc edx ; {Bit 7 - Protect Bit} + in al,dx + and al,7fh + out dx,al + + + mov esi,offset xvga_data + mov ecx,19h + mov bl,00h +int_lo2: + mov edx,3d4h + mov al,bl + out dx,al + inc edx + mov al,byte ptr [cs:esi] + out dx,al + + inc si + inc bl + dec ecx + + jne int_lo2 + + ret + + + public Redraw_lo_ +Redraw_lo_: ;esi 614Kb obrazovka + ;edi lbuffer + ;ebx xlattable + + mov eax,1102h +rdrwlo2:mov edx,3c4h + out dx,ax + push eax + push esi + xor eax,eax + mov edi,0xa0000h + mov ecx,40*480 +rdrwlo1:lodsd + add esi,12 + shld edx,eax,16 + and eax,7bdeh ;odmaskuj pro soften + and edx,7bdeh + add eax,edx ;soften + shr eax,1 + mov al,[ebx+eax*2] ;vyber barvu z palety + mov dl,al + lodsd + add esi,12 + shld edx,eax,16 + and eax,7bdeh ;odmaskuj pro soften + and dx,7bdeh + add ax,dx ;soften + shr eax,1 + mov al,[ebx+eax*2] ;vyber barvu z palety + shr edx,8 + mov ah,dh + xchg ah,al + stosw + dec ecx + jnz rdrwlo1 + pop esi + pop eax + add esi,4 + rol ah,1 + jnc rdrwlo2 + ret + + public Redraw256_ +Redraw256_: ;esi - source + ;edi - target + ;ebx - xlat + + test ebx,1 + jz rdrwlo7 + inc ebx +rdrwlo7:xor eax,eax +rdrwlo4:mov ecx,480*65536 +rdrwlo6:mov cx,320 +rdrwlo5:mov edx,[esi] + and edx,7fff7fffh + add esi,4 + mov ax,dx + mov al,[ebx+eax*2] + xor ebx,1 + shr edx,16 + mov ah,[ebx+edx*2] + xor ebx,1 + stosw + dec cx + jnz rdrwlo5 + xor ebx,1 + sub ecx,65536 + jnz rdrwlo6 + ret + + public redraw32_ +redraw32_: ;esi source + ;edi target + ;ebx notused (xlat) + mov ecx,(640*480*2) shr 2 + rep movsd + ret + + + public redrawbox_lo_ +redrawbox_lo_: ;esi source + ;edi target + ;ebx xlat + ;ecx xs + ;edx,ys + shr ecx,1 + mov eax,1102h + xchg ecx,edi + shr ecx,1 + rol ah,cl + shr ecx,2 + add ecx,0a0000h + xchg ecx,edi + shl ecx,16 + and edx,0ffffh + or ecx,edx + push ebp + mov edx,3c4h ;edx adresa sequenceru + mov ebp,ecx ;ebp velikost ramce + sub ebp,10000h +rboxlo2:out dx,ax ;nastav bit roviny + push esi + push edi + push eax + push ebp ;bp pocet radku +rboxlo1:mov ecx,[esi] ;nacti dve barvy + shld eax,ecx,16 ;presun horni pulku do ecx + and eax,7bdfh ;odmaskuj pro soften + and ecx,7bdfh + add eax,ecx ;soften + shr eax,1 ;/2 + mov al,[ebx+eax*2] ;vyber barvu z palety + mov [edi],al ;zapis + add esi,_linelen ;dalsi radek + add edi,80 + dec bp ;dokud to neni vsechno + jnz rboxlo1 + pop ebp + pop eax + pop edi + pop esi + add esi,4 + rol ah,1 + adc edi,0 + sub ebp,10000h + jnc rboxlo2 + pop ebp + ret + + + public Redrawbox256_ +Redrawbox256_: ;esi - source + ;edi - target + ;ebx - xlat + ;ecx - ys + ;edx - xs + + shl ecx,16 + shr edx,1 + mov cx,dx + test ebx,1 + jz rboxlo7 + inc ebx +rboxlo7:xor eax,eax +rboxlo6:push ecx + push esi + push edi +rboxlo5:mov edx,[esi] + and edx,07fff7fffh + add esi,4 + mov ax,dx + mov al,[ebx+eax*2] + xor ebx,1 + shr edx,16 + mov ah,[ebx+edx*2] + xor ebx,1 + stosw + dec cx + jnz rboxlo5 + pop edi + pop esi + pop ecx + add esi,_linelen + add edi,640 + xor ebx,1 + sub ecx,65536 + test ecx,0ffff0000h + jnz rboxlo6 + ret + + public redrawbox32_ +redrawbox32_: ;esi source + ;edi target + ;ebx xs + ;edx ys + shr ebx,1 +rbox32: mov ecx,ebx + rep movsd + mov ecx,ebx + shl ecx,2 + sub esi,ecx + sub edi,ecx + add esi,_linelen + add edi,_linelen + dec edx + jnz rbox32 + ret + + public get_picture_ +get_picture_: ;esi - X + ;eax - Y + ;ebx - xs + ;ecx - ys + ;edi - obrazek + mov [edi],ebx ;zapis velikost obrazku + mov [edi+2],ecx + mov ecx,esi ;uchovej x v ecx + mov ebx,eax ;uchovej y v ebx + call getadr_ ;zjisti adresu bodu + mov esi,eax ;vloz ji do esi + xor eax,eax ;vynuluj pripadne bajty v horni polovine eax + mov ax,[edi];vem velikost x + add edi,2 + mov _pictlen,eax + mov edx,eax ;z kopiruj jeste do pracovniho dx + add edx,ecx ;pricti k nemu souradnici + cmp edx,640 ;je-li vetsi nez max velikost obrazovky x + jc gpok1 ; + mov eax,640 ;pak za eax dosad plnou velikost + sub eax,ecx ;odecti souradnici +gpok1: mov ecx,eax ;vloz do ecx + mov ax,[edi];vem velikost y + add edi,2 + mov edx,eax + add edx,ebx + cmp edx,480 + jc gpok2 + mov eax,480 + sub eax,ebx +gpok2: mov edx,eax + mov ax,15 ;nastav typ 15 + stosw ;zapis + mov ebx,esi ;uloz esi jeste do ebx +gp15bit:mov eax,ecx ;uloz ecx jeste do eax +gp15bi1:shr ecx,1 ;pocet dvojic bodu + rep movsd ;presun do pameti + rcl ecx,1 ;pokud zbyl jeste jeden + rep movsw ;tak ted + mov ecx,_pictlen + sub ecx,eax + shl ecx,1 + add edi,ecx ;jdi na dalsi radku v obrazku + mov ecx,eax ;obnov counter + add ebx,_linelen ;jdi na dalsi radku na obrazovce + mov esi,ebx ;obnov esi + dec edx ;dokud neni konec + jnz gp15bi1 + ret + + public hor_line_xor_ +Hor_line_xor_: ;EAX - Y ESI - X1 ECX - X2 + call getadr_ ;eax obsahuje adresu bodu + shr esi,1 + cmp ecx,esi ;x2>x1 + jnc xhorlin1 + xchg ecx,esi ;jestli ne tak je prohod +xhorlin1:sub ecx,esi ;xs=x2-x1+1 + inc ecx ; + mov edi,eax ;esi je adresa + mov ax,_curcolor ;nacti barvu +xhorlin2:xor [edi],ax + add edi,2 + dec ecx + jnz xhorlin2 + ret + +public ver_line_xor_ +ver_line_xor_: ;EAX - Y1 ESI - X ECX - Y2 + cmp ecx,eax ;y2>y1 + jnc xverlin1 + xchg ecx,eax ;jestli ne tak je prohod +xverlin1:sub ecx,eax + inc ecx + call getadr_ ;eax obsahuje adresu bodu + mov esi,eax + mov ax,_curcolor ;nacti barvu +xverlin2:xor [esi],ax ;kresli caru po bodech + add esi,_linelen + dec ecx + jnz xverlin2 + ret + +public switchmap_ ;eax - bank +switchmap_: + cmp eax,_lastbank + jz swbnk1 + pushad + mov _lastbank,eax + call switchvesabank_ + popad +swbnk1: ret + +public mapvesaadr_ ;edi - adr +mapvesaadr_: + push eax + push ecx + mov eax,edi + mov ecx,_granuality + shr eax,cl + call switchmap_ + pop ecx + pop eax + and edi,_gran_mask + add edi,0xa0000 + ret + +mapvesaadr macro + push eax + push ecx + mov eax,edi + mov ecx,_granuality + shr eax,cl + call switchmap_ + pop ecx + pop eax + and edi,_gran_mask + add edi,0xa0000 +endm + + + public redraw32b_ +redraw32b_: ;esi source + ;edi target + ;ebx notused (xlat) + xor eax,eax +rdrw32b:mov ebx,480 +rdrw32b1:mov edi,eax + call mapvesaadr_ + mov ecx,320 + rep movsd + add eax,2048 + dec ebx + jnz rdrw32b1 + ret + + + public redrawbox32b_ +redrawbox32b_: ;esi source + ;edi target + ;ebx xs + ;edx ys + mov eax,edi +rbox32b:mov edi,eax + call mapvesaadr_ + mov ecx,ebx + shr ecx,1 + rep movsd + rcl ecx,1 + rep movsw + mov ecx,ebx + shl ecx,1 + sub esi,ecx + add eax,2048 + add esi,_linelen + dec edx + jnz rbox32b + ret + +swap_at_end macro reg16,reg32 + local sw1,sw2 + +sw2: movzx eax,reg16 ;nacti 16 bitovou cast registru + dec eax ;sniz ke kontrole o 1 + cmp eax,_gran_mask ;kontrola zda je vetsi nebo rovny masce + jc sw1 ;kdyz ne tak preskoc na sw1 + mov eax,_lastbank ;vem cislo banky + inc eax ;pricti jednicku + mov _lastbank,eax ;vloz zpatky do banky + pushad + call switchvesabank_ ;prepni banku + popad + sub reg32,_gran_mask ;odecti delku stranky od cele adresy + dec reg32 +sw1: +endm + public Redraw256b_ +Redraw256b_: ;esi - source + ;edi - target + ;ebx - xlat + xor edi,edi + call mapvesaadr_ + xor eax,eax +rdrwlb4:mov ecx,480*65536 +rdrwlb6:mov cx,320 +rdrwlb5:mov edx,[esi] + and edx,7fff7fffh + add esi,4 + mov ax,dx + mov al,[ebx+eax*2] + shr edx,16 + xor ebx,1 + mov ah,[ebx+edx*2] + stosw + swap_at_end di,edi + xor ebx,1 + dec cx + jnz rdrwlb5 + xor ebx,1 + sub ecx,65536 + jnz rdrwlb6 + ret + + public Redrawbox256b_ +Redrawbox256b_: ;esi - source + ;edi - target + ;ebx - xlat + ;ecx - ys + ;edx - xs + + shl ecx,16 + shr edx,1 + mov cx,dx + test ebx,1 + jz rboxlb7 + inc ebx +rboxlb7:xor eax,eax +rboxlb6:push ecx + push esi + push edi + call mapvesaadr_ +rboxlb5:mov edx,[esi] + and edx,7fff7fffh + add esi,4 + mov ax,dx + mov al,[ebx+eax*2] + shr edx,16 + xor ebx,1 + mov ah,[ebx+edx*2] + stosw + swap_at_end di,edi + xor ebx,1 + dec cx + jnz rboxlb5 + pop edi + pop esi + pop ecx + add esi,_linelen + add edi,640 + xor ebx,1 + sub ecx,65536 + test ecx,0ffff0000h + jnz rboxlb6 + ret + + public Redraw16_plane +Redraw16_plane: ;esi - source + ;edi - target (A0000h) + ;ebx - xlat + ;ebp - planenum (jednicka v prislusnem bitu) + mov ecx,640*480 + mov edi,SEGA000 +rdrw16_l1: + shl eax,1 + movzx edx,word ptr[esi] + test [ebx+edx*2],ebp + jz rdrw16_s + or eax,1 +rdrw16_s: + add esi,2 + dec ecx + test ecx,15 + jnz rdrw16_l1 + xchg al,ah + test ecx,31 + jnz rdrw16_l1 + rol eax,16 + stosd + or ecx,ecx + jnz rdrw16_l1 + ret + + public Redraw16_ +Redraw16_: + + push ebp + push esi + mov edx,3c4h + mov eax,0802h + mov ebp,8h + out dx,ax + call Redraw16_plane + pop esi + push esi + mov edx,3c4h + mov eax,0402h + mov ebp,4h + out dx,ax + call Redraw16_plane + pop esi + push esi + mov edx,3c4h + mov eax,0202h + mov ebp,2h + out dx,ax + call Redraw16_plane + pop esi + mov edx,3c4h + mov eax,0102h + mov ebp,1h + out dx,ax + call Redraw16_plane + pop ebp + ret + +;Redraw16_: + push ebp + mov edx,3c4h + mov eax,0f02h + out dx,ax + mov edx,3ceh + mov eax,0205h + out dx,ax + mov eax,8008h + mov edi,SEGA000 + mov ebp,640*480 +rdw16: movzx ecx,word ptr[esi] + mov cl,byte ptr [ebx+ecx*2] + out dx,ax + mov [edi],cl + add esi,2 + ror ah,1 + adc edi,0 + dec ebp + jnz rdw16 + pop ebp + mov eax,0005h + out dx,ax + mov eax,0ff08h + out dx,ax + ret + + public Redraw16box_plane + ;esi - pozice + ;edi - output + ;ecx - ch = xs, hodni ecx=ys + ;esi - source + ;ebx - xlat + ;ebp - planenum (jednicka v prislusnem bitu) +redraw16box_plane: + sub ecx,10000h +rbx16_l1: + mov cl,ch + push esi + push edi +rbx16_l2: + mov ah,8 +rbx16_l3: + shl al,1 + movzx edx,word ptr[esi] + test [ebx+edx*2],ebp + jz rbx16_s + or al,1 +rbx16_s: + add esi,2 + dec ah + jnz rbx16_l3 + stosb + dec cl + jnz rbx16_l2 + pop edi + pop esi + add esi,1280 + add edi,80 + sub ecx,10000h + jnc rbx16_l1 + ret + + public Redrawbox16_ + ;esi - pozice + ;edi - output + ;ecx - xs + ;edx - ys + ;ebx - xlat +Redrawbox16_: + push ebp + mov eax,esp + push esi + push edi + shl ecx,16 + and edx,0ffh + shl edx,8 + or ecx,edx + push ecx + push eax + mov edx,3c4h + mov eax,0802h + out dx,ax + mov ebp,8 + call Redraw16box_plane + mov ebp,esp + mov ecx,[ebp+4] + mov edi,[ebp+8] + mov esi,[ebp+12] + mov edx,3c4h + mov eax,0402h + out dx,ax + mov ebp,4 + call Redraw16box_plane + mov ebp,esp + mov ecx,[ebp+4] + mov edi,[ebp+8] + mov esi,[ebp+12] + mov edx,3c4h + mov eax,0202h + out dx,ax + mov ebp,2 + call Redraw16box_plane + mov ebp,esp + mov ecx,[ebp+4] + mov edi,[ebp+8] + mov esi,[ebp+12] + mov edx,3c4h + mov eax,0102h + out dx,ax + mov ebp,1 + call Redraw16box_plane + pop esp + pop ebp + ret + + + +public redraw32bb_ +Redraw32bb_: + ;esi source + ;edi target + + mov ebx,(640*480)*2 ;ebx je velikost obrazovky + mov edx,_gran_mask + inc edx +rd32bb2:mov ecx,ebx ;ecx je velikost prenaseneho bloku + cmp ecx,edx ;kontrola zda li se prenasi prez stranku + jc rd32bb1 ;pokud ne pa ecx==ebx + mov ecx,edx ;jinak prenos stranky +rd32bb1:mov eax,edi ;uchovej edi + sub ebx,ecx ;ve tvaru o ecx vetsi (po prenosu + add eax,ecx ;a ebx sniz o prenaseny pocet + shr ecx,2 ;prenos probiha ve dword rezimu + mapvesaadr ;mapuj stranku edi=>edi + rep movsd ;prenos pameti + mov edi,eax ;obnov edi + or ebx,ebx ;test ebx na nulu + jnz rd32bb2 ;konec + ret + + +public redrawbox32bb_ +redrawbox32bb_: + ;esi source + ;edi target + ;ebx xs + ;edx ys + + shl ebx,1 ;delka je *2 +rdb32bb3:mov eax,edi ;precti adresu + and eax,_gran_mask ;maskuj stranku + sub eax,_gran_mask ;eax je pocet bajtu do nasledujiciho prenuti stranky + neg eax ;+1 + inc eax + push ebx ;uchovej delku ctverce v zasobniku +rdb32bb2:mov ecx,ebx ;vem minimum z cisel ebx a eax a dej to ecx + cmp ecx,eax + jc rdb32bb1 + mov ecx,eax +rdb32bb1:sub ebx,ecx ;odecti delku prenasenych bajtu + add edi,ecx ;pricti delku k adrese + push edi ;uloz to do sp + sub edi,ecx ;sniz adresu na puvodni hodnotu + shr ecx,2 ;del ecx 4 (presun dvojslov) + mapvesaadr ;namapuj adresu a banku + rep movsd ;PRESUN + pop edi ;obnov adresu + or ebx,ebx ;kontrola zda je prenesen radek + jnz rdb32bb2 ;ne, opakuj od urceni minima + pop ebx ;ano, obnov delku ctverce ze zasobniku + mov ecx,1280 ;od 1280 (640*2) odecti + sub ecx,ebx ;delku radky + add edi,ecx ;pricti to jak k cili + add esi,ecx ; tak ke zdroji + dec edx ;sniz citac radku + jnz rdb32bb3 ;dokud neni 0 + ret +_TEXT ends +END diff --git a/LIBS/BLDICONS.C b/LIBS/BLDICONS.C new file mode 100644 index 0000000..64cca04 --- /dev/null +++ b/LIBS/BLDICONS.C @@ -0,0 +1,82 @@ +#include +#include +#include +#include "memman.h" +#include "pcx.h" + +FILE *src,*trg,*scr; +#define IKNNAME "IKONY%02d.LIB" +#define IKONSINLIB 17 +#define PCXSIZE (2+2+2+512+45*55) +int icount=6; +char szBuff[65536]; + +void Error(char *text,char *param) + { + printf(text,param); + puts(""); + exit(1); + } + +void ReadScript(char *script) + { + int i; + int j=0; + char *pcx; + unsigned short *wpcx; + scr=fopen(script,"rt"); + if (scr==NULL) Error("Nemohu otevrit soubor: %s",script); + i=fscanf(scr,"%s",szBuff); + while (i!=EOF) + { + if (open_pcx(szBuff,A_8BIT,&pcx)==-1) Error("Nemohu pracovat se souborem: %s",szBuff); + wpcx=(unsigned short *)pcx; + if (wpcx[0]!=45 && wpcx[1]!=55) Error("Ikona musi mit rozmety 45x55. Soubor: %s",szBuff); + if (j==0) + { + sprintf(szBuff,IKNNAME,icount++); + printf("Sestavuji soubor %s\n",szBuff); + trg=fopen(szBuff,"wb"); + if (trg==NULL) Error("Nelze zapisovat do souboru %s",szBuff); + } + if (!fwrite(pcx,PCXSIZE,1,trg)) Error("Chyba nastala pri zapisu do souboru %s",szBuff); + free(pcx); + j++; + if (j==18) + { + fclose(trg); + j=0; + } + i=fscanf(scr,"%s",szBuff); + } + if (j!=0) + { + void *p; + int s; + p=malloc(s=(18-j)*PCXSIZE); + memset(p,0,s); + fwrite(p,s,1,trg); + } + fcloseall(); + } + +void Help() + { + Error("Pouziti: \n" + "\n" + "BLDICONS