Initial import. master
authorSimon Morgan <sjm@sjm.io>
Fri, 8 May 2015 00:15:24 +0000 (01:15 +0100)
committerSimon Morgan <sjm@sjm.io>
Fri, 8 May 2015 00:15:24 +0000 (01:15 +0100)
726 files changed:
SFI Source Code license agreement.txt [new file with mode: 0644]
Standard Gaming Platform/Bitmap.h [new file with mode: 0644]
Standard Gaming Platform/Button Sound Control.c [new file with mode: 0644]
Standard Gaming Platform/Button Sound Control.h [new file with mode: 0644]
Standard Gaming Platform/Button System.c [new file with mode: 0644]
Standard Gaming Platform/Button System.h [new file with mode: 0644]
Standard Gaming Platform/Compression.c [new file with mode: 0644]
Standard Gaming Platform/Compression.h [new file with mode: 0644]
Standard Gaming Platform/Container.c [new file with mode: 0644]
Standard Gaming Platform/Container.h [new file with mode: 0644]
Standard Gaming Platform/Cursor Control.c [new file with mode: 0644]
Standard Gaming Platform/Cursor Control.h [new file with mode: 0644]
Standard Gaming Platform/DEBUG.C [new file with mode: 0644]
Standard Gaming Platform/DEBUG.H [new file with mode: 0644]
Standard Gaming Platform/DbMan.c [new file with mode: 0644]
Standard Gaming Platform/DbMan.h [new file with mode: 0644]
Standard Gaming Platform/DirectDraw Calls.c [new file with mode: 0644]
Standard Gaming Platform/DirectDraw Calls.h [new file with mode: 0644]
Standard Gaming Platform/DirectX Common.c [new file with mode: 0644]
Standard Gaming Platform/DirectX Common.h [new file with mode: 0644]
Standard Gaming Platform/English.c [new file with mode: 0644]
Standard Gaming Platform/ExceptionHandling.cpp [new file with mode: 0644]
Standard Gaming Platform/ExceptionHandling.h [new file with mode: 0644]
Standard Gaming Platform/FileMan.c [new file with mode: 0644]
Standard Gaming Platform/FileMan.h [new file with mode: 0644]
Standard Gaming Platform/Flic.c [new file with mode: 0644]
Standard Gaming Platform/Font.c [new file with mode: 0644]
Standard Gaming Platform/Font.h [new file with mode: 0644]
Standard Gaming Platform/Install.c [new file with mode: 0644]
Standard Gaming Platform/Install.h [new file with mode: 0644]
Standard Gaming Platform/JA2 SGP ALL.H [new file with mode: 0644]
Standard Gaming Platform/Ja2 Libs.c [new file with mode: 0644]
Standard Gaming Platform/Ja2 Libs.h [new file with mode: 0644]
Standard Gaming Platform/LibraryDataBase.c [new file with mode: 0644]
Standard Gaming Platform/LibraryDataBase.h [new file with mode: 0644]
Standard Gaming Platform/MemMan.c [new file with mode: 0644]
Standard Gaming Platform/MemMan.h [new file with mode: 0644]
Standard Gaming Platform/Mss-old.h [new file with mode: 0644]
Standard Gaming Platform/Mss.h [new file with mode: 0644]
Standard Gaming Platform/Mutex Manager.c [new file with mode: 0644]
Standard Gaming Platform/Mutex Manager.h [new file with mode: 0644]
Standard Gaming Platform/PCX.C [new file with mode: 0644]
Standard Gaming Platform/RAD.H [new file with mode: 0644]
Standard Gaming Platform/Random.c [new file with mode: 0644]
Standard Gaming Platform/RegInst.c [new file with mode: 0644]
Standard Gaming Platform/RegInst.h [new file with mode: 0644]
Standard Gaming Platform/SMACK.H [new file with mode: 0644]
Standard Gaming Platform/SMACKW32.LIB [new file with mode: 0644]
Standard Gaming Platform/STCI.c [new file with mode: 0644]
Standard Gaming Platform/STCI.h [new file with mode: 0644]
Standard Gaming Platform/Standard Gaming Platform.dsp [new file with mode: 0644]
Standard Gaming Platform/TopicIDs.h [new file with mode: 0644]
Standard Gaming Platform/TopicOps.h [new file with mode: 0644]
Standard Gaming Platform/Types.h [new file with mode: 0644]
Standard Gaming Platform/WCheck.h [new file with mode: 0644]
Standard Gaming Platform/WinFont.c [new file with mode: 0644]
Standard Gaming Platform/WinFont.h [new file with mode: 0644]
Standard Gaming Platform/WizShare.h [new file with mode: 0644]
Standard Gaming Platform/ZCONF.H [new file with mode: 0644]
Standard Gaming Platform/ZLIB.H [new file with mode: 0644]
Standard Gaming Platform/ddraw.h [new file with mode: 0644]
Standard Gaming Platform/ddraw.lib [new file with mode: 0644]
Standard Gaming Platform/dsound.h [new file with mode: 0644]
Standard Gaming Platform/english.h [new file with mode: 0644]
Standard Gaming Platform/flic.h [new file with mode: 0644]
Standard Gaming Platform/himage.c [new file with mode: 0644]
Standard Gaming Platform/himage.h [new file with mode: 0644]
Standard Gaming Platform/imgfmt.h [new file with mode: 0644]
Standard Gaming Platform/impTGA.c [new file with mode: 0644]
Standard Gaming Platform/impTGA.h [new file with mode: 0644]
Standard Gaming Platform/input.c [new file with mode: 0644]
Standard Gaming Platform/input.h [new file with mode: 0644]
Standard Gaming Platform/line.c [new file with mode: 0644]
Standard Gaming Platform/line.h [new file with mode: 0644]
Standard Gaming Platform/mousesystem.c [new file with mode: 0644]
Standard Gaming Platform/mousesystem.h [new file with mode: 0644]
Standard Gaming Platform/mousesystem_macros.h [new file with mode: 0644]
Standard Gaming Platform/mss32.lib [new file with mode: 0644]
Standard Gaming Platform/pcx.h [new file with mode: 0644]
Standard Gaming Platform/random.h [new file with mode: 0644]
Standard Gaming Platform/sgp.c [new file with mode: 0644]
Standard Gaming Platform/sgp.h [new file with mode: 0644]
Standard Gaming Platform/shading.c [new file with mode: 0644]
Standard Gaming Platform/shading.h [new file with mode: 0644]
Standard Gaming Platform/soundman.c [new file with mode: 0644]
Standard Gaming Platform/soundman.h [new file with mode: 0644]
Standard Gaming Platform/timer.c [new file with mode: 0644]
Standard Gaming Platform/timer.h [new file with mode: 0644]
Standard Gaming Platform/trle.h [new file with mode: 0644]
Standard Gaming Platform/video.c [new file with mode: 0644]
Standard Gaming Platform/video.h [new file with mode: 0644]
Standard Gaming Platform/video_private.h [new file with mode: 0644]
Standard Gaming Platform/vobject.c [new file with mode: 0644]
Standard Gaming Platform/vobject.h [new file with mode: 0644]
Standard Gaming Platform/vobject_blitters.c [new file with mode: 0644]
Standard Gaming Platform/vobject_blitters.h [new file with mode: 0644]
Standard Gaming Platform/vobject_private.h [new file with mode: 0644]
Standard Gaming Platform/vsurface.c [new file with mode: 0644]
Standard Gaming Platform/vsurface.h [new file with mode: 0644]
Standard Gaming Platform/vsurface_private.h [new file with mode: 0644]
ja2/Build/Cheats.h [new file with mode: 0644]
ja2/Build/Credits.c [new file with mode: 0644]
ja2/Build/Credits.h [new file with mode: 0644]
ja2/Build/Editor/Button Defines.h [new file with mode: 0644]
ja2/Build/Editor/Cursor Modes.c [new file with mode: 0644]
ja2/Build/Editor/Cursor Modes.h [new file with mode: 0644]
ja2/Build/Editor/Editor All.h [new file with mode: 0644]
ja2/Build/Editor/Editor Callback Prototypes.h [new file with mode: 0644]
ja2/Build/Editor/Editor Callbacks.c [new file with mode: 0644]
ja2/Build/Editor/Editor Modes.c [new file with mode: 0644]
ja2/Build/Editor/Editor Modes.h [new file with mode: 0644]
ja2/Build/Editor/Editor Taskbar Creation.c [new file with mode: 0644]
ja2/Build/Editor/Editor Taskbar Creation.h [new file with mode: 0644]
ja2/Build/Editor/Editor Taskbar Utils.c [new file with mode: 0644]
ja2/Build/Editor/Editor Taskbar Utils.h [new file with mode: 0644]
ja2/Build/Editor/Editor Undo.c [new file with mode: 0644]
ja2/Build/Editor/Editor Undo.h [new file with mode: 0644]
ja2/Build/Editor/Editor.dsp [new file with mode: 0644]
ja2/Build/Editor/EditorBuildings.c [new file with mode: 0644]
ja2/Build/Editor/EditorBuildings.h [new file with mode: 0644]
ja2/Build/Editor/EditorDefines.h [new file with mode: 0644]
ja2/Build/Editor/EditorItems.c [new file with mode: 0644]
ja2/Build/Editor/EditorItems.h [new file with mode: 0644]
ja2/Build/Editor/EditorMapInfo.c [new file with mode: 0644]
ja2/Build/Editor/EditorMapInfo.h [new file with mode: 0644]
ja2/Build/Editor/EditorMercs.c [new file with mode: 0644]
ja2/Build/Editor/EditorMercs.h [new file with mode: 0644]
ja2/Build/Editor/EditorTerrain.c [new file with mode: 0644]
ja2/Build/Editor/EditorTerrain.h [new file with mode: 0644]
ja2/Build/Editor/Item Statistics.c [new file with mode: 0644]
ja2/Build/Editor/Item Statistics.h [new file with mode: 0644]
ja2/Build/Editor/LoadScreen.c [new file with mode: 0644]
ja2/Build/Editor/LoadScreen.h [new file with mode: 0644]
ja2/Build/Editor/Road Smoothing.c [new file with mode: 0644]
ja2/Build/Editor/Road Smoothing.h [new file with mode: 0644]
ja2/Build/Editor/Sector Summary.c [new file with mode: 0644]
ja2/Build/Editor/Sector Summary.h [new file with mode: 0644]
ja2/Build/Editor/SmartMethod.c [new file with mode: 0644]
ja2/Build/Editor/SmartMethod.h [new file with mode: 0644]
ja2/Build/Editor/Smoothing Utils.c [new file with mode: 0644]
ja2/Build/Editor/Smoothing Utils.h [new file with mode: 0644]
ja2/Build/Editor/Summary Info.h [new file with mode: 0644]
ja2/Build/Editor/edit_sys.c [new file with mode: 0644]
ja2/Build/Editor/edit_sys.h [new file with mode: 0644]
ja2/Build/Editor/editscreen.c [new file with mode: 0644]
ja2/Build/Editor/editscreen.h [new file with mode: 0644]
ja2/Build/Editor/messagebox.c [new file with mode: 0644]
ja2/Build/Editor/messagebox.h [new file with mode: 0644]
ja2/Build/Editor/newsmooth.c [new file with mode: 0644]
ja2/Build/Editor/newsmooth.h [new file with mode: 0644]
ja2/Build/Editor/popupmenu.c [new file with mode: 0644]
ja2/Build/Editor/popupmenu.h [new file with mode: 0644]
ja2/Build/Editor/selectwin.c [new file with mode: 0644]
ja2/Build/Editor/selectwin.h [new file with mode: 0644]
ja2/Build/Editor/smooth.c [new file with mode: 0644]
ja2/Build/Editor/smooth.h [new file with mode: 0644]
ja2/Build/Fade Screen.c [new file with mode: 0644]
ja2/Build/Fade Screen.h [new file with mode: 0644]
ja2/Build/GameInitOptionsScreen.c [new file with mode: 0644]
ja2/Build/GameInitOptionsScreen.h [new file with mode: 0644]
ja2/Build/GameSettings.c [new file with mode: 0644]
ja2/Build/GameSettings.h [new file with mode: 0644]
ja2/Build/GameVersion.c [new file with mode: 0644]
ja2/Build/GameVersion.h [new file with mode: 0644]
ja2/Build/HelpScreen.c [new file with mode: 0644]
ja2/Build/HelpScreen.h [new file with mode: 0644]
ja2/Build/HelpScreenText.h [new file with mode: 0644]
ja2/Build/Init.c [new file with mode: 0644]
ja2/Build/Init.h [new file with mode: 0644]
ja2/Build/Intro.c [new file with mode: 0644]
ja2/Build/Intro.h [new file with mode: 0644]
ja2/Build/JA2 All.h [new file with mode: 0644]
ja2/Build/JA2 Demo Ads.h [new file with mode: 0644]
ja2/Build/JA2 Splash.c [new file with mode: 0644]
ja2/Build/JA2 Splash.h [new file with mode: 0644]
ja2/Build/JA2.dsp [new file with mode: 0644]
ja2/Build/JA2.dsw [new file with mode: 0644]
ja2/Build/JA2.ncb [new file with mode: 0644]
ja2/Build/JA2.opt [new file with mode: 0644]
ja2/Build/Language Defines.h [new file with mode: 0644]
ja2/Build/Laptop/AimArchives.c [new file with mode: 0644]
ja2/Build/Laptop/AimArchives.h [new file with mode: 0644]
ja2/Build/Laptop/AimFacialIndex.c [new file with mode: 0644]
ja2/Build/Laptop/AimFacialIndex.h [new file with mode: 0644]
ja2/Build/Laptop/AimHistory.c [new file with mode: 0644]
ja2/Build/Laptop/AimHistory.h [new file with mode: 0644]
ja2/Build/Laptop/AimLinks.c [new file with mode: 0644]
ja2/Build/Laptop/AimLinks.h [new file with mode: 0644]
ja2/Build/Laptop/AimMembers.c [new file with mode: 0644]
ja2/Build/Laptop/AimMembers.h [new file with mode: 0644]
ja2/Build/Laptop/AimPolicies.c [new file with mode: 0644]
ja2/Build/Laptop/AimPolicies.h [new file with mode: 0644]
ja2/Build/Laptop/AimSort.c [new file with mode: 0644]
ja2/Build/Laptop/AimSort.h [new file with mode: 0644]
ja2/Build/Laptop/BobbyR.c [new file with mode: 0644]
ja2/Build/Laptop/BobbyR.h [new file with mode: 0644]
ja2/Build/Laptop/BobbyRAmmo.c [new file with mode: 0644]
ja2/Build/Laptop/BobbyRAmmo.h [new file with mode: 0644]
ja2/Build/Laptop/BobbyRArmour.c [new file with mode: 0644]
ja2/Build/Laptop/BobbyRArmour.h [new file with mode: 0644]
ja2/Build/Laptop/BobbyRGuns.c [new file with mode: 0644]
ja2/Build/Laptop/BobbyRGuns.h [new file with mode: 0644]
ja2/Build/Laptop/BobbyRMailOrder.c [new file with mode: 0644]
ja2/Build/Laptop/BobbyRMailOrder.h [new file with mode: 0644]
ja2/Build/Laptop/BobbyRMisc.c [new file with mode: 0644]
ja2/Build/Laptop/BobbyRMisc.h [new file with mode: 0644]
ja2/Build/Laptop/BobbyRShipments.c [new file with mode: 0644]
ja2/Build/Laptop/BobbyRShipments.h [new file with mode: 0644]
ja2/Build/Laptop/BobbyRUsed.c [new file with mode: 0644]
ja2/Build/Laptop/BobbyRUsed.h [new file with mode: 0644]
ja2/Build/Laptop/BrokenLink.c [new file with mode: 0644]
ja2/Build/Laptop/BrokenLink.h [new file with mode: 0644]
ja2/Build/Laptop/CharProfile.c [new file with mode: 0644]
ja2/Build/Laptop/CharProfile.h [new file with mode: 0644]
ja2/Build/Laptop/GunEmporium.c [new file with mode: 0644]
ja2/Build/Laptop/GunEmporium.h [new file with mode: 0644]
ja2/Build/Laptop/IMP AboutUs.c [new file with mode: 0644]
ja2/Build/Laptop/IMP AboutUs.h [new file with mode: 0644]
ja2/Build/Laptop/IMP Attribute Entrance.c [new file with mode: 0644]
ja2/Build/Laptop/IMP Attribute Entrance.h [new file with mode: 0644]
ja2/Build/Laptop/IMP Attribute Finish.c [new file with mode: 0644]
ja2/Build/Laptop/IMP Attribute Finish.h [new file with mode: 0644]
ja2/Build/Laptop/IMP Attribute Selection.c [new file with mode: 0644]
ja2/Build/Laptop/IMP Attribute Selection.h [new file with mode: 0644]
ja2/Build/Laptop/IMP Begin Screen.c [new file with mode: 0644]
ja2/Build/Laptop/IMP Begin Screen.h [new file with mode: 0644]
ja2/Build/Laptop/IMP Compile Character.c [new file with mode: 0644]
ja2/Build/Laptop/IMP Compile Character.h [new file with mode: 0644]
ja2/Build/Laptop/IMP Confirm.c [new file with mode: 0644]
ja2/Build/Laptop/IMP Confirm.h [new file with mode: 0644]
ja2/Build/Laptop/IMP Finish.c [new file with mode: 0644]
ja2/Build/Laptop/IMP Finish.h [new file with mode: 0644]
ja2/Build/Laptop/IMP HomePage.c [new file with mode: 0644]
ja2/Build/Laptop/IMP HomePage.h [new file with mode: 0644]
ja2/Build/Laptop/IMP MainPage.c [new file with mode: 0644]
ja2/Build/Laptop/IMP MainPage.h [new file with mode: 0644]
ja2/Build/Laptop/IMP Personality Entrance.c [new file with mode: 0644]
ja2/Build/Laptop/IMP Personality Entrance.h [new file with mode: 0644]
ja2/Build/Laptop/IMP Personality Finish.c [new file with mode: 0644]
ja2/Build/Laptop/IMP Personality Finish.h [new file with mode: 0644]
ja2/Build/Laptop/IMP Personality Quiz.c [new file with mode: 0644]
ja2/Build/Laptop/IMP Personality Quiz.h [new file with mode: 0644]
ja2/Build/Laptop/IMP Portraits.c [new file with mode: 0644]
ja2/Build/Laptop/IMP Portraits.h [new file with mode: 0644]
ja2/Build/Laptop/IMP Text System.c [new file with mode: 0644]
ja2/Build/Laptop/IMP Text System.h [new file with mode: 0644]
ja2/Build/Laptop/IMP Voices.c [new file with mode: 0644]
ja2/Build/Laptop/IMP Voices.h [new file with mode: 0644]
ja2/Build/Laptop/IMPVideoObjects.c [new file with mode: 0644]
ja2/Build/Laptop/IMPVideoObjects.h [new file with mode: 0644]
ja2/Build/Laptop/Insurance Text.h [new file with mode: 0644]
ja2/Build/Laptop/Laptop All.h [new file with mode: 0644]
ja2/Build/Laptop/Laptop.dsp [new file with mode: 0644]
ja2/Build/Laptop/LaptopSave.h [new file with mode: 0644]
ja2/Build/Laptop/Speck Quotes.h [new file with mode: 0644]
ja2/Build/Laptop/Store Inventory.c [new file with mode: 0644]
ja2/Build/Laptop/Store Inventory.h [new file with mode: 0644]
ja2/Build/Laptop/aim.c [new file with mode: 0644]
ja2/Build/Laptop/aim.h [new file with mode: 0644]
ja2/Build/Laptop/email.c [new file with mode: 0644]
ja2/Build/Laptop/email.h [new file with mode: 0644]
ja2/Build/Laptop/files.c [new file with mode: 0644]
ja2/Build/Laptop/files.h [new file with mode: 0644]
ja2/Build/Laptop/finances.c [new file with mode: 0644]
ja2/Build/Laptop/finances.h [new file with mode: 0644]
ja2/Build/Laptop/florist Cards.c [new file with mode: 0644]
ja2/Build/Laptop/florist Cards.h [new file with mode: 0644]
ja2/Build/Laptop/florist Gallery.c [new file with mode: 0644]
ja2/Build/Laptop/florist Gallery.h [new file with mode: 0644]
ja2/Build/Laptop/florist Order Form.c [new file with mode: 0644]
ja2/Build/Laptop/florist Order Form.h [new file with mode: 0644]
ja2/Build/Laptop/florist.c [new file with mode: 0644]
ja2/Build/Laptop/florist.h [new file with mode: 0644]
ja2/Build/Laptop/funeral.c [new file with mode: 0644]
ja2/Build/Laptop/funeral.h [new file with mode: 0644]
ja2/Build/Laptop/history.c [new file with mode: 0644]
ja2/Build/Laptop/history.h [new file with mode: 0644]
ja2/Build/Laptop/insurance Comments.c [new file with mode: 0644]
ja2/Build/Laptop/insurance Comments.h [new file with mode: 0644]
ja2/Build/Laptop/insurance Contract.c [new file with mode: 0644]
ja2/Build/Laptop/insurance Contract.h [new file with mode: 0644]
ja2/Build/Laptop/insurance Info.c [new file with mode: 0644]
ja2/Build/Laptop/insurance Info.h [new file with mode: 0644]
ja2/Build/Laptop/insurance.c [new file with mode: 0644]
ja2/Build/Laptop/insurance.h [new file with mode: 0644]
ja2/Build/Laptop/laptop.c [new file with mode: 0644]
ja2/Build/Laptop/laptop.h [new file with mode: 0644]
ja2/Build/Laptop/mercs Account.c [new file with mode: 0644]
ja2/Build/Laptop/mercs Account.h [new file with mode: 0644]
ja2/Build/Laptop/mercs Files.c [new file with mode: 0644]
ja2/Build/Laptop/mercs Files.h [new file with mode: 0644]
ja2/Build/Laptop/mercs No Account.c [new file with mode: 0644]
ja2/Build/Laptop/mercs No Account.h [new file with mode: 0644]
ja2/Build/Laptop/mercs.c [new file with mode: 0644]
ja2/Build/Laptop/mercs.h [new file with mode: 0644]
ja2/Build/Laptop/personnel.c [new file with mode: 0644]
ja2/Build/Laptop/personnel.h [new file with mode: 0644]
ja2/Build/Laptop/sirtech.c [new file with mode: 0644]
ja2/Build/Laptop/sirtech.h [new file with mode: 0644]
ja2/Build/Loading Screen.c [new file with mode: 0644]
ja2/Build/Loading Screen.h [new file with mode: 0644]
ja2/Build/MainMenuScreen.c [new file with mode: 0644]
ja2/Build/MessageBoxScreen.c [new file with mode: 0644]
ja2/Build/MessageBoxScreen.h [new file with mode: 0644]
ja2/Build/Options Screen.c [new file with mode: 0644]
ja2/Build/Options Screen.h [new file with mode: 0644]
ja2/Build/Res/ja2.rc [new file with mode: 0644]
ja2/Build/Res/jagged3.ico [new file with mode: 0644]
ja2/Build/Res/resource.h [new file with mode: 0644]
ja2/Build/SCREENS.C [new file with mode: 0644]
ja2/Build/SCREENS.H [new file with mode: 0644]
ja2/Build/SaveLoadGame.c [new file with mode: 0644]
ja2/Build/SaveLoadGame.h [new file with mode: 0644]
ja2/Build/SaveLoadScreen.c [new file with mode: 0644]
ja2/Build/SaveLoadScreen.h [new file with mode: 0644]
ja2/Build/Strategic/AI Viewer.c [new file with mode: 0644]
ja2/Build/Strategic/Assignments.c [new file with mode: 0644]
ja2/Build/Strategic/Assignments.h [new file with mode: 0644]
ja2/Build/Strategic/Auto Resolve.c [new file with mode: 0644]
ja2/Build/Strategic/Auto Resolve.h [new file with mode: 0644]
ja2/Build/Strategic/Campaign Init.c [new file with mode: 0644]
ja2/Build/Strategic/Campaign Init.h [new file with mode: 0644]
ja2/Build/Strategic/Campaign Types.h [new file with mode: 0644]
ja2/Build/Strategic/Creature Spreading.c [new file with mode: 0644]
ja2/Build/Strategic/Creature Spreading.h [new file with mode: 0644]
ja2/Build/Strategic/Game Clock.c [new file with mode: 0644]
ja2/Build/Strategic/Game Clock.h [new file with mode: 0644]
ja2/Build/Strategic/Game Event Hook.c [new file with mode: 0644]
ja2/Build/Strategic/Game Event Hook.h [new file with mode: 0644]
ja2/Build/Strategic/Game Events.c [new file with mode: 0644]
ja2/Build/Strategic/Game Events.h [new file with mode: 0644]
ja2/Build/Strategic/Game Init.c [new file with mode: 0644]
ja2/Build/Strategic/Game Init.h [new file with mode: 0644]
ja2/Build/Strategic/Hourly Update.c [new file with mode: 0644]
ja2/Build/Strategic/Map Screen Helicopter.c [new file with mode: 0644]
ja2/Build/Strategic/Map Screen Helicopter.h [new file with mode: 0644]
ja2/Build/Strategic/Map Screen Interface Border.c [new file with mode: 0644]
ja2/Build/Strategic/Map Screen Interface Border.h [new file with mode: 0644]
ja2/Build/Strategic/Map Screen Interface Bottom.c [new file with mode: 0644]
ja2/Build/Strategic/Map Screen Interface Bottom.h [new file with mode: 0644]
ja2/Build/Strategic/Map Screen Interface Map Inventory.c [new file with mode: 0644]
ja2/Build/Strategic/Map Screen Interface Map Inventory.h [new file with mode: 0644]
ja2/Build/Strategic/Map Screen Interface Map.c [new file with mode: 0644]
ja2/Build/Strategic/Map Screen Interface Map.h [new file with mode: 0644]
ja2/Build/Strategic/Map Screen Interface TownMine Info.c [new file with mode: 0644]
ja2/Build/Strategic/Map Screen Interface TownMine Info.h [new file with mode: 0644]
ja2/Build/Strategic/Map Screen Interface.c [new file with mode: 0644]
ja2/Build/Strategic/Map Screen Interface.h [new file with mode: 0644]
ja2/Build/Strategic/Meanwhile.c [new file with mode: 0644]
ja2/Build/Strategic/Meanwhile.h [new file with mode: 0644]
ja2/Build/Strategic/Merc Contract.c [new file with mode: 0644]
ja2/Build/Strategic/Merc Contract.h [new file with mode: 0644]
ja2/Build/Strategic/Player Command.c [new file with mode: 0644]
ja2/Build/Strategic/Player Command.h [new file with mode: 0644]
ja2/Build/Strategic/PreBattle Interface.c [new file with mode: 0644]
ja2/Build/Strategic/PreBattle Interface.h [new file with mode: 0644]
ja2/Build/Strategic/Queen Command.c [new file with mode: 0644]
ja2/Build/Strategic/Queen Command.h [new file with mode: 0644]
ja2/Build/Strategic/Quest Debug System.c [new file with mode: 0644]
ja2/Build/Strategic/Quest Debug System.h [new file with mode: 0644]
ja2/Build/Strategic/QuestText.c [new file with mode: 0644]
ja2/Build/Strategic/QuestText.h [new file with mode: 0644]
ja2/Build/Strategic/Quests.c [new file with mode: 0644]
ja2/Build/Strategic/Quests.h [new file with mode: 0644]
ja2/Build/Strategic/Scheduling.c [new file with mode: 0644]
ja2/Build/Strategic/Scheduling.h [new file with mode: 0644]
ja2/Build/Strategic/Strategic AI.c [new file with mode: 0644]
ja2/Build/Strategic/Strategic AI.h [new file with mode: 0644]
ja2/Build/Strategic/Strategic All.h [new file with mode: 0644]
ja2/Build/Strategic/Strategic Event Handler.c [new file with mode: 0644]
ja2/Build/Strategic/Strategic Event Handler.h [new file with mode: 0644]
ja2/Build/Strategic/Strategic Merc Handler.c [new file with mode: 0644]
ja2/Build/Strategic/Strategic Merc Handler.h [new file with mode: 0644]
ja2/Build/Strategic/Strategic Mines.c [new file with mode: 0644]
ja2/Build/Strategic/Strategic Mines.h [new file with mode: 0644]
ja2/Build/Strategic/Strategic Movement Costs.c [new file with mode: 0644]
ja2/Build/Strategic/Strategic Movement.c [new file with mode: 0644]
ja2/Build/Strategic/Strategic Movement.h [new file with mode: 0644]
ja2/Build/Strategic/Strategic Pathing.c [new file with mode: 0644]
ja2/Build/Strategic/Strategic Pathing.h [new file with mode: 0644]
ja2/Build/Strategic/Strategic Status.c [new file with mode: 0644]
ja2/Build/Strategic/Strategic Status.h [new file with mode: 0644]
ja2/Build/Strategic/Strategic Town Loyalty.c [new file with mode: 0644]
ja2/Build/Strategic/Strategic Town Loyalty.h [new file with mode: 0644]
ja2/Build/Strategic/Strategic Turns.c [new file with mode: 0644]
ja2/Build/Strategic/Strategic Turns.h [new file with mode: 0644]
ja2/Build/Strategic/Strategic.dsp [new file with mode: 0644]
ja2/Build/Strategic/Town Militia.c [new file with mode: 0644]
ja2/Build/Strategic/Town Militia.h [new file with mode: 0644]
ja2/Build/Strategic/mapscreen.c [new file with mode: 0644]
ja2/Build/Strategic/mapscreen.h [new file with mode: 0644]
ja2/Build/Strategic/strategic town reputation.c [new file with mode: 0644]
ja2/Build/Strategic/strategic town reputation.h [new file with mode: 0644]
ja2/Build/Strategic/strategic.c [new file with mode: 0644]
ja2/Build/Strategic/strategic.h [new file with mode: 0644]
ja2/Build/Strategic/strategicmap.c [new file with mode: 0644]
ja2/Build/Strategic/strategicmap.h [new file with mode: 0644]
ja2/Build/Sys Globals.c [new file with mode: 0644]
ja2/Build/Sys Globals.h [new file with mode: 0644]
ja2/Build/Tactical/Action Items.h [new file with mode: 0644]
ja2/Build/Tactical/Air Raid.c [new file with mode: 0644]
ja2/Build/Tactical/Air Raid.h [new file with mode: 0644]
ja2/Build/Tactical/Animation Cache.c [new file with mode: 0644]
ja2/Build/Tactical/Animation Cache.h [new file with mode: 0644]
ja2/Build/Tactical/Animation Control.c [new file with mode: 0644]
ja2/Build/Tactical/Animation Control.h [new file with mode: 0644]
ja2/Build/Tactical/Animation Data.c [new file with mode: 0644]
ja2/Build/Tactical/Animation Data.h [new file with mode: 0644]
ja2/Build/Tactical/Arms Dealer Init.c [new file with mode: 0644]
ja2/Build/Tactical/Arms Dealer Init.h [new file with mode: 0644]
ja2/Build/Tactical/ArmsDealerInvInit.c [new file with mode: 0644]
ja2/Build/Tactical/ArmsDealerInvInit.h [new file with mode: 0644]
ja2/Build/Tactical/Auto Bandage.c [new file with mode: 0644]
ja2/Build/Tactical/Auto Bandage.h [new file with mode: 0644]
ja2/Build/Tactical/Boxing.c [new file with mode: 0644]
ja2/Build/Tactical/Boxing.h [new file with mode: 0644]
ja2/Build/Tactical/Bullets.h [new file with mode: 0644]
ja2/Build/Tactical/Campaign.c [new file with mode: 0644]
ja2/Build/Tactical/Campaign.h [new file with mode: 0644]
ja2/Build/Tactical/Civ Quotes.c [new file with mode: 0644]
ja2/Build/Tactical/Civ Quotes.h [new file with mode: 0644]
ja2/Build/Tactical/Dialogue Control.c [new file with mode: 0644]
ja2/Build/Tactical/Dialogue Control.h [new file with mode: 0644]
ja2/Build/Tactical/DisplayCover.c [new file with mode: 0644]
ja2/Build/Tactical/DisplayCover.h [new file with mode: 0644]
ja2/Build/Tactical/Drugs And Alcohol.c [new file with mode: 0644]
ja2/Build/Tactical/Drugs And Alcohol.h [new file with mode: 0644]
ja2/Build/Tactical/End Game.c [new file with mode: 0644]
ja2/Build/Tactical/End Game.h [new file with mode: 0644]
ja2/Build/Tactical/Enemy Soldier Save.c [new file with mode: 0644]
ja2/Build/Tactical/Enemy Soldier Save.h [new file with mode: 0644]
ja2/Build/Tactical/Faces.c [new file with mode: 0644]
ja2/Build/Tactical/GAP.C [new file with mode: 0644]
ja2/Build/Tactical/GAP.H [new file with mode: 0644]
ja2/Build/Tactical/Handle Doors.c [new file with mode: 0644]
ja2/Build/Tactical/Handle Doors.h [new file with mode: 0644]
ja2/Build/Tactical/Handle Items.c [new file with mode: 0644]
ja2/Build/Tactical/Handle Items.h [new file with mode: 0644]
ja2/Build/Tactical/Handle UI Plan.c [new file with mode: 0644]
ja2/Build/Tactical/Handle UI Plan.h [new file with mode: 0644]
ja2/Build/Tactical/Handle UI.c [new file with mode: 0644]
ja2/Build/Tactical/Handle UI.h [new file with mode: 0644]
ja2/Build/Tactical/Interface Control.c [new file with mode: 0644]
ja2/Build/Tactical/Interface Control.h [new file with mode: 0644]
ja2/Build/Tactical/Interface Cursors.c [new file with mode: 0644]
ja2/Build/Tactical/Interface Cursors.h [new file with mode: 0644]
ja2/Build/Tactical/Interface Dialogue.c [new file with mode: 0644]
ja2/Build/Tactical/Interface Items.c [new file with mode: 0644]
ja2/Build/Tactical/Interface Items.h [new file with mode: 0644]
ja2/Build/Tactical/Interface Panels.c [new file with mode: 0644]
ja2/Build/Tactical/Interface Panels.h [new file with mode: 0644]
ja2/Build/Tactical/Interface Utils.c [new file with mode: 0644]
ja2/Build/Tactical/Interface Utils.h [new file with mode: 0644]
ja2/Build/Tactical/Interface.c [new file with mode: 0644]
ja2/Build/Tactical/Interface.h [new file with mode: 0644]
ja2/Build/Tactical/Inventory Choosing.c [new file with mode: 0644]
ja2/Build/Tactical/Inventory Choosing.h [new file with mode: 0644]
ja2/Build/Tactical/Item Types.h [new file with mode: 0644]
ja2/Build/Tactical/Items.c [new file with mode: 0644]
ja2/Build/Tactical/Items.h [new file with mode: 0644]
ja2/Build/Tactical/Keys.c [new file with mode: 0644]
ja2/Build/Tactical/Keys.h [new file with mode: 0644]
ja2/Build/Tactical/LOS.c [new file with mode: 0644]
ja2/Build/Tactical/LOS.h [new file with mode: 0644]
ja2/Build/Tactical/Map Information.c [new file with mode: 0644]
ja2/Build/Tactical/Map Information.h [new file with mode: 0644]
ja2/Build/Tactical/Merc Entering.c [new file with mode: 0644]
ja2/Build/Tactical/Merc Hiring.c [new file with mode: 0644]
ja2/Build/Tactical/Merc Hiring.h [new file with mode: 0644]
ja2/Build/Tactical/Militia Control.c [new file with mode: 0644]
ja2/Build/Tactical/Militia Control.h [new file with mode: 0644]
ja2/Build/Tactical/Morale.c [new file with mode: 0644]
ja2/Build/Tactical/Morale.h [new file with mode: 0644]
ja2/Build/Tactical/Overhead Types.h [new file with mode: 0644]
ja2/Build/Tactical/Overhead.c [new file with mode: 0644]
ja2/Build/Tactical/Overhead.h [new file with mode: 0644]
ja2/Build/Tactical/PATHAI.C [new file with mode: 0644]
ja2/Build/Tactical/PATHAI.H [new file with mode: 0644]
ja2/Build/Tactical/PathAIDebug.h [new file with mode: 0644]
ja2/Build/Tactical/Points.c [new file with mode: 0644]
ja2/Build/Tactical/Points.h [new file with mode: 0644]
ja2/Build/Tactical/QARRAY.C [new file with mode: 0644]
ja2/Build/Tactical/Real Time Input.c [new file with mode: 0644]
ja2/Build/Tactical/Rotting Corpses.c [new file with mode: 0644]
ja2/Build/Tactical/Rotting Corpses.h [new file with mode: 0644]
ja2/Build/Tactical/ShopKeeper Interface.c [new file with mode: 0644]
ja2/Build/Tactical/ShopKeeper Interface.h [new file with mode: 0644]
ja2/Build/Tactical/ShopKeeper Quotes.h [new file with mode: 0644]
ja2/Build/Tactical/SkillCheck.c [new file with mode: 0644]
ja2/Build/Tactical/SkillCheck.h [new file with mode: 0644]
ja2/Build/Tactical/Soldier Add.c [new file with mode: 0644]
ja2/Build/Tactical/Soldier Add.h [new file with mode: 0644]
ja2/Build/Tactical/Soldier Ani.c [new file with mode: 0644]
ja2/Build/Tactical/Soldier Ani.h [new file with mode: 0644]
ja2/Build/Tactical/Soldier Control.c [new file with mode: 0644]
ja2/Build/Tactical/Soldier Control.h [new file with mode: 0644]
ja2/Build/Tactical/Soldier Create.c [new file with mode: 0644]
ja2/Build/Tactical/Soldier Create.h [new file with mode: 0644]
ja2/Build/Tactical/Soldier Find.c [new file with mode: 0644]
ja2/Build/Tactical/Soldier Find.h [new file with mode: 0644]
ja2/Build/Tactical/Soldier Functions.h [new file with mode: 0644]
ja2/Build/Tactical/Soldier Init List.c [new file with mode: 0644]
ja2/Build/Tactical/Soldier Init List.h [new file with mode: 0644]
ja2/Build/Tactical/Soldier Profile.c [new file with mode: 0644]
ja2/Build/Tactical/Soldier Profile.h [new file with mode: 0644]
ja2/Build/Tactical/Soldier Tile.c [new file with mode: 0644]
ja2/Build/Tactical/Soldier macros.h [new file with mode: 0644]
ja2/Build/Tactical/Spread Burst.c [new file with mode: 0644]
ja2/Build/Tactical/Spread burst.h [new file with mode: 0644]
ja2/Build/Tactical/Squads.c [new file with mode: 0644]
ja2/Build/Tactical/Squads.h [new file with mode: 0644]
ja2/Build/Tactical/Strategic Exit GUI.c [new file with mode: 0644]
ja2/Build/Tactical/Strategic Exit GUI.h [new file with mode: 0644]
ja2/Build/Tactical/Structure Wrap.c [new file with mode: 0644]
ja2/Build/Tactical/Structure Wrap.h [new file with mode: 0644]
ja2/Build/Tactical/Tactical All.h [new file with mode: 0644]
ja2/Build/Tactical/Tactical Save.c [new file with mode: 0644]
ja2/Build/Tactical/Tactical Save.h [new file with mode: 0644]
ja2/Build/Tactical/Tactical Turns.c [new file with mode: 0644]
ja2/Build/Tactical/Tactical Turns.h [new file with mode: 0644]
ja2/Build/Tactical/Tactical.dsp [new file with mode: 0644]
ja2/Build/Tactical/TeamTurns.c [new file with mode: 0644]
ja2/Build/Tactical/TeamTurns.h [new file with mode: 0644]
ja2/Build/Tactical/Turn Based Input.c [new file with mode: 0644]
ja2/Build/Tactical/UI Cursors.c [new file with mode: 0644]
ja2/Build/Tactical/UI Cursors.h [new file with mode: 0644]
ja2/Build/Tactical/Vehicles.c [new file with mode: 0644]
ja2/Build/Tactical/Vehicles.h [new file with mode: 0644]
ja2/Build/Tactical/Weapons.c [new file with mode: 0644]
ja2/Build/Tactical/Weapons.h [new file with mode: 0644]
ja2/Build/Tactical/World Items.c [new file with mode: 0644]
ja2/Build/Tactical/World Items.h [new file with mode: 0644]
ja2/Build/Tactical/bullets.c [new file with mode: 0644]
ja2/Build/Tactical/faces.h [new file with mode: 0644]
ja2/Build/Tactical/fov.c [new file with mode: 0644]
ja2/Build/Tactical/fov.h [new file with mode: 0644]
ja2/Build/Tactical/interface Dialogue.h [new file with mode: 0644]
ja2/Build/Tactical/merc entering.h [new file with mode: 0644]
ja2/Build/Tactical/opplist.c [new file with mode: 0644]
ja2/Build/Tactical/opplist.h [new file with mode: 0644]
ja2/Build/Tactical/qarray.h [new file with mode: 0644]
ja2/Build/Tactical/rt time defines.h [new file with mode: 0644]
ja2/Build/Tactical/soldier profile type.h [new file with mode: 0644]
ja2/Build/Tactical/soldier tile.h [new file with mode: 0644]
ja2/Build/TacticalAI/AI All.h [new file with mode: 0644]
ja2/Build/TacticalAI/AIInternals.h [new file with mode: 0644]
ja2/Build/TacticalAI/AIList.c [new file with mode: 0644]
ja2/Build/TacticalAI/AIList.h [new file with mode: 0644]
ja2/Build/TacticalAI/AIMain.c [new file with mode: 0644]
ja2/Build/TacticalAI/AIUtils.c [new file with mode: 0644]
ja2/Build/TacticalAI/Attacks.c [new file with mode: 0644]
ja2/Build/TacticalAI/CreatureDecideAction.c [new file with mode: 0644]
ja2/Build/TacticalAI/DecideAction.c [new file with mode: 0644]
ja2/Build/TacticalAI/FindLocations.c [new file with mode: 0644]
ja2/Build/TacticalAI/Knowledge.c [new file with mode: 0644]
ja2/Build/TacticalAI/Medical.c [new file with mode: 0644]
ja2/Build/TacticalAI/Movement.c [new file with mode: 0644]
ja2/Build/TacticalAI/NPC.c [new file with mode: 0644]
ja2/Build/TacticalAI/NPC.h [new file with mode: 0644]
ja2/Build/TacticalAI/PanicButtons.c [new file with mode: 0644]
ja2/Build/TacticalAI/QuestDebug.c [new file with mode: 0644]
ja2/Build/TacticalAI/QuestDebug.h [new file with mode: 0644]
ja2/Build/TacticalAI/Realtime.c [new file with mode: 0644]
ja2/Build/TacticalAI/TacticalAI.dsp [new file with mode: 0644]
ja2/Build/TacticalAI/ai.h [new file with mode: 0644]
ja2/Build/TileEngine/Ambient Control.c [new file with mode: 0644]
ja2/Build/TileEngine/Ambient Control.h [new file with mode: 0644]
ja2/Build/TileEngine/Ambient Types.h [new file with mode: 0644]
ja2/Build/TileEngine/Buildings.c [new file with mode: 0644]
ja2/Build/TileEngine/Buildings.h [new file with mode: 0644]
ja2/Build/TileEngine/Exit Grids.c [new file with mode: 0644]
ja2/Build/TileEngine/Exit Grids.h [new file with mode: 0644]
ja2/Build/TileEngine/Explosion Control.c [new file with mode: 0644]
ja2/Build/TileEngine/Explosion Control.h [new file with mode: 0644]
ja2/Build/TileEngine/Fog Of War.c [new file with mode: 0644]
ja2/Build/TileEngine/Fog Of War.h [new file with mode: 0644]
ja2/Build/TileEngine/Interactive Tiles.c [new file with mode: 0644]
ja2/Build/TileEngine/Interactive Tiles.h [new file with mode: 0644]
ja2/Build/TileEngine/Isometric Utils.c [new file with mode: 0644]
ja2/Build/TileEngine/Isometric Utils.h [new file with mode: 0644]
ja2/Build/TileEngine/LightEffects.c [new file with mode: 0644]
ja2/Build/TileEngine/LightEffects.h [new file with mode: 0644]
ja2/Build/TileEngine/Map Edgepoints.c [new file with mode: 0644]
ja2/Build/TileEngine/Map Edgepoints.h [new file with mode: 0644]
ja2/Build/TileEngine/Radar Screen.c [new file with mode: 0644]
ja2/Build/TileEngine/Radar Screen.h [new file with mode: 0644]
ja2/Build/TileEngine/Render Dirty.c [new file with mode: 0644]
ja2/Build/TileEngine/Render Dirty.h [new file with mode: 0644]
ja2/Build/TileEngine/Render Fun.c [new file with mode: 0644]
ja2/Build/TileEngine/Render Fun.h [new file with mode: 0644]
ja2/Build/TileEngine/Render Z.c [new file with mode: 0644]
ja2/Build/TileEngine/SaveLoadMap.c [new file with mode: 0644]
ja2/Build/TileEngine/SaveLoadMap.h [new file with mode: 0644]
ja2/Build/TileEngine/Shade Table Util.c [new file with mode: 0644]
ja2/Build/TileEngine/Shade Table Util.h [new file with mode: 0644]
ja2/Build/TileEngine/Simple Render Utils.c [new file with mode: 0644]
ja2/Build/TileEngine/Simple Render Utils.h [new file with mode: 0644]
ja2/Build/TileEngine/Smell.c [new file with mode: 0644]
ja2/Build/TileEngine/Smell.h [new file with mode: 0644]
ja2/Build/TileEngine/SmokeEffects.c [new file with mode: 0644]
ja2/Build/TileEngine/SmokeEffects.h [new file with mode: 0644]
ja2/Build/TileEngine/Structure Internals.h [new file with mode: 0644]
ja2/Build/TileEngine/Tactical Placement GUI.c [new file with mode: 0644]
ja2/Build/TileEngine/Tactical Placement GUI.h [new file with mode: 0644]
ja2/Build/TileEngine/Tile Animation.c [new file with mode: 0644]
ja2/Build/TileEngine/Tile Animation.h [new file with mode: 0644]
ja2/Build/TileEngine/Tile Cache.c [new file with mode: 0644]
ja2/Build/TileEngine/Tile Cache.h [new file with mode: 0644]
ja2/Build/TileEngine/Tile Surface.c [new file with mode: 0644]
ja2/Build/TileEngine/Tile Surface.h [new file with mode: 0644]
ja2/Build/TileEngine/TileDat.c [new file with mode: 0644]
ja2/Build/TileEngine/TileDat.h [new file with mode: 0644]
ja2/Build/TileEngine/TileEngine All.h [new file with mode: 0644]
ja2/Build/TileEngine/TileEngine.dsp [new file with mode: 0644]
ja2/Build/TileEngine/World Tileset Enums.h [new file with mode: 0644]
ja2/Build/TileEngine/WorldDat.c [new file with mode: 0644]
ja2/Build/TileEngine/WorldDat.h [new file with mode: 0644]
ja2/Build/TileEngine/environment.c [new file with mode: 0644]
ja2/Build/TileEngine/environment.h [new file with mode: 0644]
ja2/Build/TileEngine/lighting.c [new file with mode: 0644]
ja2/Build/TileEngine/lighting.h [new file with mode: 0644]
ja2/Build/TileEngine/overhead map.c [new file with mode: 0644]
ja2/Build/TileEngine/overhead map.h [new file with mode: 0644]
ja2/Build/TileEngine/phys math.c [new file with mode: 0644]
ja2/Build/TileEngine/phys math.h [new file with mode: 0644]
ja2/Build/TileEngine/physics.c [new file with mode: 0644]
ja2/Build/TileEngine/physics.h [new file with mode: 0644]
ja2/Build/TileEngine/pits.c [new file with mode: 0644]
ja2/Build/TileEngine/pits.h [new file with mode: 0644]
ja2/Build/TileEngine/renderworld.c [new file with mode: 0644]
ja2/Build/TileEngine/renderworld.h [new file with mode: 0644]
ja2/Build/TileEngine/structure.c [new file with mode: 0644]
ja2/Build/TileEngine/structure.h [new file with mode: 0644]
ja2/Build/TileEngine/sysutil.c [new file with mode: 0644]
ja2/Build/TileEngine/sysutil.h [new file with mode: 0644]
ja2/Build/TileEngine/tiledef.c [new file with mode: 0644]
ja2/Build/TileEngine/tiledef.h [new file with mode: 0644]
ja2/Build/TileEngine/worlddef.c [new file with mode: 0644]
ja2/Build/TileEngine/worlddef.h [new file with mode: 0644]
ja2/Build/TileEngine/worldman.c [new file with mode: 0644]
ja2/Build/TileEngine/worldman.h [new file with mode: 0644]
ja2/Build/Utils/Animated ProgressBar.c [new file with mode: 0644]
ja2/Build/Utils/Animated ProgressBar.h [new file with mode: 0644]
ja2/Build/Utils/Cinematics.c [new file with mode: 0644]
ja2/Build/Utils/Cinematics.h [new file with mode: 0644]
ja2/Build/Utils/Cursors.c [new file with mode: 0644]
ja2/Build/Utils/Cursors.h [new file with mode: 0644]
ja2/Build/Utils/Debug Control.c [new file with mode: 0644]
ja2/Build/Utils/Debug Control.h [new file with mode: 0644]
ja2/Build/Utils/Encrypted File.c [new file with mode: 0644]
ja2/Build/Utils/Encrypted File.h [new file with mode: 0644]
ja2/Build/Utils/Event Manager.c [new file with mode: 0644]
ja2/Build/Utils/Event Manager.h [new file with mode: 0644]
ja2/Build/Utils/Event Pump.c [new file with mode: 0644]
ja2/Build/Utils/Event Pump.h [new file with mode: 0644]
ja2/Build/Utils/Font Control.c [new file with mode: 0644]
ja2/Build/Utils/Font Control.h [new file with mode: 0644]
ja2/Build/Utils/MapUtility.c [new file with mode: 0644]
ja2/Build/Utils/MercTextBox.c [new file with mode: 0644]
ja2/Build/Utils/MercTextBox.h [new file with mode: 0644]
ja2/Build/Utils/Multi Language Graphic Utils.c [new file with mode: 0644]
ja2/Build/Utils/Multi Language Graphic Utils.h [new file with mode: 0644]
ja2/Build/Utils/Multilingual Text Code Generator.c [new file with mode: 0644]
ja2/Build/Utils/Multilingual Text Code Generator.h [new file with mode: 0644]
ja2/Build/Utils/Music Control.c [new file with mode: 0644]
ja2/Build/Utils/Music Control.h [new file with mode: 0644]
ja2/Build/Utils/PopUpBox.c [new file with mode: 0644]
ja2/Build/Utils/PopUpBox.h [new file with mode: 0644]
ja2/Build/Utils/Quantize Wrap.cpp [new file with mode: 0644]
ja2/Build/Utils/Quantize Wrap.h [new file with mode: 0644]
ja2/Build/Utils/Quantize.cpp [new file with mode: 0644]
ja2/Build/Utils/Quantize.h [new file with mode: 0644]
ja2/Build/Utils/RADMAL.I [new file with mode: 0644]
ja2/Build/Utils/RADMALW.I [new file with mode: 0644]
ja2/Build/Utils/STIConvert.c [new file with mode: 0644]
ja2/Build/Utils/STIConvert.h [new file with mode: 0644]
ja2/Build/Utils/Slider.c [new file with mode: 0644]
ja2/Build/Utils/Slider.h [new file with mode: 0644]
ja2/Build/Utils/Sound Control.c [new file with mode: 0644]
ja2/Build/Utils/Sound Control.h [new file with mode: 0644]
ja2/Build/Utils/Text Input.c [new file with mode: 0644]
ja2/Build/Utils/Text Input.h [new file with mode: 0644]
ja2/Build/Utils/Text Utils.c [new file with mode: 0644]
ja2/Build/Utils/Text.h [new file with mode: 0644]
ja2/Build/Utils/Timer Control.c [new file with mode: 0644]
ja2/Build/Utils/Timer Control.h [new file with mode: 0644]
ja2/Build/Utils/Utilities.c [new file with mode: 0644]
ja2/Build/Utils/Utilities.h [new file with mode: 0644]
ja2/Build/Utils/Utils All.h [new file with mode: 0644]
ja2/Build/Utils/Utils.dsp [new file with mode: 0644]
ja2/Build/Utils/Win Util.c [new file with mode: 0644]
ja2/Build/Utils/Win Util.h [new file with mode: 0644]
ja2/Build/Utils/WordWrap.c [new file with mode: 0644]
ja2/Build/Utils/WordWrap.h [new file with mode: 0644]
ja2/Build/Utils/_DutchText.c [new file with mode: 0644]
ja2/Build/Utils/_EnglishText.c [new file with mode: 0644]
ja2/Build/Utils/_FrenchText.c [new file with mode: 0644]
ja2/Build/Utils/_GermanText.c [new file with mode: 0644]
ja2/Build/Utils/_ItalianText.c [new file with mode: 0644]
ja2/Build/Utils/_Ja25EnglishText.c [new file with mode: 0644]
ja2/Build/Utils/_Ja25EnglishText.h [new file with mode: 0644]
ja2/Build/Utils/_Ja25GermanText.c [new file with mode: 0644]
ja2/Build/Utils/_Ja25GermanText.h [new file with mode: 0644]
ja2/Build/Utils/_PolishText.c [new file with mode: 0644]
ja2/Build/Utils/_RussianText.c [new file with mode: 0644]
ja2/Build/Utils/_TaiwaneseText.c [new file with mode: 0644]
ja2/Build/Utils/dsutil.c [new file with mode: 0644]
ja2/Build/Utils/dsutil.h [new file with mode: 0644]
ja2/Build/Utils/maputility.h [new file with mode: 0644]
ja2/Build/Utils/message.c [new file with mode: 0644]
ja2/Build/Utils/message.h [new file with mode: 0644]
ja2/Build/VtuneApi.h [new file with mode: 0644]
ja2/Build/aniviewscreen.c [new file with mode: 0644]
ja2/Build/builddefines.h [new file with mode: 0644]
ja2/Build/gameloop.c [new file with mode: 0644]
ja2/Build/gameloop.h [new file with mode: 0644]
ja2/Build/gamescreen.c [new file with mode: 0644]
ja2/Build/gamescreen.h [new file with mode: 0644]
ja2/Build/ja2.h [new file with mode: 0644]
ja2/Build/jascreens.c [new file with mode: 0644]
ja2/Build/jascreens.h [new file with mode: 0644]
ja2/Build/local.h [new file with mode: 0644]
ja2/Build/mainmenuscreen.h [new file with mode: 0644]
ja2/Build/resource.h [new file with mode: 0644]
ja2/Build/screenids.h [new file with mode: 0644]
readme.txt [new file with mode: 0644]

diff --git a/SFI Source Code license agreement.txt b/SFI Source Code license agreement.txt
new file mode 100644 (file)
index 0000000..59767b1
--- /dev/null
@@ -0,0 +1,45 @@
+This Strategy First Inc. Source Code License Agreement ("SFI-SCLA") forms a legal agreement between you and Strategy First Inc. ("Strategy First") for the source code, related materials, or related documentation (together, the "Software"). \r
+\r
+By using this Software you agree to be bound by the terms of this SFI-SCLA. Do not install, copy, or use the Software if you do not agree to the terms of this License Agreement. The Software is protected by copyright and other intellectual property laws and Strategy First is licensing the Software, not selling it.    \r
+\r
+YOUR RIGHTS:\r
+\r
+You may use this Software for any non-commercial purpose, subject to the conditions of this License. Non-commercial purposes include, but are not limited to, teaching, research, public demos and your own experimentation. You may distribute this Software with books or other teaching materials, or publish the Software on websites that are intended to teach the use of the Software for academic or other non-commercial purposes. You may not use or distribute this Software, or any works that derive from it, in any form for commercial purposes. Commercial purposes include, but are not limited to, running a business, licensing, renting, or selling the Software, distributing the Software for use with any commercial products, or any other activity which purpose is to procure a profit or gain to you or others.  This Software includes source code or data, and you may modify such portions of the Software and distribute the modified Software for non-commercial purposes, as provided in this Licensing Agreement. \r
\r
+This Licensing Agreement does not grant you a license to any of Strategy First's copyrights or patents for anything you might create using any of the information included in the Software. \r
\r
+In return, you agree: \r
+\r
+1.     That you will not remove any copyright or other notices from the Software.\r
+\r
+2.     That if any of the Software is in binary format, you will not attempt to modify such portions of the Software, or to reverse engineer or decompile them, except and only to the extent authorized by law. \r
+\r
+3.     That if you distribute the Software or any derivative works of the Software, you will distribute them using a verbatim copy of this License, and you will not grant any\r
+rights to the Software or derivative works that are broader than those provided by this Licensing Agreement. For example, you may not distribute any modifications of the Software under terms that would permit commercial use, or under terms that require the Software or such derivative works to be sublicensed to others.\r
+\r
+4.     That if you have modified the Software or created derivative works, and distribute such modifications or derivative works, you will cause the modified files to carry \r
+prominent notices so that recipients know that they are not receiving the original Software. Such notices must state: (i) that you have changed the Software; and (ii) the date of any changes.\r
+\r
+5.     That Strategy First is granted, without any limitations, and on a royalty free basis, the rights to reproduce, install, use, modify, distribute and transfer your modifications to the Software source code or data.\r
+\r
+6.     That any feedback about the Software provided by you to us is voluntarily given, and Strategy First shall be free to use the feedback as it sees fit without obligation or \r
+restriction of any kind, even if the feedback is designated by you as confidential.\r
+\r
+7.     THAT THE SOFTWARE COMES "AS IS", WITH NO WARRANTIES. THIS MEANS NO EXPRESS, IMPLIED OR STATUTORY WARRANTY, INCLUDING WITHOUT LIMITATION, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, ANY WARRANTY AGAINST INTERFERENCE WITH YOUR ENJOYMENT OF THE SOFTWARE OR ANY WARRANTY OF TITLE OR NON-INFRINGEMENT. THERE IS NO WARRANTY THAT THIS SOFTWARE WILL FULFILL ANY OF YOUR PARTICULAR PURPOSES OR NEEDS. ALSO, YOU MUST PASS THIS DISCLAIMER ON WHENEVER YOU DISTRIBUTE THE SOFTWARE OR DERIVATIVE WORKS.\r
+\r
+8.     THAT NEITHER STRATEGY FIRST NOR ANY CONTRIBUTOR TO THE SOFTWARE WILL BE LIABLE FOR ANY DAMAGES RELATED TO THE SOFTWARE OR THIS LICENSE, INCLUDING DIRECT, INDIRECT, SPECIAL, \r
+CONSEQUENTIAL OR INCIDENTAL DAMAGES, TO THE MAXIMUM EXTENT THE LAW PERMITS, NO MATTER WHAT LEGAL THEORY IT IS BASED ON. ALSO, YOU MUST PASS THIS LIMITATION OF LIABILITY ON WHENEVER YOU DISTRIBUTE THE SOFTWARE OR DERIVATIVE WORKS.\r
+\r
+9.     That we have no duty of reasonable care or lack of negligence, and we are not obligated to provide technical support for the Software.\r
+\r
+10.    That if you breach this SFI-SCLA or if you sue anyone over patents that you think may apply to the Software or anyone's use of the Software, your license to the Software ends automatically and you shall destroy all of your copies of the Software immediately.  Section 5 of this SFI-SCLA shall survive any termination of this license.\r
+\r
+11.    That the patent rights, if any, granted in this Licensing Agreement only apply to the Software, not to any derivative works you make.\r
+\r
+12.    That the Software is subject to U.S. export jurisdiction at the time it is licensed to you, and it may be subject to additional export or import laws in other places.  You agree to comply with all such laws and regulations that may apply to the Software after delivery of the software to you.\r
+\r
+13.    That your rights under this License end automatically if you breach it in any way.\r
+\r
+14.    That all rights not expressly granted to you in this License are reserved.\r
+\r
+15.    That this SFI-SCLA shall be construed and controlled by the laws of the Province of Quebec, Canada, without regard to conflicts of law.  If any provision of this SFI-SCLA shall be deemed unenforceable or contrary to law, the rest of this SFI-SCLA shall remain in full effect and interpreted in an enforceable manner that most nearly captures the intent of the original language.\r
diff --git a/Standard Gaming Platform/Bitmap.h b/Standard Gaming Platform/Bitmap.h
new file mode 100644 (file)
index 0000000..81bc4b3
--- /dev/null
@@ -0,0 +1,63 @@
+//**************************************************************************\r
+//\r
+// Filename :  bitmap.h\r
+//\r
+//     Purpose :       bitmap format\r
+//\r
+// Modification history :\r
+//\r
+//             20nov96:HJH                             - Creation\r
+//\r
+//**************************************************************************\r
+\r
+#ifndef _bitmap_h\r
+#define _bitmap_h\r
+\r
+//**************************************************************************\r
+//\r
+//                             Includes\r
+//\r
+//**************************************************************************\r
+\r
+#include "types.h"\r
+\r
+//**************************************************************************\r
+//\r
+//                             Defines\r
+//\r
+//**************************************************************************\r
+\r
+//**************************************************************************\r
+//\r
+//                             Typedefs\r
+//\r
+//**************************************************************************\r
+\r
+typedef struct sgpBmHeadertag\r
+{\r
+       UINT32  uiNumBytes;                     //      number of bytes of the bitmap, including the\r
+                                                                               // memory for all variables in this structure plus\r
+                                                                               // all the memory in bitmap\r
+       UINT32  uiWidth;                                // width of bitmap in pixels\r
+       UINT32  uiHeight;                       // height of bitmap in pixels\r
+       UINT8           uiBitDepth;                     // 8, 16, 24, or 32\r
+       UINT8           uiNumPalEntries;        // if uiBitDepth is 8, non-zero, else 0\r
+} SGPBmHeader;\r
+\r
+typedef struct sgpBitmaptag\r
+{\r
+       SGPBmHeader     header;\r
+       UINT8                   uiData[1];      // if uiNumPalEntries != 0\r
+                                                                       //              uiNumPalEntries*3 (rgb) bytes for palette\r
+                                                                       // if uiBitDepth == 8\r
+                                                                       //              uiWidth * uiHeight bytes\r
+                                                                       // else if uiBitDepth == 16\r
+                                                                       //              uiWidth * uiHeight * 2 bytes\r
+                                                                       // else if uiBitDepth == 24\r
+                                                                       //              uiWidth * uiHeight * 3 bytes\r
+                                                                       // else if uiBitDepth == 32\r
+                                                                       //              uiWidth * uiHeight * 4 bytes\r
+} SGPBitmap;\r
+\r
+#endif\r
+\r
diff --git a/Standard Gaming Platform/Button Sound Control.c b/Standard Gaming Platform/Button Sound Control.c
new file mode 100644 (file)
index 0000000..404fe71
--- /dev/null
@@ -0,0 +1,193 @@
+#ifdef JA2_PRECOMPILED_HEADERS\r
+       #include "JA2 SGP ALL.H"\r
+#elif defined( WIZ8_PRECOMPILED_HEADERS )\r
+       #include "WIZ8 SGP ALL.H"\r
+#else\r
+       #include "types.h"\r
+       #include "Button System.h"\r
+       #include "Button Sound Control.h"\r
+       #include "Sound Control.h"\r
+       #include "jascreens.h"\r
+#endif\r
+\r
+void SpecifyButtonSoundScheme( INT32 iButtonID, INT8 bSoundScheme )\r
+{\r
+       ButtonList[ iButtonID ]->ubSoundSchemeID = (UINT8)bSoundScheme;\r
+       if( bSoundScheme == BUTTON_SOUND_SCHEME_GENERIC )\r
+       {\r
+               #ifdef JA2\r
+               switch( guiCurrentScreen )\r
+               {\r
+                       case MAINMENU_SCREEN:\r
+                       case OPTIONS_SCREEN:\r
+                       case LOADSAVE_SCREEN:\r
+                       case SAVE_LOAD_SCREEN:\r
+                       case INIT_SCREEN:\r
+                               ButtonList[ iButtonID ]->ubSoundSchemeID = BUTTON_SOUND_SCHEME_BIGSWITCH3;\r
+                               break;\r
+\r
+                       case LAPTOP_SCREEN:\r
+                               ButtonList[ iButtonID ]->ubSoundSchemeID = BUTTON_SOUND_SCHEME_COMPUTERBEEP2;\r
+                               break;\r
+\r
+                       case AUTORESOLVE_SCREEN:\r
+                       case MAP_SCREEN:\r
+                       case GAME_SCREEN:\r
+                       case SHOPKEEPER_SCREEN:\r
+                               ButtonList[ iButtonID ]->ubSoundSchemeID = BUTTON_SOUND_SCHEME_SMALLSWITCH2;\r
+                               break;\r
+\r
+                       case GAME_INIT_OPTIONS_SCREEN:\r
+                               ButtonList[ iButtonID ]->ubSoundSchemeID = BUTTON_SOUND_SCHEME_VERYSMALLSWITCH2;\r
+                               break;\r
+\r
+                       //Anything not handled gets NO sound.\r
+                       //SHOPKEEPER_SCREEN,\r
+                       //GAME_SCREEN,\r
+                       //MSG_BOX_SCREEN,\r
+                               \r
+                       //ERROR_SCREEN,\r
+                       //ANIEDIT_SCREEN,\r
+                       //PALEDIT_SCREEN,\r
+                       //DEBUG_SCREEN,\r
+                       //SEX_SCREEN,\r
+               }\r
+               #endif\r
+               if( bSoundScheme == BUTTON_SOUND_SCHEME_GENERIC )\r
+                       bSoundScheme = BUTTON_SOUND_SCHEME_NONE;\r
+       }\r
+}\r
+\r
+void PlayButtonSound( INT32 iButtonID, INT32 iSoundType )\r
+{\r
+       if ( ButtonList[ iButtonID ] == NULL )\r
+       {\r
+               return;\r
+       }\r
+\r
+       switch( ButtonList[ iButtonID ]->ubSoundSchemeID )\r
+       {\r
+               case BUTTON_SOUND_SCHEME_NONE:\r
+               case BUTTON_SOUND_SCHEME_GENERIC:\r
+                       break;\r
+\r
+#ifdef JA2\r
+\r
+               case BUTTON_SOUND_SCHEME_VERYSMALLSWITCH1:\r
+                       switch( iSoundType )\r
+                       {\r
+                               case BUTTON_SOUND_CLICKED_ON:\r
+                                       PlayJA2Sample( VSM_SWITCH1_IN, RATE_11025, 15, 1, MIDDLEPAN );                  \r
+                                       break;\r
+                               case BUTTON_SOUND_CLICKED_OFF:\r
+                                       PlayJA2Sample( VSM_SWITCH1_OUT, RATE_11025, 15, 1, MIDDLEPAN );                 \r
+                                       break;\r
+                               case BUTTON_SOUND_DISABLED_CLICK:\r
+                                       PlayJA2SampleFromFile( "Sounds\\Disabled Button.wav", RATE_11025, 15, 1, MIDDLEPAN );                   \r
+                                       break;\r
+                       }\r
+                       break;\r
+               case BUTTON_SOUND_SCHEME_VERYSMALLSWITCH2:\r
+                       switch( iSoundType )\r
+                       {\r
+                               case BUTTON_SOUND_CLICKED_ON:\r
+                                       PlayJA2Sample( VSM_SWITCH2_IN, RATE_11025, 15, 1, MIDDLEPAN );                  \r
+                                       break;\r
+                               case BUTTON_SOUND_CLICKED_OFF:\r
+                                       PlayJA2Sample( VSM_SWITCH2_OUT, RATE_11025, 15, 1, MIDDLEPAN );                 \r
+                                       break;\r
+                               case BUTTON_SOUND_DISABLED_CLICK:\r
+                                       PlayJA2SampleFromFile( "Sounds\\Disabled Button.wav", RATE_11025, 15, 1, MIDDLEPAN );                   \r
+                                       break;\r
+                       }\r
+                       break;\r
+               case BUTTON_SOUND_SCHEME_SMALLSWITCH1:\r
+                       switch( iSoundType )\r
+                       {\r
+                               case BUTTON_SOUND_CLICKED_ON:\r
+                                       PlayJA2Sample( SM_SWITCH1_IN, RATE_11025, 15, 1, MIDDLEPAN );                   \r
+                                       break;\r
+                               case BUTTON_SOUND_CLICKED_OFF:\r
+                                       PlayJA2Sample( SM_SWITCH1_OUT, RATE_11025, 15, 1, MIDDLEPAN );                  \r
+                                       break;\r
+                               case BUTTON_SOUND_DISABLED_CLICK:\r
+                                       PlayJA2SampleFromFile( "Sounds\\Disabled Button.wav", RATE_11025, 15, 1, MIDDLEPAN );                   \r
+                                       break;\r
+                       }\r
+                       break;\r
+               case BUTTON_SOUND_SCHEME_SMALLSWITCH2:\r
+                       switch( iSoundType )\r
+                       {\r
+                               case BUTTON_SOUND_CLICKED_ON:\r
+                                       PlayJA2Sample( SM_SWITCH2_IN, RATE_11025, 15, 1, MIDDLEPAN );                   \r
+                                       break;\r
+                               case BUTTON_SOUND_CLICKED_OFF:\r
+                                       PlayJA2Sample( SM_SWITCH2_OUT, RATE_11025, 15, 1, MIDDLEPAN );                  \r
+                                       break;\r
+                               case BUTTON_SOUND_DISABLED_CLICK:\r
+                                       PlayJA2SampleFromFile( "Sounds\\Disabled Button.wav", RATE_11025, 15, 1, MIDDLEPAN );                   \r
+                                       break;\r
+                       }\r
+                       break;\r
+               case BUTTON_SOUND_SCHEME_SMALLSWITCH3:\r
+                       switch( iSoundType )\r
+                       {\r
+                               case BUTTON_SOUND_CLICKED_ON:\r
+                                       PlayJA2Sample( SM_SWITCH3_IN, RATE_11025, 15, 1, MIDDLEPAN );                   \r
+                                       break;\r
+                               case BUTTON_SOUND_CLICKED_OFF:\r
+                                       PlayJA2Sample( SM_SWITCH3_OUT, RATE_11025, 15, 1, MIDDLEPAN );                  \r
+                                       break;\r
+                               case BUTTON_SOUND_DISABLED_CLICK:\r
+                                       PlayJA2SampleFromFile( "Sounds\\Disabled Button.wav", RATE_11025, 15, 1, MIDDLEPAN );                   \r
+                                       break;\r
+                       }\r
+                       break;\r
+               case BUTTON_SOUND_SCHEME_BIGSWITCH3:\r
+                       switch( iSoundType )\r
+                       {\r
+                               case BUTTON_SOUND_CLICKED_ON:\r
+                                       PlayJA2Sample( BIG_SWITCH3_IN, RATE_11025, 15, 1, MIDDLEPAN );                  \r
+                                       break;\r
+                               case BUTTON_SOUND_CLICKED_OFF:\r
+                                       PlayJA2Sample( BIG_SWITCH3_OUT, RATE_11025, 15, 1, MIDDLEPAN );                 \r
+                                       break;\r
+                               case BUTTON_SOUND_DISABLED_CLICK:\r
+                                       PlayJA2SampleFromFile( "Sounds\\Disabled Button.wav", RATE_11025, 15, 1, MIDDLEPAN );                   \r
+                                       break;\r
+                       }\r
+                       break;\r
+               case BUTTON_SOUND_SCHEME_COMPUTERBEEP2:\r
+                       switch( iSoundType )\r
+                       {\r
+                               case BUTTON_SOUND_CLICKED_ON:\r
+                                       PlayJA2Sample( COMPUTER_BEEP2_IN, RATE_11025, 15, 1, MIDDLEPAN );                       \r
+                                       break;\r
+                               case BUTTON_SOUND_CLICKED_OFF:\r
+                                       PlayJA2Sample( COMPUTER_BEEP2_OUT, RATE_11025, 15, 1, MIDDLEPAN );                      \r
+                                       break;\r
+                               case BUTTON_SOUND_DISABLED_CLICK:\r
+                                       PlayJA2SampleFromFile( "Sounds\\Disabled Button.wav", RATE_11025, 15, 1, MIDDLEPAN );                   \r
+                                       break;\r
+                       }\r
+                       break;\r
+               case BUTTON_SOUND_SCHEME_COMPUTERSWITCH1:\r
+                       switch( iSoundType )\r
+                       {\r
+                               case BUTTON_SOUND_CLICKED_ON:\r
+                                       PlayJA2Sample( COMPUTER_SWITCH1_IN, RATE_11025, 15, 1, MIDDLEPAN );                     \r
+                                       break;\r
+                               case BUTTON_SOUND_CLICKED_OFF:\r
+                                       PlayJA2Sample( COMPUTER_SWITCH1_OUT, RATE_11025, 15, 1, MIDDLEPAN );                    \r
+                                       break;\r
+                               case BUTTON_SOUND_DISABLED_CLICK:\r
+                                       PlayJA2SampleFromFile( "Sounds\\Disabled Button.wav", RATE_11025, 15, 1, MIDDLEPAN );                   \r
+                                       break;\r
+                       }\r
+                       break;\r
+\r
+#endif\r
+\r
+       }       \r
+\r
+}
\ No newline at end of file
diff --git a/Standard Gaming Platform/Button Sound Control.h b/Standard Gaming Platform/Button Sound Control.h
new file mode 100644 (file)
index 0000000..0a1d6c1
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef __BUTTON_SOUND_CONTROL_H\r
+#define __BUTTON_SOUND_CONTROL_H\r
+\r
+\r
+//These are gener\r
+enum\r
+{\r
+       BUTTON_SOUND_SCHEME_NONE,\r
+       BUTTON_SOUND_SCHEME_GENERIC,\r
+       BUTTON_SOUND_SCHEME_VERYSMALLSWITCH1,\r
+       BUTTON_SOUND_SCHEME_VERYSMALLSWITCH2,\r
+       BUTTON_SOUND_SCHEME_SMALLSWITCH1,\r
+       BUTTON_SOUND_SCHEME_SMALLSWITCH2,\r
+       BUTTON_SOUND_SCHEME_SMALLSWITCH3,\r
+       BUTTON_SOUND_SCHEME_BIGSWITCH3,\r
+       BUTTON_SOUND_SCHEME_COMPUTERBEEP2,\r
+       BUTTON_SOUND_SCHEME_COMPUTERSWITCH1,\r
+};\r
+\r
+#endif\r
diff --git a/Standard Gaming Platform/Button System.c b/Standard Gaming Platform/Button System.c
new file mode 100644 (file)
index 0000000..e81123e
--- /dev/null
@@ -0,0 +1,4392 @@
+/***********************************************************************************************\r
+       Button System.c\r
+\r
+       Rewritten mostly by Kris Morness\r
+***********************************************************************************************/\r
+\r
+#ifdef JA2_PRECOMPILED_HEADERS\r
+       #include "JA2 SGP ALL.H"\r
+#elif defined( WIZ8_PRECOMPILED_HEADERS )\r
+       #include "WIZ8 SGP ALL.H"\r
+#else\r
+       #include "types.h"\r
+       #include <windows.h>\r
+       #include <stdio.h>\r
+       #include <memory.h>\r
+       #include "debug.h"\r
+       #include "input.h"\r
+       #include "memman.h"\r
+       #include "english.h"\r
+       #include "vobject.h"\r
+       #include "vobject_blitters.h"\r
+       #include "soundman.h"\r
+       #include "Button System.h"\r
+       #include "line.h"\r
+       #include <stdarg.h>\r
+       #if defined( JA2 ) || defined( UTIL )\r
+               #include "WordWrap.h"\r
+               #include "video.h"\r
+               #include "Button Sound Control.h"\r
+               #ifdef _JA2_RENDER_DIRTY\r
+                       #include "\JA2\Build\utils\Font Control.h"\r
+                       #include "Render Dirty.h"\r
+                       #include "utilities.h"\r
+               #endif\r
+       #else\r
+               #include "video2.h"\r
+       #endif\r
+#endif\r
+\r
+\r
+//ATE: Added to let Wiz default creating mouse regions with no cursor, JA2 default to a cursor ( first one )\r
+#ifdef JA2\r
+       #define         MSYS_STARTING_CURSORVAL         0\r
+#else\r
+       #define         MSYS_STARTING_CURSORVAL         MSYS_NO_CURSOR\r
+       // The following should be moved from here\r
+       #define GETPIXELDEPTH( )        ( gbPixelDepth )                // From "utilities.h" in JA2\r
+       #define         COLOR_RED                                               162                                                     // From "lighting.h" in JA2\r
+       #define         COLOR_BLUE                                      203\r
+       #define         COLOR_YELLOW                            144\r
+       #define         COLOR_GREEN                                     184\r
+       #define         COLOR_LTGREY                            134\r
+       #define         COLOR_BROWN                                     80\r
+       #define         COLOR_PURPLE                            160\r
+       #define         COLOR_ORANGE                            76\r
+       #define         COLOR_WHITE                                     208\r
+       #define         COLOR_BLACK                                     72\r
+       // this doesn't exactly belong here either... (From "Font Control.h" in JA2)\r
+       #define         FONT_MCOLOR_BLACK                               0\r
+#endif\r
+#define                COLOR_DKGREY                            136\r
+\r
+\r
+#define MAX_GENERIC_PICS               40\r
+#define MAX_BUTTON_ICONS               40\r
+\r
+\r
+#define GUI_BTN_NONE                                                   0\r
+#define GUI_BTN_DUPLICATE_VOBJ         1\r
+#define GUI_BTN_EXTERNAL_VOBJ                  2\r
+\r
+\r
+UINT8          str[128];\r
+\r
+//Kris:  December 2, 1997\r
+//Special internal debugging utilities that will ensure that you don't attempt to delete\r
+//an already deleted button, or it's images, etc.  It will also ensure that you don't create\r
+//the same button that already exists.\r
+//TO REMOVE ALL DEBUG FUNCTIONALITY:  simply comment out BUTTONSYSTEM_DEBUGGING definition\r
+#ifdef JA2\r
+  #ifdef _DEBUG\r
+         #define BUTTONSYSTEM_DEBUGGING\r
+  #endif\r
+#endif\r
+\r
+#ifdef BUTTONSYSTEM_DEBUGGING\r
+BOOLEAN gfIgnoreShutdownAssertions;\r
+//Called immediately before assigning the button to the button list.\r
+void AssertFailIfIdenticalButtonAttributesFound( GUI_BUTTON *b )\r
+{\r
+       INT32 x;\r
+       GUI_BUTTON *c;\r
+       for( x = 0; x < MAX_BUTTONS; x++ )\r
+       {\r
+               c = ButtonList[ x ];\r
+               if( !c )                                                                                                                                                                                                                                        continue;\r
+               if( c->uiFlags                                                                  &  BUTTON_DELETION_PENDING              )   continue;\r
+               if( c->UserData[3]                                                      == 0xffffffff                                                                   )               continue;\r
+               if( b->Area.PriorityLevel                               != c->Area.PriorityLevel                        )               continue;\r
+               if( b->Area.RegionTopLeftX                      != c->Area.RegionTopLeftX                       )               continue;\r
+               if( b->Area.RegionTopLeftY                      != c->Area.RegionTopLeftY                       )               continue;\r
+               if( b->Area.RegionBottomRightX  != c->Area.RegionBottomRightX )         continue;\r
+               if( b->Area.RegionBottomRightY  != c->Area.RegionBottomRightY )         continue;\r
+               if( b->ClickCallback                                            != c->ClickCallback                                             )               continue;\r
+               if( b->MoveCallback                                                     != c->MoveCallback                                              )               continue;\r
+               if( b->XLoc                                                                                     != c->XLoc                                                                              )               continue;\r
+               if( b->YLoc                                                                                     != c->YLoc                                                                              )               continue;\r
+               //if we get this far, it is reasonably safe to assume that the newly created\r
+               //button already exists.  Placing a break point on the following assert will\r
+               //allow the coder to easily isolate the case!\r
+               sprintf( str, "Attempting to create a button that has already been created (existing buttonID %d).", c->IDNum );\r
+               AssertMsg( 0, str );\r
+       }\r
+}\r
+#endif\r
+\r
+//Kris:\r
+//These are the variables used for the anchoring of a particular button.\r
+//When you click on a button, it get's anchored, until you release the mouse button.\r
+//When you move around, you don't want to select other buttons, even when you release\r
+//it.  This follows the Windows 95 convention.\r
+GUI_BUTTON *gpAnchoredButton;\r
+GUI_BUTTON *gpPrevAnchoredButton;\r
+BOOLEAN gfAnchoredState;\r
+void ReleaseAnchorMode();\r
+\r
+INT8 gbDisabledButtonStyle;\r
+void DrawHatchOnButton( GUI_BUTTON *b );\r
+void DrawShadeOnButton( GUI_BUTTON *b );\r
+void DrawDefaultOnButton( GUI_BUTTON *b );\r
+\r
+GUI_BUTTON *gpCurrentFastHelpButton;\r
+\r
+BOOLEAN gfRenderHilights = TRUE;\r
+\r
+BUTTON_PICS            ButtonPictures[MAX_BUTTON_PICS];\r
+INT32                                  ButtonPicsLoaded;\r
+\r
+UINT32 ButtonDestBuffer = BACKBUFFER;\r
+UINT32 ButtonDestPitch = 640*2;\r
+UINT32 ButtonDestBPP = 16;\r
+\r
+GUI_BUTTON *ButtonList[MAX_BUTTONS];\r
+\r
+INT32 ButtonsInList=0;\r
+\r
+UINT16 GetWidthOfButtonPic( UINT16 usButtonPicID, INT32 iSlot )\r
+{\r
+       return ButtonPictures[ usButtonPicID ].vobj->pETRLEObject[ iSlot ].usWidth;\r
+}\r
+\r
+HVOBJECT GenericButtonGrayed[MAX_GENERIC_PICS];\r
+HVOBJECT GenericButtonOffNormal[MAX_GENERIC_PICS];\r
+HVOBJECT GenericButtonOffHilite[MAX_GENERIC_PICS];\r
+HVOBJECT GenericButtonOnNormal[MAX_GENERIC_PICS];\r
+HVOBJECT GenericButtonOnHilite[MAX_GENERIC_PICS];\r
+HVOBJECT GenericButtonBackground[MAX_GENERIC_PICS];\r
+UINT16 GenericButtonFillColors[MAX_GENERIC_PICS];\r
+UINT16 GenericButtonBackgroundIndex[MAX_GENERIC_PICS];\r
+INT16 GenericButtonOffsetX[MAX_GENERIC_PICS];\r
+INT16 GenericButtonOffsetY[MAX_GENERIC_PICS];\r
+\r
+HVOBJECT GenericButtonIcons[MAX_BUTTON_ICONS];\r
+\r
+// flag to state we wish to render buttons on the one after the next pass through render buttons\r
+BOOLEAN fPausedMarkButtonsDirtyFlag = FALSE;\r
+BOOLEAN fDisableHelpTextRestoreFlag = FALSE;\r
+\r
+BOOLEAN gfDelayButtonDeletion = FALSE;\r
+BOOLEAN gfPendingButtonDeletion = FALSE;\r
+void RemoveButtonsMarkedForDeletion();\r
+\r
+extern MOUSE_REGION *MSYS_PrevRegion;\r
+extern MOUSE_REGION *MSYS_CurrRegion;\r
+\r
+//=============================================================================\r
+//     FindFreeButtonSlot\r
+//\r
+//     Finds an available slot for loading button pictures\r
+//\r
+INT32 FindFreeButtonSlot(void)\r
+{\r
+       int slot;\r
+\r
+       // Are there any slots available?\r
+       if(ButtonPicsLoaded >= MAX_BUTTON_PICS)\r
+               return(BUTTON_NO_SLOT);\r
+\r
+       // Search for a slot\r
+       for(slot=0;slot<MAX_BUTTON_PICS;slot++)\r
+       {\r
+               if(ButtonPictures[slot].vobj==NULL)\r
+                       return(slot);\r
+       }\r
+\r
+       return(BUTTON_NO_SLOT);\r
+}\r
+\r
+\r
+\r
+//=============================================================================\r
+//     LoadButtonImage\r
+//\r
+//     Load images for use with QuickButtons.\r
+//\r
+INT32 LoadButtonImage(UINT8 *filename, INT32 Grayed, INT32 OffNormal, INT32 OffHilite, INT32 OnNormal, INT32 OnHilite)\r
+{\r
+       VOBJECT_DESC    vo_desc;\r
+       UINT32                          UseSlot;\r
+       ETRLEObject             *pTrav;\r
+       UINT32                          MaxHeight,MaxWidth,ThisHeight,ThisWidth;\r
+       UINT32 MemBefore,MemAfter,MemUsed;\r
+\r
+       AssertMsg(filename!=BUTTON_NO_FILENAME, "Attempting to LoadButtonImage() with null filename." );\r
+       AssertMsg(strlen(filename), "Attempting to LoadButtonImage() with empty filename string." );\r
+\r
+       // is there ANY file to open?\r
+       if((Grayed == BUTTON_NO_IMAGE) && (OffNormal == BUTTON_NO_IMAGE) && (OffHilite == BUTTON_NO_IMAGE) &&\r
+                (OnNormal == BUTTON_NO_IMAGE) && (OnHilite == BUTTON_NO_IMAGE))\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, String("No button pictures selected for %s",filename));\r
+               return(-1);\r
+       }\r
+\r
+       // Get a button image slot\r
+       if((UseSlot=FindFreeButtonSlot()) == BUTTON_NO_SLOT)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, String("Out of button image slots for %s",filename));\r
+               return(-1);\r
+       }\r
+\r
+       // Load the image\r
+       vo_desc.fCreateFlags = VOBJECT_CREATE_FROMFILE;\r
+       strcpy(vo_desc.ImageFile, filename);\r
+\r
+       MemBefore = MemGetFree();\r
+       if((ButtonPictures[UseSlot].vobj = CreateVideoObject(&vo_desc)) == NULL)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, String("Couldn't create VOBJECT for %s",filename));\r
+               return(-1);\r
+       }\r
+       MemAfter = MemGetFree();\r
+       MemUsed = MemBefore-MemAfter;\r
+\r
+       // Init the QuickButton image structure with indexes to use\r
+       ButtonPictures[UseSlot].Grayed=Grayed;\r
+       ButtonPictures[UseSlot].OffNormal=OffNormal;\r
+       ButtonPictures[UseSlot].OffHilite=OffHilite;\r
+       ButtonPictures[UseSlot].OnNormal=OnNormal;\r
+       ButtonPictures[UseSlot].OnHilite=OnHilite;\r
+       ButtonPictures[UseSlot].fFlags = GUI_BTN_NONE;\r
+\r
+       // Fit the button size to the largest image in the set\r
+       MaxWidth=MaxHeight=0;\r
+       if(Grayed != BUTTON_NO_IMAGE)\r
+       {\r
+               pTrav = &(ButtonPictures[UseSlot].vobj->pETRLEObject[Grayed]);\r
+               ThisHeight = (UINT32)(pTrav->usHeight+pTrav->sOffsetY);\r
+               ThisWidth = (UINT32)(pTrav->usWidth+pTrav->sOffsetX);\r
+\r
+               if(MaxWidth<ThisWidth)\r
+                       MaxWidth=ThisWidth;\r
+               if(MaxHeight<ThisHeight)\r
+                       MaxHeight=ThisHeight;\r
+       }\r
+\r
+       if(OffNormal != BUTTON_NO_IMAGE)\r
+       {\r
+               pTrav = &(ButtonPictures[UseSlot].vobj->pETRLEObject[OffNormal]);\r
+               ThisHeight = (UINT32)(pTrav->usHeight+pTrav->sOffsetY);\r
+               ThisWidth = (UINT32)(pTrav->usWidth+pTrav->sOffsetX);\r
+\r
+               if(MaxWidth<ThisWidth)\r
+                       MaxWidth=ThisWidth;\r
+               if(MaxHeight<ThisHeight)\r
+                       MaxHeight=ThisHeight;\r
+       }\r
+\r
+       if(OffHilite != BUTTON_NO_IMAGE)\r
+       {\r
+               pTrav = &(ButtonPictures[UseSlot].vobj->pETRLEObject[OffHilite]);\r
+               ThisHeight = (UINT32)(pTrav->usHeight+pTrav->sOffsetY);\r
+               ThisWidth = (UINT32)(pTrav->usWidth+pTrav->sOffsetX);\r
+\r
+               if(MaxWidth<ThisWidth)\r
+                       MaxWidth=ThisWidth;\r
+               if(MaxHeight<ThisHeight)\r
+                       MaxHeight=ThisHeight;\r
+       }\r
+\r
+       if(OnNormal != BUTTON_NO_IMAGE)\r
+       {\r
+               pTrav = &(ButtonPictures[UseSlot].vobj->pETRLEObject[OnNormal]);\r
+               ThisHeight = (UINT32)(pTrav->usHeight+pTrav->sOffsetY);\r
+               ThisWidth = (UINT32)(pTrav->usWidth+pTrav->sOffsetX);\r
+\r
+               if(MaxWidth<ThisWidth)\r
+                       MaxWidth=ThisWidth;\r
+               if(MaxHeight<ThisHeight)\r
+                       MaxHeight=ThisHeight;\r
+       }\r
+\r
+       if(OnHilite != BUTTON_NO_IMAGE)\r
+       {\r
+               pTrav = &(ButtonPictures[UseSlot].vobj->pETRLEObject[OnHilite]);\r
+               ThisHeight = (UINT32)(pTrav->usHeight+pTrav->sOffsetY);\r
+               ThisWidth = (UINT32)(pTrav->usWidth+pTrav->sOffsetX);\r
+\r
+               if(MaxWidth<ThisWidth)\r
+                       MaxWidth=ThisWidth;\r
+               if(MaxHeight<ThisHeight)\r
+                       MaxHeight=ThisHeight;\r
+       }\r
+\r
+       // Set the width and height for this image set\r
+       ButtonPictures[UseSlot].MaxHeight=MaxHeight;\r
+       ButtonPictures[UseSlot].MaxWidth=MaxWidth;\r
+\r
+       // return the image slot number\r
+       ButtonPicsLoaded++;\r
+       return(UseSlot);\r
+}\r
+\r
+\r
+//=============================================================================\r
+//     UseLoadedButtonImage\r
+//\r
+//     Uses a previously loaded quick button image for use with QuickButtons.\r
+//     The function simply duplicates the vobj!\r
+//\r
+INT32 UseLoadedButtonImage(INT32 LoadedImg, INT32 Grayed, INT32 OffNormal, INT32 OffHilite, INT32 OnNormal, INT32 OnHilite)\r
+{\r
+       UINT32                          UseSlot;\r
+       ETRLEObject             *pTrav;\r
+       UINT32                          MaxHeight,MaxWidth,ThisHeight,ThisWidth;\r
+\r
+\r
+       // Is button image index given valid?\r
+       if( ButtonPictures[LoadedImg].vobj == NULL )\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, String("Invalid button picture handle given for pre-loaded button image %d",LoadedImg));\r
+               return(-1);\r
+       }\r
+\r
+       // Is button image an external vobject?\r
+       if( ButtonPictures[LoadedImg].fFlags & GUI_BTN_EXTERNAL_VOBJ )\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, String("Invalid button picture handle given (%d), cannot use external images as duplicates.",LoadedImg));\r
+               return(-1);\r
+       }\r
+\r
+       // is there ANY file to open?\r
+       if((Grayed == BUTTON_NO_IMAGE) && (OffNormal == BUTTON_NO_IMAGE) && (OffHilite == BUTTON_NO_IMAGE) &&\r
+                (OnNormal == BUTTON_NO_IMAGE) && (OnHilite == BUTTON_NO_IMAGE))\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, String("No button pictures selected for pre-loaded button image %d",LoadedImg));\r
+               return(-1);\r
+       }\r
+\r
+       // Get a button image slot\r
+       if((UseSlot=FindFreeButtonSlot()) == BUTTON_NO_SLOT)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, String("Out of button image slots for pre-loaded button image %d",LoadedImg));\r
+               return(-1);\r
+       }\r
+\r
+       // Init the QuickButton image structure with indexes to use\r
+       ButtonPictures[UseSlot].vobj = ButtonPictures[LoadedImg].vobj;\r
+       ButtonPictures[UseSlot].Grayed=Grayed;\r
+       ButtonPictures[UseSlot].OffNormal=OffNormal;\r
+       ButtonPictures[UseSlot].OffHilite=OffHilite;\r
+       ButtonPictures[UseSlot].OnNormal=OnNormal;\r
+       ButtonPictures[UseSlot].OnHilite=OnHilite;\r
+       ButtonPictures[UseSlot].fFlags = GUI_BTN_DUPLICATE_VOBJ;\r
+\r
+       // Fit the button size to the largest image in the set\r
+       MaxWidth=MaxHeight=0;\r
+       if(Grayed != BUTTON_NO_IMAGE)\r
+       {\r
+               pTrav = &(ButtonPictures[UseSlot].vobj->pETRLEObject[Grayed]);\r
+               ThisHeight = (UINT32)(pTrav->usHeight+pTrav->sOffsetY);\r
+               ThisWidth = (UINT32)(pTrav->usWidth+pTrav->sOffsetX);\r
+\r
+               if(MaxWidth<ThisWidth)\r
+                       MaxWidth=ThisWidth;\r
+               if(MaxHeight<ThisHeight)\r
+                       MaxHeight=ThisHeight;\r
+       }\r
+\r
+       if(OffNormal != BUTTON_NO_IMAGE)\r
+       {\r
+               pTrav = &(ButtonPictures[UseSlot].vobj->pETRLEObject[OffNormal]);\r
+               ThisHeight = (UINT32)(pTrav->usHeight+pTrav->sOffsetY);\r
+               ThisWidth = (UINT32)(pTrav->usWidth+pTrav->sOffsetX);\r
+\r
+               if(MaxWidth<ThisWidth)\r
+                       MaxWidth=ThisWidth;\r
+               if(MaxHeight<ThisHeight)\r
+                       MaxHeight=ThisHeight;\r
+       }\r
+\r
+       if(OffHilite != BUTTON_NO_IMAGE)\r
+       {\r
+               pTrav = &(ButtonPictures[UseSlot].vobj->pETRLEObject[OffHilite]);\r
+               ThisHeight = (UINT32)(pTrav->usHeight+pTrav->sOffsetY);\r
+               ThisWidth = (UINT32)(pTrav->usWidth+pTrav->sOffsetX);\r
+\r
+               if(MaxWidth<ThisWidth)\r
+                       MaxWidth=ThisWidth;\r
+               if(MaxHeight<ThisHeight)\r
+                       MaxHeight=ThisHeight;\r
+       }\r
+\r
+       if(OnNormal != BUTTON_NO_IMAGE)\r
+       {\r
+               pTrav = &(ButtonPictures[UseSlot].vobj->pETRLEObject[OnNormal]);\r
+               ThisHeight = (UINT32)(pTrav->usHeight+pTrav->sOffsetY);\r
+               ThisWidth = (UINT32)(pTrav->usWidth+pTrav->sOffsetX);\r
+\r
+               if(MaxWidth<ThisWidth)\r
+                       MaxWidth=ThisWidth;\r
+               if(MaxHeight<ThisHeight)\r
+                       MaxHeight=ThisHeight;\r
+       }\r
+\r
+       if(OnHilite != BUTTON_NO_IMAGE)\r
+       {\r
+               pTrav = &(ButtonPictures[UseSlot].vobj->pETRLEObject[OnHilite]);\r
+               ThisHeight = (UINT32)(pTrav->usHeight+pTrav->sOffsetY);\r
+               ThisWidth = (UINT32)(pTrav->usWidth+pTrav->sOffsetX);\r
+\r
+               if(MaxWidth<ThisWidth)\r
+                       MaxWidth=ThisWidth;\r
+               if(MaxHeight<ThisHeight)\r
+                       MaxHeight=ThisHeight;\r
+       }\r
+\r
+       // Set the width and height for this image set\r
+       ButtonPictures[UseSlot].MaxHeight=MaxHeight;\r
+       ButtonPictures[UseSlot].MaxWidth=MaxWidth;\r
+\r
+       // return the image slot number\r
+       ButtonPicsLoaded++;\r
+       return(UseSlot);\r
+}\r
+\r
+\r
+\r
+//=============================================================================\r
+//     UseVObjAsButtonImage\r
+//\r
+//     Uses a previously loaded VObject for use with QuickButtons.\r
+//     The function simply duplicates the vobj pointer and uses that.\r
+//\r
+//             **** NOTE ****\r
+//                     The image isn't unloaded with a call to UnloadButtonImage. The internal\r
+//                     structures are simply removed from the button image list. It's up to\r
+//                     the user to actually unload the image.\r
+//\r
+INT32 UseVObjAsButtonImage(HVOBJECT hVObject, INT32 Grayed, INT32 OffNormal, INT32 OffHilite, INT32 OnNormal, INT32 OnHilite)\r
+{\r
+       UINT32                          UseSlot;\r
+       ETRLEObject             *pTrav;\r
+       UINT32                          MaxHeight,MaxWidth,ThisHeight,ThisWidth;\r
+\r
+\r
+       // Is button image index given valid?\r
+       if( hVObject == NULL )\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, String("UseVObjAsButtonImage: Invalid VObject image given"));\r
+               return(-1);\r
+       }\r
+\r
+       // is there ANY file to open?\r
+       if((Grayed == BUTTON_NO_IMAGE) && (OffNormal == BUTTON_NO_IMAGE) && (OffHilite == BUTTON_NO_IMAGE) &&\r
+                (OnNormal == BUTTON_NO_IMAGE) && (OnHilite == BUTTON_NO_IMAGE))\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, String("UseVObjAsButtonImage: No button pictures indexes selected for VObject"));\r
+               return(-1);\r
+       }\r
+\r
+       // Get a button image slot\r
+       if((UseSlot=FindFreeButtonSlot()) == BUTTON_NO_SLOT)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, String("UseVObjAsButtonImage: Out of button image slots for VObject"));\r
+               return(-1);\r
+       }\r
+\r
+       // Init the QuickButton image structure with indexes to use\r
+       ButtonPictures[UseSlot].vobj = hVObject;\r
+       ButtonPictures[UseSlot].Grayed=Grayed;\r
+       ButtonPictures[UseSlot].OffNormal=OffNormal;\r
+       ButtonPictures[UseSlot].OffHilite=OffHilite;\r
+       ButtonPictures[UseSlot].OnNormal=OnNormal;\r
+       ButtonPictures[UseSlot].OnHilite=OnHilite;\r
+       ButtonPictures[UseSlot].fFlags = GUI_BTN_EXTERNAL_VOBJ;\r
+\r
+       // Fit the button size to the largest image in the set\r
+       MaxWidth=MaxHeight=0;\r
+       if(Grayed != BUTTON_NO_IMAGE)\r
+       {\r
+               pTrav = &(ButtonPictures[UseSlot].vobj->pETRLEObject[Grayed]);\r
+               ThisHeight = (UINT32)(pTrav->usHeight+pTrav->sOffsetY);\r
+               ThisWidth = (UINT32)(pTrav->usWidth+pTrav->sOffsetX);\r
+\r
+               if(MaxWidth<ThisWidth)\r
+                       MaxWidth=ThisWidth;\r
+               if(MaxHeight<ThisHeight)\r
+                       MaxHeight=ThisHeight;\r
+       }\r
+\r
+       if(OffNormal != BUTTON_NO_IMAGE)\r
+       {\r
+               pTrav = &(ButtonPictures[UseSlot].vobj->pETRLEObject[OffNormal]);\r
+               ThisHeight = (UINT32)(pTrav->usHeight+pTrav->sOffsetY);\r
+               ThisWidth = (UINT32)(pTrav->usWidth+pTrav->sOffsetX);\r
+\r
+               if(MaxWidth<ThisWidth)\r
+                       MaxWidth=ThisWidth;\r
+               if(MaxHeight<ThisHeight)\r
+                       MaxHeight=ThisHeight;\r
+       }\r
+\r
+       if(OffHilite != BUTTON_NO_IMAGE)\r
+       {\r
+               pTrav = &(ButtonPictures[UseSlot].vobj->pETRLEObject[OffHilite]);\r
+               ThisHeight = (UINT32)(pTrav->usHeight+pTrav->sOffsetY);\r
+               ThisWidth = (UINT32)(pTrav->usWidth+pTrav->sOffsetX);\r
+\r
+               if(MaxWidth<ThisWidth)\r
+                       MaxWidth=ThisWidth;\r
+               if(MaxHeight<ThisHeight)\r
+                       MaxHeight=ThisHeight;\r
+       }\r
+\r
+       if(OnNormal != BUTTON_NO_IMAGE)\r
+       {\r
+               pTrav = &(ButtonPictures[UseSlot].vobj->pETRLEObject[OnNormal]);\r
+               ThisHeight = (UINT32)(pTrav->usHeight+pTrav->sOffsetY);\r
+               ThisWidth = (UINT32)(pTrav->usWidth+pTrav->sOffsetX);\r
+\r
+               if(MaxWidth<ThisWidth)\r
+                       MaxWidth=ThisWidth;\r
+               if(MaxHeight<ThisHeight)\r
+                       MaxHeight=ThisHeight;\r
+       }\r
+\r
+       if(OnHilite != BUTTON_NO_IMAGE)\r
+       {\r
+               pTrav = &(ButtonPictures[UseSlot].vobj->pETRLEObject[OnHilite]);\r
+               ThisHeight = (UINT32)(pTrav->usHeight+pTrav->sOffsetY);\r
+               ThisWidth = (UINT32)(pTrav->usWidth+pTrav->sOffsetX);\r
+\r
+               if(MaxWidth<ThisWidth)\r
+                       MaxWidth=ThisWidth;\r
+               if(MaxHeight<ThisHeight)\r
+                       MaxHeight=ThisHeight;\r
+       }\r
+\r
+       // Set the width and height for this image set\r
+       ButtonPictures[UseSlot].MaxHeight=MaxHeight;\r
+       ButtonPictures[UseSlot].MaxWidth=MaxWidth;\r
+\r
+       // return the image slot number\r
+       ButtonPicsLoaded++;\r
+       return(UseSlot);\r
+}\r
+\r
+\r
+\r
+//=============================================================================\r
+//     SetButtonDestBuffer\r
+//\r
+//     Sets the destination buffer for all button blits.\r
+//\r
+BOOLEAN SetButtonDestBuffer(UINT32 DestBuffer)\r
+{\r
+       if(DestBuffer != BUTTON_USE_DEFAULT)\r
+               ButtonDestBuffer = DestBuffer;\r
+\r
+       return(TRUE);\r
+}\r
+\r
+\r
+\r
+//Removes a QuickButton image from the system.\r
+void UnloadButtonImage(INT32 Index)\r
+{\r
+       INT32 x;\r
+       BOOLEAN fDone;\r
+\r
+       if( Index < 0 || Index >= MAX_BUTTON_PICS )\r
+       {\r
+               sprintf( str, "Attempting to UnloadButtonImage with out of range index %d.", Index );\r
+               AssertMsg( 0, str );\r
+       }\r
+\r
+       if( !ButtonPictures[ Index ].vobj )\r
+       {\r
+               #ifdef BUTTONSYSTEM_DEBUGGING\r
+               if( gfIgnoreShutdownAssertions )\r
+               #endif\r
+                       return;\r
+               AssertMsg( 0, "Attempting to UnloadButtonImage that has a null vobj (already deleted).");\r
+       }\r
+\r
+       // If this is a duplicated button image, then don't trash the vobject\r
+       if(ButtonPictures[Index].fFlags & GUI_BTN_DUPLICATE_VOBJ || ButtonPictures[Index].fFlags & GUI_BTN_EXTERNAL_VOBJ)\r
+       {\r
+               ButtonPictures[Index].vobj = NULL;\r
+               ButtonPicsLoaded--;\r
+       }\r
+       else\r
+       {\r
+               // Deleting a non-duplicate, so see if any dups present. if so, then\r
+               // convert one of them to an original!\r
+\r
+               fDone = FALSE;\r
+               for( x = 0; x < MAX_BUTTON_PICS && !fDone; x++ )\r
+               {\r
+                       if( (x != Index) && (ButtonPictures[x].vobj == ButtonPictures[Index].vobj) )\r
+                       {\r
+                               if ( ButtonPictures[x].fFlags & GUI_BTN_DUPLICATE_VOBJ )\r
+                               {\r
+                                       // If we got here, then we got a duplicate object of the one we\r
+                                       // want to delete, so convert it to an original!\r
+                                       ButtonPictures[x].fFlags &= (~GUI_BTN_DUPLICATE_VOBJ);\r
+\r
+                                       // Now remove this button, but not it's vobject\r
+                                       ButtonPictures[Index].vobj = NULL;\r
+\r
+                                       fDone = TRUE;\r
+                                       ButtonPicsLoaded--;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       // If image slot isn't empty, delete the image\r
+       if(ButtonPictures[Index].vobj != NULL)\r
+       {\r
+               DeleteVideoObject(ButtonPictures[Index].vobj);\r
+               ButtonPictures[Index].vobj = NULL;\r
+               ButtonPicsLoaded--;\r
+       }\r
+}\r
+\r
+\r
+\r
+//=============================================================================\r
+//     EnableButton\r
+//\r
+//     Enables an already created button.\r
+//\r
+BOOLEAN EnableButton( INT32 iButtonID )\r
+{\r
+       GUI_BUTTON *b;\r
+       UINT32 OldState;\r
+\r
+       if( iButtonID < 0 || iButtonID >= MAX_BUTTONS )\r
+       {\r
+               sprintf( str, "Attempting to EnableButton with out of range buttonID %d.", iButtonID );\r
+               AssertMsg( 0, str );\r
+       }\r
+\r
+       b = ButtonList[ iButtonID ];\r
+\r
+       // If button exists, set the ENABLED flag\r
+       if( b )\r
+       {\r
+               OldState = b->uiFlags & BUTTON_ENABLED;\r
+               b->uiFlags |= ( BUTTON_ENABLED | BUTTON_DIRTY );\r
+       }\r
+       else\r
+               OldState = 0;\r
+\r
+\r
+       // Return previous ENABLED state of this button\r
+       return((OldState==BUTTON_ENABLED)?TRUE:FALSE);\r
+}\r
+\r
+\r
+\r
+//=============================================================================\r
+//     DisableButton\r
+//\r
+//     Disables a button. The button remains in the system list, and can be\r
+//     reactivated by calling EnableButton.\r
+//\r
+//     Diabled buttons will appear "grayed out" on the screen (unless the\r
+//     graphics for such are not available).\r
+//\r
+BOOLEAN DisableButton(INT32 iButtonID )\r
+{\r
+       GUI_BUTTON *b;\r
+       UINT32 OldState;\r
+\r
+       if( iButtonID < 0 || iButtonID >= MAX_BUTTONS )\r
+       {\r
+               sprintf( str, "Attempting to DisableButton with out of range buttonID %d.", iButtonID );\r
+               AssertMsg( 0, str );\r
+       }\r
+\r
+       b = ButtonList[ iButtonID ];\r
+\r
+       // If button exists, reset the ENABLED flag\r
+       if( b )\r
+       {\r
+               OldState = b->uiFlags & BUTTON_ENABLED;\r
+               b->uiFlags &= (~BUTTON_ENABLED);\r
+               b->uiFlags |= BUTTON_DIRTY;\r
+       }\r
+       else\r
+               OldState = 0;\r
+\r
+       // Return previous ENABLED state of button\r
+       return((OldState==BUTTON_ENABLED)?TRUE:FALSE);\r
+}\r
+\r
+\r
+\r
+//=============================================================================\r
+//     InitializeButtonImageManager\r
+//\r
+//     Initializes the button image sub-system. This function is called by\r
+//     InitButtonSystem.\r
+//\r
+BOOLEAN InitializeButtonImageManager(INT32 DefaultBuffer, INT32 DefaultPitch, INT32 DefaultBPP)\r
+{\r
+       VOBJECT_DESC    vo_desc;\r
+       UINT8 Pix;\r
+       int x;\r
+\r
+       // Set up the default settings\r
+       if(DefaultBuffer != BUTTON_USE_DEFAULT)\r
+               ButtonDestBuffer = (UINT32)DefaultBuffer;\r
+       else\r
+               ButtonDestBuffer = FRAME_BUFFER;\r
+\r
+       if(DefaultPitch != BUTTON_USE_DEFAULT)\r
+               ButtonDestPitch = (UINT32)DefaultPitch;\r
+       else\r
+               ButtonDestPitch = 640*2;\r
+\r
+       if(DefaultBPP != BUTTON_USE_DEFAULT)\r
+               ButtonDestBPP = (UINT32)DefaultBPP;\r
+       else\r
+               ButtonDestBPP = 16;\r
+\r
+       // Blank out all QuickButton images\r
+       for(x=0;x<MAX_BUTTON_PICS;x++)\r
+       {\r
+               ButtonPictures[x].vobj=NULL;\r
+               ButtonPictures[x].Grayed = -1;\r
+               ButtonPictures[x].OffNormal = -1;\r
+               ButtonPictures[x].OffHilite = -1;\r
+               ButtonPictures[x].OnNormal = -1;\r
+               ButtonPictures[x].OnHilite = -1;\r
+       }\r
+       ButtonPicsLoaded = 0;\r
+\r
+       // Blank out all Generic button data\r
+       for(x=0;x<MAX_GENERIC_PICS;x++)\r
+       {\r
+               GenericButtonGrayed[x]=NULL;\r
+               GenericButtonOffNormal[x]=NULL;\r
+               GenericButtonOffHilite[x]=NULL;\r
+               GenericButtonOnNormal[x]=NULL;\r
+               GenericButtonOnHilite[x]=NULL;\r
+               GenericButtonBackground[x]=NULL;\r
+               GenericButtonBackgroundIndex[x]=0;\r
+               GenericButtonFillColors[x]=0;\r
+               GenericButtonBackgroundIndex[x]=0;\r
+               GenericButtonOffsetX[x]=0;\r
+               GenericButtonOffsetY[x]=0;\r
+       }\r
+\r
+       // Blank out all icon images\r
+       for(x=0;x<MAX_BUTTON_ICONS;x++)\r
+               GenericButtonIcons[x]=NULL;\r
+\r
+       // Load the default generic button images\r
+       vo_desc.fCreateFlags = VOBJECT_CREATE_FROMFILE;\r
+       strcpy(vo_desc.ImageFile, DEFAULT_GENERIC_BUTTON_OFF);\r
+\r
+       if((GenericButtonOffNormal[0] = CreateVideoObject(&vo_desc)) == NULL)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, "Couldn't create VOBJECT for "DEFAULT_GENERIC_BUTTON_OFF);\r
+               return(FALSE);\r
+       }\r
+\r
+       vo_desc.fCreateFlags = VOBJECT_CREATE_FROMFILE;\r
+       strcpy(vo_desc.ImageFile, DEFAULT_GENERIC_BUTTON_ON);\r
+\r
+       if((GenericButtonOnNormal[0] = CreateVideoObject(&vo_desc)) == NULL)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, "Couldn't create VOBJECT for "DEFAULT_GENERIC_BUTTON_ON);\r
+               return(FALSE);\r
+       }\r
+\r
+       // Load up the off hilite and on hilite images. We won't check for errors because if the file\r
+       // doesn't exists, the system simply ignores that file. These are only here as extra images, they\r
+       // aren't required for operation (only OFF Normal and ON Normal are required).\r
+       vo_desc.fCreateFlags = VOBJECT_CREATE_FROMFILE;\r
+       strcpy(vo_desc.ImageFile, DEFAULT_GENERIC_BUTTON_OFF_HI);\r
+       GenericButtonOffHilite[0] = CreateVideoObject(&vo_desc);\r
+\r
+       vo_desc.fCreateFlags = VOBJECT_CREATE_FROMFILE;\r
+       strcpy(vo_desc.ImageFile, DEFAULT_GENERIC_BUTTON_ON_HI);\r
+       GenericButtonOnHilite[0] = CreateVideoObject(&vo_desc);\r
+\r
+       Pix=0;\r
+       if(!GetETRLEPixelValue(&Pix,GenericButtonOffNormal[0],8,0,0))\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, "Couldn't get generic button's background pixel value");\r
+               return(FALSE);\r
+       }\r
+\r
+       if(GETPIXELDEPTH()==16)\r
+               GenericButtonFillColors[0]=GenericButtonOffNormal[0]->p16BPPPalette[Pix];\r
+       else if(GETPIXELDEPTH()==8)\r
+               GenericButtonFillColors[0]=COLOR_DKGREY;\r
+\r
+       return(TRUE);\r
+}\r
+\r
+\r
+\r
+//=============================================================================\r
+//     FindFreeGenericSlot\r
+//\r
+//     Finds the next available slot for generic (TEXT and/or ICONIC) buttons.\r
+//\r
+INT16 FindFreeGenericSlot(void)\r
+{\r
+       INT16 slot,x;\r
+\r
+       slot=BUTTON_NO_SLOT;\r
+       for(x=0;x<MAX_GENERIC_PICS && slot<0;x++)\r
+       {\r
+               if(GenericButtonOffNormal[x]==NULL)\r
+                       slot=x;\r
+       }\r
+\r
+       return(slot);\r
+}\r
+\r
+\r
+\r
+//=============================================================================\r
+//     FindFreeIconSlot\r
+//\r
+//     Finds the next available slot for button icon images.\r
+//\r
+INT16 FindFreeIconSlot(void)\r
+{\r
+       INT16 slot,x;\r
+\r
+       slot=BUTTON_NO_SLOT;\r
+       for(x=0;x<MAX_BUTTON_ICONS && slot<0;x++)\r
+       {\r
+               if(GenericButtonIcons[x]==NULL)\r
+                       slot=x;\r
+       }\r
+\r
+       return(slot);\r
+}\r
+\r
+\r
+\r
+//=============================================================================\r
+//     LoadGenericButtonIcon\r
+//\r
+//     Loads an image file for use as a button icon.\r
+//\r
+INT16 LoadGenericButtonIcon(UINT8 *filename)\r
+{\r
+       INT16 ImgSlot;\r
+       VOBJECT_DESC    vo_desc;\r
+\r
+       AssertMsg(filename != BUTTON_NO_FILENAME, "Attempting to LoadGenericButtonIcon() with null filename.");\r
+\r
+       // Get slot for icon image\r
+       if((ImgSlot=FindFreeIconSlot()) == BUTTON_NO_SLOT)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, "LoadGenericButtonIcon: Out of generic button icon slots");\r
+               return(-1);\r
+       }\r
+\r
+       // Load the icon\r
+       vo_desc.fCreateFlags = VOBJECT_CREATE_FROMFILE;\r
+       strcpy(vo_desc.ImageFile, filename);\r
+\r
+       if((GenericButtonIcons[ImgSlot] = CreateVideoObject(&vo_desc)) == NULL)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, String("LoadGenericButtonIcon: Couldn't create VOBJECT for %s",filename));\r
+               return(-1);\r
+       }\r
+\r
+       // Return the slot number\r
+       return(ImgSlot);\r
+}\r
+\r
+//=============================================================================\r
+//     UnloadGenericButtonIcon\r
+//\r
+//     Removes a button icon graphic from the system\r
+//\r
+BOOLEAN UnloadGenericButtonIcon(INT16 GenImg)\r
+{\r
+       if( GenImg < 0 || GenImg >= MAX_BUTTON_ICONS  )\r
+       {\r
+               sprintf( str, "Attempting to UnloadGenericButtonIcon with out of range index %d.", GenImg );\r
+               AssertMsg( 0, str );\r
+       }\r
+\r
+       if( !GenericButtonIcons[ GenImg ] )\r
+       {\r
+               #ifdef BUTTONSYSTEM_DEBUGGING\r
+               if( gfIgnoreShutdownAssertions )\r
+               #endif\r
+                       return FALSE;\r
+               AssertMsg( 0, "Attempting to UnloadGenericButtonIcon that has no icon (already deleted)." );\r
+       }\r
+       // If an icon is present in the slot, remove it.\r
+       DeleteVideoObject(GenericButtonIcons[GenImg]);\r
+       GenericButtonIcons[GenImg]=NULL;\r
+       return TRUE;\r
+}\r
+\r
+\r
+\r
+//=============================================================================\r
+//     UnloadGenericButtonImage\r
+//\r
+//     Removes the images associated with a generic button. Except the icon\r
+//     image of iconic buttons. See above.\r
+//\r
+BOOLEAN UnloadGenericButtonImage(INT16 GenImg)\r
+{\r
+       BOOLEAN fDeletedSomething = FALSE;\r
+       if( GenImg < 0 || GenImg >= MAX_GENERIC_PICS  )\r
+       {\r
+               sprintf( str, "Attempting to UnloadGenericButtonImage with out of range index %d.", GenImg );\r
+               AssertMsg( 0, str );\r
+       }\r
+\r
+       // For each possible image type in a generic button, check if it's\r
+       // present, and if so, remove it.\r
+       if(GenericButtonGrayed[GenImg]!=NULL)\r
+       {\r
+               DeleteVideoObject(GenericButtonGrayed[GenImg]);\r
+               GenericButtonGrayed[GenImg]=NULL;\r
+               fDeletedSomething = TRUE;\r
+       }\r
+\r
+       if(GenericButtonOffNormal[GenImg]!=NULL)\r
+       {\r
+               DeleteVideoObject(GenericButtonOffNormal[GenImg]);\r
+               GenericButtonOffNormal[GenImg]=NULL;\r
+               fDeletedSomething = TRUE;\r
+       }\r
+\r
+       if(GenericButtonOffHilite[GenImg]!=NULL)\r
+       {\r
+               DeleteVideoObject(GenericButtonOffHilite[GenImg]);\r
+               GenericButtonOffHilite[GenImg]=NULL;\r
+               fDeletedSomething = TRUE;\r
+       }\r
+\r
+       if(GenericButtonOnNormal[GenImg]!=NULL)\r
+       {\r
+               DeleteVideoObject(GenericButtonOnNormal[GenImg]);\r
+               GenericButtonOnNormal[GenImg]=NULL;\r
+               fDeletedSomething = TRUE;\r
+       }\r
+\r
+       if(GenericButtonOnHilite[GenImg]!=NULL)\r
+       {\r
+               DeleteVideoObject(GenericButtonOnHilite[GenImg]);\r
+               GenericButtonOnHilite[GenImg]=NULL;\r
+               fDeletedSomething = TRUE;\r
+       }\r
+\r
+       if(GenericButtonBackground[GenImg]!=NULL)\r
+       {\r
+               DeleteVideoObject(GenericButtonBackground[GenImg]);\r
+               GenericButtonBackground[GenImg]=NULL;\r
+               fDeletedSomething = TRUE;\r
+       }\r
+\r
+       #ifdef BUTTONSYSTEM_DEBUGGING\r
+       if( !gfIgnoreShutdownAssertions && !fDeletedSomething )\r
+               AssertMsg( 0, "Attempting to UnloadGenericButtonImage that has no images (already deleted)." );\r
+       #endif\r
+\r
+       // Reset the remaining variables\r
+       GenericButtonFillColors[GenImg]=0;\r
+       GenericButtonBackgroundIndex[GenImg]=0;\r
+       GenericButtonOffsetX[GenImg]=0;\r
+       GenericButtonOffsetY[GenImg]=0;\r
+\r
+       return(TRUE);\r
+}\r
+\r
+\r
+\r
+//=============================================================================\r
+//     LoadGenericButtonImages\r
+//\r
+//     Loads the image files required for displaying a generic button.\r
+//\r
+INT16 LoadGenericButtonImages(UINT8 *GrayName,UINT8 *OffNormName,UINT8 *OffHiliteName,UINT8 *OnNormName,UINT8 *OnHiliteName,UINT8 *BkGrndName,INT16 Index,INT16 OffsetX, INT16 OffsetY)\r
+{\r
+       INT16 ImgSlot;\r
+       VOBJECT_DESC    vo_desc;\r
+       UINT8 Pix;\r
+\r
+       // if the images for Off-Normal and On-Normal don't exist, abort call\r
+       if((OffNormName == BUTTON_NO_FILENAME) || (OnNormName == BUTTON_NO_FILENAME))\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, "LoadGenericButtonImages: No filenames for OFFNORMAL and/or ONNORMAL images");\r
+               return(-1);\r
+       }\r
+\r
+       // Get a slot number for these images\r
+       if((ImgSlot=FindFreeGenericSlot()) == -1)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, "LoadGenericButtonImages: Out of generic button slots");\r
+               return(-1);\r
+       }\r
+\r
+       // Load the image for the Off-Normal button state (required)\r
+       vo_desc.fCreateFlags = VOBJECT_CREATE_FROMFILE;\r
+       strcpy(vo_desc.ImageFile, OffNormName);\r
+\r
+       if((GenericButtonOffNormal[ImgSlot] = CreateVideoObject(&vo_desc)) == NULL)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, String("LoadGenericButtonImages: Couldn't create VOBJECT for %s",OffNormName));\r
+               return(-1);\r
+       }\r
+\r
+       // Load the image for the On-Normal button state (required)\r
+       vo_desc.fCreateFlags = VOBJECT_CREATE_FROMFILE;\r
+       strcpy(vo_desc.ImageFile, OnNormName);\r
+\r
+       if((GenericButtonOnNormal[ImgSlot] = CreateVideoObject(&vo_desc)) == NULL)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, String("LoadGenericButtonImages: Couldn't create VOBJECT for %s",OnNormName));\r
+               return(-1);\r
+       }\r
+\r
+       // For the optional button state images, see if a filename was given, and\r
+       // if so, load it.\r
+\r
+       if(GrayName != BUTTON_NO_FILENAME)\r
+       {\r
+               vo_desc.fCreateFlags = VOBJECT_CREATE_FROMFILE;\r
+               strcpy(vo_desc.ImageFile, GrayName);\r
+\r
+               if((GenericButtonGrayed[ImgSlot] = CreateVideoObject(&vo_desc)) == NULL)\r
+               {\r
+                       DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, String("LoadGenericButtonImages: Couldn't create VOBJECT for %s",GrayName));\r
+                       return(-1);\r
+               }\r
+       }\r
+       else\r
+               GenericButtonGrayed[ImgSlot] = NULL;\r
+\r
+       if(OffHiliteName != BUTTON_NO_FILENAME)\r
+       {\r
+               vo_desc.fCreateFlags = VOBJECT_CREATE_FROMFILE;\r
+               strcpy(vo_desc.ImageFile, OffHiliteName);\r
+\r
+               if((GenericButtonOffHilite[ImgSlot] = CreateVideoObject(&vo_desc)) == NULL)\r
+               {\r
+                       DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, String("LoadGenericButtonImages: Couldn't create VOBJECT for %s",OffHiliteName));\r
+                       return(-1);\r
+               }\r
+       }\r
+       else\r
+               GenericButtonOffHilite[ImgSlot] = NULL;\r
+\r
+       if(OnHiliteName != BUTTON_NO_FILENAME)\r
+       {\r
+               vo_desc.fCreateFlags = VOBJECT_CREATE_FROMFILE;\r
+               strcpy(vo_desc.ImageFile, OnHiliteName);\r
+\r
+               if((GenericButtonOnHilite[ImgSlot] = CreateVideoObject(&vo_desc)) == NULL)\r
+               {\r
+                       DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, String("LoadGenericButtonImages: Couldn't create VOBJECT for %s",OnHiliteName));\r
+                       return(-1);\r
+               }\r
+       }\r
+       else\r
+               GenericButtonOnHilite[ImgSlot] = NULL;\r
+\r
+       if(BkGrndName != BUTTON_NO_FILENAME)\r
+       {\r
+               vo_desc.fCreateFlags = VOBJECT_CREATE_FROMFILE;\r
+               strcpy(vo_desc.ImageFile, BkGrndName);\r
+\r
+               if((GenericButtonBackground[ImgSlot] = CreateVideoObject(&vo_desc)) == NULL)\r
+               {\r
+                       DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, String("LoadGenericButtonImages: Couldn't create VOBJECT for %s",BkGrndName));\r
+                       return(-1);\r
+               }\r
+       }\r
+       else\r
+               GenericButtonBackground[ImgSlot] = NULL;\r
+\r
+       GenericButtonBackgroundIndex[ImgSlot]=Index;\r
+\r
+       // Get the background fill color from the last (9th) sub-image in the\r
+       // Off-Normal image.\r
+       Pix=0;\r
+       if(!GetETRLEPixelValue(&Pix,GenericButtonOffNormal[ImgSlot],8,0,0))\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER, DBG_LEVEL_0, "LoadGenericButtonImages: Couldn't get generic button's background pixel value");\r
+               return(-1);\r
+       }\r
+\r
+       GenericButtonFillColors[ImgSlot]=GenericButtonOffNormal[ImgSlot]->p16BPPPalette[Pix];\r
+\r
+       // Set the button's background image adjustement offsets\r
+       GenericButtonOffsetX[ImgSlot]=OffsetX;\r
+       GenericButtonOffsetY[ImgSlot]=OffsetY;\r
+\r
+       // Return the slot number used.\r
+       return(ImgSlot);\r
+}\r
+\r
+\r
+//=============================================================================\r
+//     ShutdownButtonImageManager\r
+//\r
+//     Cleans up, and shuts down the button image manager sub-system.\r
+//\r
+//     This function is called by ShutdownButtonSystem.\r
+//\r
+void ShutdownButtonImageManager(void)\r
+{\r
+       int x;\r
+\r
+       #ifdef BUTTONSYSTEM_DEBUGGING\r
+       gfIgnoreShutdownAssertions = TRUE;\r
+       #endif\r
+\r
+       // Remove all QuickButton images\r
+       for(x=0;x<MAX_BUTTON_PICS;x++)\r
+               UnloadButtonImage(x);\r
+\r
+       // Remove all GenericButton images\r
+       for(x=0;x<MAX_GENERIC_PICS;x++)\r
+       {\r
+               if(GenericButtonGrayed[x]!=NULL)\r
+               {\r
+                       DeleteVideoObject(GenericButtonGrayed[x]);\r
+                       GenericButtonGrayed[x]=NULL;\r
+               }\r
+\r
+               if(GenericButtonOffNormal[x]!=NULL)\r
+               {\r
+                       DeleteVideoObject(GenericButtonOffNormal[x]);\r
+                       GenericButtonOffNormal[x]=NULL;\r
+               }\r
+\r
+               if(GenericButtonOffHilite[x]!=NULL)\r
+               {\r
+                       DeleteVideoObject(GenericButtonOffHilite[x]);\r
+                       GenericButtonOffHilite[x]=NULL;\r
+               }\r
+\r
+               if(GenericButtonOnNormal[x]!=NULL)\r
+               {\r
+                       DeleteVideoObject(GenericButtonOnNormal[x]);\r
+                       GenericButtonOnNormal[x]=NULL;\r
+               }\r
+\r
+               if(GenericButtonOnHilite[x]!=NULL)\r
+               {\r
+                       DeleteVideoObject(GenericButtonOnHilite[x]);\r
+                       GenericButtonOnHilite[x]=NULL;\r
+               }\r
+\r
+               if(GenericButtonBackground[x]!=NULL)\r
+               {\r
+                       DeleteVideoObject(GenericButtonBackground[x]);\r
+                       GenericButtonBackground[x]=NULL;\r
+               }\r
+\r
+               GenericButtonFillColors[x]=0;\r
+               GenericButtonBackgroundIndex[x]=0;\r
+               GenericButtonOffsetX[x]=0;\r
+               GenericButtonOffsetY[x]=0;\r
+       }\r
+\r
+       // Remove all button icons\r
+       for(x=0;x<MAX_BUTTON_ICONS;x++)\r
+       {\r
+               if(GenericButtonIcons[x]!=NULL)\r
+                       GenericButtonIcons[x]=NULL;\r
+       }\r
+}\r
+\r
+\r
+\r
+//=============================================================================\r
+//     InitButtonSystem\r
+//\r
+//     Initializes the GUI button system for use. Must be called before using\r
+//     any other button functions.\r
+//\r
+BOOLEAN InitButtonSystem(void)\r
+{\r
+       INT32 x;\r
+\r
+       #ifdef BUTTONSYSTEM_DEBUGGING\r
+       gfIgnoreShutdownAssertions = FALSE;\r
+       #endif\r
+\r
+       RegisterDebugTopic(TOPIC_BUTTON_HANDLER,"Button System & Button Image Manager");\r
+\r
+       // Clear out button list\r
+       for(x=0;x<MAX_BUTTONS;x++)\r
+       {\r
+               ButtonList[x]=NULL;\r
+       }\r
+\r
+       // Initialize the button image manager sub-system\r
+       if(InitializeButtonImageManager(-1,-1,-1) == FALSE)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER,DBG_LEVEL_0,"Failed button image manager init\n");\r
+               return(FALSE);\r
+       }\r
+\r
+       ButtonsInList = 0;\r
+\r
+       return(TRUE);\r
+}\r
+\r
+\r
+\r
+//=============================================================================\r
+//     ShutdownButtonSystem\r
+//\r
+//     Shuts down and cleans up the GUI button system. Must be called before\r
+//     exiting the program. Button functions should not be used after calling\r
+//     this function.\r
+//\r
+void ShutdownButtonSystem(void)\r
+{\r
+       int x;\r
+\r
+       // Kill off all buttons in the system\r
+       for(x=0;x<MAX_BUTTONS;x++)\r
+       {\r
+               if(ButtonList[x]!=NULL)\r
+                       RemoveButton(x);\r
+       }\r
+       // Shutdown the button image manager sub-system\r
+       ShutdownButtonImageManager();\r
+\r
+       UnRegisterDebugTopic(TOPIC_BUTTON_HANDLER,"Button System & Button Image Manager");\r
+}\r
+\r
+void RemoveButtonsMarkedForDeletion()\r
+{\r
+       INT32 i;\r
+       for( i = 0; i < MAX_BUTTONS; i++ )\r
+       {\r
+               if( ButtonList[ i ] && ButtonList[ i ]->uiFlags & BUTTON_DELETION_PENDING )\r
+               {\r
+                       RemoveButton( i );\r
+               }\r
+       }\r
+}\r
+\r
+//=============================================================================\r
+//     RemoveButton\r
+//\r
+//     Removes a button from the system's list. All memory associated with the\r
+//     button is released.\r
+//\r
+void RemoveButton(INT32 iButtonID)\r
+{\r
+       GUI_BUTTON *b;\r
+\r
+       if( iButtonID < 0 || iButtonID >= MAX_BUTTONS )\r
+       {\r
+               sprintf( str, "Attempting to RemoveButton with out of range buttonID %d.", iButtonID );\r
+               AssertMsg( 0, str );\r
+       }\r
+\r
+       b = ButtonList[ iButtonID ];\r
+\r
+       // If button exists...\r
+       if( !b )\r
+       {\r
+               #ifdef BUTTONSYSTEM_DEBUGGING\r
+               if( gfIgnoreShutdownAssertions )\r
+               #endif\r
+                       return;\r
+               AssertMsg( 0, "Attempting to remove a button that has already been deleted." );\r
+       }\r
+\r
+       //If we happen to be in the middle of a callback, and attempt to delete a button,\r
+       //like deleting a node during list processing, then we delay it till after the callback\r
+       //is completed.\r
+       if( gfDelayButtonDeletion )\r
+       {\r
+               b->uiFlags |= BUTTON_DELETION_PENDING;\r
+               gfPendingButtonDeletion = TRUE;\r
+               return;\r
+       }\r
+\r
+       //Kris:\r
+       if( b->uiFlags & BUTTON_SELFDELETE_IMAGE )\r
+       { //checkboxes and simple create buttons have their own graphics associated with them,\r
+               //and it is handled internally.  We delete it here.  This provides the advantage of less\r
+               //micromanagement, but with the disadvantage of wasting more memory if you have lots of\r
+               //buttons using the same graphics.\r
+               UnloadButtonImage( b->ImageNum );\r
+       }\r
+\r
+       // ...kill it!!!\r
+       MSYS_RemoveRegion(&b->Area);\r
+\r
+#ifdef _JA2_RENDER_DIRTY\r
+       if ( b->uiFlags & BUTTON_SAVEBACKGROUND )\r
+       {\r
+               FreeBackgroundRectPending(b->BackRect);\r
+       }\r
+#endif\r
+\r
+       // Get rid of the text string\r
+       if (b->string != NULL)\r
+               MemFree( b->string );\r
+\r
+       if( b == gpAnchoredButton )\r
+               gpAnchoredButton = NULL;\r
+       if( b == gpPrevAnchoredButton )\r
+               gpPrevAnchoredButton = NULL;\r
+\r
+       MemFree(b);\r
+       b=NULL;\r
+       ButtonList[ iButtonID ] = NULL;\r
+}\r
+\r
+\r
+\r
+//=============================================================================\r
+//     GetNextButtonNumber\r
+//\r
+//     Finds the next available button slot.\r
+//\r
+INT32 GetNextButtonNumber(void)\r
+{\r
+       INT32 x;\r
+\r
+       for(x=0;x<MAX_BUTTONS;x++)\r
+       {\r
+               if(ButtonList[x] == NULL)\r
+                       return(x);\r
+       }\r
+\r
+       return(BUTTON_NO_SLOT);\r
+}\r
+\r
+\r
+\r
+//=============================================================================\r
+//     ResizeButton\r
+//\r
+//     Changes the size of a generic button.\r
+//\r
+//     QuickButtons cannot be resized, therefore this function ignores the\r
+//     call if a QuickButton is given.\r
+//\r
+void ResizeButton(INT32 iButtonID,INT16 w, INT16 h)\r
+{\r
+       GUI_BUTTON *b;\r
+       INT32   xloc,yloc;\r
+\r
+       if( iButtonID < 0 || iButtonID >= MAX_BUTTONS )\r
+       {\r
+               sprintf( str, "Attempting to resize button with out of range buttonID %d.", iButtonID );\r
+               AssertMsg( 0, str );\r
+       }\r
+\r
+       // if button size is too small, adjust it.\r
+       if(w<4)\r
+               w=4;\r
+       if(h<3)\r
+               h=3;\r
+\r
+       b = ButtonList[ iButtonID ];\r
+\r
+       if( !b )\r
+       {\r
+               sprintf( str, "Attempting to resize deleted button with buttonID %d", iButtonID );\r
+               AssertMsg( 0, str );\r
+       }\r
+\r
+       // If this is a QuickButton, ignore this call\r
+       if((b->uiFlags & BUTTON_TYPES) == BUTTON_QUICK)\r
+               return;\r
+\r
+       // Get current button screen location\r
+       xloc=b->XLoc;\r
+       yloc=b->YLoc;\r
+\r
+       // Set the new MOUSE_REGION area values to reflect change in size.\r
+       b->Area.RegionTopLeftX=(UINT16)xloc;\r
+       b->Area.RegionTopLeftY=(UINT16)yloc;\r
+       b->Area.RegionBottomRightX=(UINT16)(xloc+w);\r
+       b->Area.RegionBottomRightY=(UINT16)(yloc+h);\r
+       b->uiFlags |= BUTTON_DIRTY;\r
+\r
+#ifdef _JA2_RENDER_DIRTY\r
+       if ( b->uiFlags & BUTTON_SAVEBACKGROUND )\r
+       {\r
+               FreeBackgroundRectPending(b->BackRect);\r
+               b->BackRect = RegisterBackgroundRect(BGND_FLAG_PERMANENT | BGND_FLAG_SAVERECT, NULL,\r
+                                       (INT16)xloc, (INT16)yloc, (INT16)(xloc+w), (INT16)(yloc+h) );\r
+       }\r
+#endif\r
+\r
+}\r
+\r
+\r
+\r
+//=============================================================================\r
+//     SetButtonPosition\r
+//\r
+//     Sets the position of a button on the screen. The position is relative\r
+//     to the top left corner of the button.\r
+//\r
+void SetButtonPosition( INT32 iButtonID ,INT16 x, INT16 y)\r
+{\r
+       GUI_BUTTON *b;\r
+       INT32   xloc,yloc,w,h;\r
+\r
+       if( iButtonID < 0 || iButtonID >= MAX_BUTTONS )\r
+       {\r
+               sprintf( str, "Attempting to set button position with out of range buttonID %d.", iButtonID );\r
+               AssertMsg( 0, str );\r
+       }\r
+\r
+       b=ButtonList[ iButtonID ];\r
+\r
+       if( !b )\r
+       {\r
+               sprintf( str, "Attempting to set button position with buttonID %d", iButtonID );\r
+               AssertMsg( 0, str );\r
+       }\r
+\r
+       // Get new screen position\r
+       xloc=(INT16)x;\r
+       yloc=(INT16)y;\r
+       // Compute current width and height of this button\r
+       w = b->Area.RegionBottomRightX - b->Area.RegionTopLeftX;\r
+       h = b->Area.RegionBottomRightY - b->Area.RegionTopLeftY;\r
+\r
+       // Set button to new location\r
+       b->XLoc=x;\r
+       b->YLoc=y;\r
+       // Set the buttons MOUSE_REGION to appropriate area\r
+       b->Area.RegionTopLeftX=(UINT16)xloc;\r
+       b->Area.RegionTopLeftY=(UINT16)yloc;\r
+       b->Area.RegionBottomRightX=(UINT16)(xloc+w);\r
+       b->Area.RegionBottomRightY=(UINT16)(yloc+h);\r
+       b->uiFlags |= BUTTON_DIRTY;\r
+\r
+#ifdef _JA2_RENDER_DIRTY\r
+       if ( b->uiFlags & BUTTON_SAVEBACKGROUND )\r
+       {\r
+               FreeBackgroundRectPending(b->BackRect);\r
+               b->BackRect = RegisterBackgroundRect(BGND_FLAG_PERMANENT | BGND_FLAG_SAVERECT, NULL,\r
+                                               (INT16)xloc, (INT16)yloc, (INT16)(xloc+w), (INT16)(yloc+h) );\r
+       }\r
+#endif\r
+\r
+}\r
+\r
+//=============================================================================\r
+//     SetButtonIcon\r
+//\r
+//     Sets the icon to be displayed on a IconicButton.\r
+//\r
+//     Calling this function with a button type other than Iconic has no effect.\r
+//\r
+INT32 SetButtonIcon( INT32 iButtonID, INT16 Icon, INT16 IconIndex )\r
+{\r
+       GUI_BUTTON *b;\r
+\r
+       if( iButtonID < 0 || iButtonID >= MAX_BUTTONS )\r
+       {\r
+               sprintf( str, "Attempting to set button icon with out of range buttonID %d.", iButtonID );\r
+               AssertMsg( 0, str );\r
+               return -1;\r
+       }\r
+       if( Icon < 0 || Icon >= MAX_BUTTON_ICONS )\r
+       {\r
+               sprintf( str, "Attempting to set button[%d] icon with out of range icon index %d.", iButtonID, Icon );\r
+               AssertMsg( 0, str );\r
+               return -1;\r
+       }\r
+\r
+       b = ButtonList[ iButtonID ];\r
+\r
+       if( !b )\r
+       {\r
+               sprintf( str, "Attempting to set deleted button icon with buttonID %d", iButtonID );\r
+               AssertMsg( 0, str );\r
+               return -1;\r
+       }\r
+\r
+       // If button isn't an icon button, ignore this call\r
+       if(((b->uiFlags & BUTTON_TYPES) == BUTTON_QUICK) ||\r
+                ((b->uiFlags & BUTTON_TYPES) == BUTTON_HOT_SPOT) ||\r
+                ((b->uiFlags & BUTTON_TYPES) == BUTTON_GENERIC))\r
+       {\r
+               return -1;\r
+       }\r
+\r
+       // Set the icon number and index to use for this button\r
+       b->iIconID = Icon;\r
+       b->usIconIndex = IconIndex;\r
+\r
+       return Icon;\r
+}\r
+\r
+\r
+\r
+//=============================================================================\r
+//     CreateIconButton\r
+//\r
+//     Creates an Iconic type button.\r
+//\r
+INT32 CreateIconButton(INT16 Icon,INT16 IconIndex,INT16 GenImg,INT16 xloc,INT16 yloc,INT16 w,INT16 h,INT32 Type,INT16 Priority,GUI_CALLBACK MoveCallback,GUI_CALLBACK ClickCallback)\r
+{\r
+       GUI_BUTTON *b;\r
+       INT32   ButtonNum;\r
+       INT32 BType,x;\r
+\r
+       if( xloc < 0 || yloc < 0 )\r
+       {\r
+               sprintf( str, "Attempting to CreateIconButton with invalid position of %d,%d", xloc, yloc );\r
+               AssertMsg( 0, str );\r
+       }\r
+       if( GenImg < -1 || GenImg >= MAX_GENERIC_PICS )\r
+       {\r
+               sprintf( str, "Attempting to CreateIconButton with out of range iconID %d.", GenImg );\r
+               AssertMsg( 0, str );\r
+       }\r
+\r
+       // if button size is too small, adjust it.\r
+       if(w<4)\r
+               w=4;\r
+       if(h<3)\r
+               h=3;\r
+\r
+       // Strip off any extraneous bits from button type\r
+       BType = Type & ( BUTTON_TYPE_MASK | BUTTON_NEWTOGGLE );\r
+\r
+       // Get a button number (slot) for this new button\r
+       if((ButtonNum = GetNextButtonNumber()) == BUTTON_NO_SLOT)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER,DBG_LEVEL_0,"CreateIconButton: No more button slots");\r
+               return(-1);\r
+       }\r
+\r
+       // Allocate memory for the GUI_BUTTON structure\r
+       if((b=(GUI_BUTTON *)MemAlloc(sizeof(GUI_BUTTON))) == NULL)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER,DBG_LEVEL_0,"CreateIconButton: Can't alloc mem for button struct");\r
+               return(-1);\r
+       }\r
+\r
+       // Init the values in the struct\r
+       b->uiFlags = BUTTON_DIRTY;\r
+       b->uiOldFlags = 0;\r
+       b->IDNum = ButtonNum;\r
+       b->XLoc = xloc;\r
+       b->YLoc = yloc;\r
+\r
+       if(GenImg<0)\r
+               b->ImageNum = 0;\r
+       else\r
+               b->ImageNum = GenImg;\r
+\r
+       for(x=0;x<4;x++)\r
+               b->UserData[x] = 0;\r
+       b->Group = -1;\r
+\r
+       b->bDefaultStatus = DEFAULT_STATUS_NONE;\r
+       b->bDisabledStyle = DISABLED_STYLE_DEFAULT;\r
+       //Init text\r
+       b->string = NULL;\r
+       b->usFont = 0;\r
+       b->fMultiColor=FALSE;\r
+       b->sForeColor = 0;\r
+       b->sWrappedWidth = -1;\r
+       b->sShadowColor = -1;\r
+       b->sForeColorDown = -1;\r
+       b->sShadowColorDown = -1;\r
+       b->sForeColorHilited = -1;\r
+       b->sShadowColorHilited = -1;\r
+       b->bJustification = BUTTON_TEXT_CENTER;\r
+       b->bTextXOffset = -1;\r
+       b->bTextYOffset = -1;\r
+       b->bTextXSubOffSet = 0;\r
+       b->bTextYSubOffSet = 0;\r
+       b->fShiftText = TRUE;\r
+       //Init icon\r
+       b->iIconID = Icon;\r
+       b->usIconIndex = IconIndex;\r
+       b->bIconXOffset = -1;\r
+       b->bIconYOffset = -1;\r
+       b->fShiftImage = TRUE;\r
+\r
+       // Set the click callback function (if any)\r
+       if(ClickCallback != BUTTON_NO_CALLBACK)\r
+       {\r
+               b->ClickCallback = ClickCallback;\r
+               BType |= BUTTON_CLICK_CALLBACK;\r
+       }\r
+       else\r
+               b->ClickCallback = BUTTON_NO_CALLBACK;\r
+\r
+       // Set the move callback function (if any)\r
+       if(MoveCallback != BUTTON_NO_CALLBACK)\r
+       {\r
+               b->MoveCallback = MoveCallback;\r
+               BType |= BUTTON_MOVE_CALLBACK;\r
+       }\r
+       else\r
+               b->MoveCallback = BUTTON_NO_CALLBACK;\r
+\r
+       // Define a mouse region for this button\r
+       MSYS_DefineRegion(&b->Area, (UINT16)xloc, (UINT16)yloc, (UINT16)(xloc+w), (UINT16)(yloc+h),\r
+                               (INT8)Priority, MSYS_STARTING_CURSORVAL, (MOUSE_CALLBACK)QuickButtonCallbackMMove, (MOUSE_CALLBACK)QuickButtonCallbackMButn);\r
+\r
+       // Link the mouse region to this button (for callback purposes)\r
+       MSYS_SetRegionUserData(&b->Area,0,ButtonNum);\r
+\r
+       // Set this button's flags\r
+       b->uiFlags |= ( BUTTON_ENABLED | BType | BUTTON_GENERIC );\r
+\r
+#ifdef _JA2_RENDER_DIRTY\r
+       b->BackRect = -1;\r
+#endif\r
+\r
+       // Add button to the button list\r
+       #ifdef BUTTONSYSTEM_DEBUGGING\r
+       AssertFailIfIdenticalButtonAttributesFound( b );\r
+       #endif\r
+       ButtonList[ButtonNum]=b;\r
+\r
+       SpecifyButtonSoundScheme( b->IDNum, BUTTON_SOUND_SCHEME_GENERIC );\r
+\r
+       // return this button's slot number\r
+       return(ButtonNum);\r
+}\r
+\r
+//Creates a generic button with text on it.\r
+INT32 CreateTextButton(UINT16 *string, UINT32 uiFont, INT16 sForeColor, INT16 sShadowColor, INT16 GenImg, INT16 xloc, INT16 yloc, INT16 w, INT16 h, INT32 Type, INT16 Priority,GUI_CALLBACK MoveCallback, GUI_CALLBACK ClickCallback)\r
+{\r
+       GUI_BUTTON *b;\r
+       INT32   ButtonNum;\r
+       INT32 BType,x;\r
+\r
+       if( xloc < 0 || yloc < 0 )\r
+       {\r
+               sprintf( str, "Attempting to CreateTextButton with invalid position of %d,%d", xloc, yloc );\r
+               AssertMsg( 0, str );\r
+       }\r
+       if( GenImg < -1 || GenImg >= MAX_GENERIC_PICS )\r
+       {\r
+               sprintf( str, "Attempting to CreateTextButton with out of range iconID %d.", GenImg );\r
+               AssertMsg( 0, str );\r
+       }\r
+\r
+       // if button size is too small, adjust it.\r
+       if(w<4)\r
+               w=4;\r
+       if(h<3)\r
+               h=3;\r
+\r
+       // Strip off any extraneous bits from button type\r
+       BType = Type & ( BUTTON_TYPE_MASK | BUTTON_NEWTOGGLE );\r
+\r
+       // Get a button number for this new button\r
+       if((ButtonNum = GetNextButtonNumber()) == BUTTON_NO_SLOT)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER,DBG_LEVEL_0,"CreateTextButton: No more button slots");\r
+               return(-1);\r
+       }\r
+\r
+       // Allocate memory for a GUI_BUTTON structure\r
+       if((b=(GUI_BUTTON *)MemAlloc(sizeof(GUI_BUTTON))) == NULL)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER,DBG_LEVEL_0,"CreateTextButton: Can't alloc mem for button struct");\r
+               return(-1);\r
+       }\r
+\r
+       // Allocate memory for the button's text string...\r
+       b->string = NULL;\r
+       if ( string && wcslen( string ) )\r
+       {\r
+               b->string = (UINT16*)MemAlloc( (wcslen(string)+1)*sizeof(UINT16) );\r
+               AssertMsg( b->string, "Out of memory error:  Couldn't allocate string in CreateTextButton." );\r
+               wcscpy( b->string, string );\r
+       }\r
+\r
+       // Init the button structure variables\r
+       b->uiFlags = BUTTON_DIRTY;\r
+       b->uiOldFlags = 0;\r
+       b->IDNum = ButtonNum;\r
+       b->XLoc = xloc;\r
+       b->YLoc = yloc;\r
+\r
+       if(GenImg<0)\r
+               b->ImageNum = 0;\r
+       else\r
+               b->ImageNum = GenImg;\r
+\r
+       for(x=0;x<4;x++)\r
+               b->UserData[x] = 0;\r
+       b->Group = -1;\r
+       b->bDefaultStatus = DEFAULT_STATUS_NONE;\r
+       b->bDisabledStyle = DISABLED_STYLE_DEFAULT;\r
+       //Init string\r
+       b->usFont = (UINT16)uiFont;\r
+       b->fMultiColor=FALSE;\r
+       b->sForeColor = sForeColor;\r
+       b->sWrappedWidth = -1;\r
+       b->sShadowColor = sShadowColor;\r
+       b->sForeColorDown = -1;\r
+       b->sShadowColorDown = -1;\r
+       b->sForeColorHilited = -1;\r
+       b->sShadowColorHilited = -1;\r
+       b->bJustification = BUTTON_TEXT_CENTER;\r
+       b->bTextXOffset = -1;\r
+       b->bTextYOffset = -1;\r
+       b->bTextXSubOffSet = 0;\r
+       b->bTextYSubOffSet = 0;\r
+       b->fShiftText = TRUE;\r
+       //Init icon\r
+       b->iIconID = -1;\r
+       b->usIconIndex = -1;\r
+       b->bIconXOffset = -1;\r
+       b->bIconYOffset = -1;\r
+       b->fShiftImage = TRUE;\r
+\r
+       // Set the button click callback function (if any)\r
+       if(ClickCallback != BUTTON_NO_CALLBACK)\r
+       {\r
+               b->ClickCallback = ClickCallback;\r
+               BType |= BUTTON_CLICK_CALLBACK;\r
+       }\r
+       else\r
+               b->ClickCallback = BUTTON_NO_CALLBACK;\r
+\r
+       // Set the button's mouse movement callback function (if any)\r
+       if(MoveCallback != BUTTON_NO_CALLBACK)\r
+       {\r
+               b->MoveCallback = MoveCallback;\r
+               BType |= BUTTON_MOVE_CALLBACK;\r
+       }\r
+       else\r
+               b->MoveCallback = BUTTON_NO_CALLBACK;\r
+\r
+       // Define a MOUSE_REGION for this button\r
+       MSYS_DefineRegion(&b->Area, (UINT16)xloc, (UINT16)yloc, (UINT16)(xloc+w), (UINT16)(yloc+h),\r
+                               (INT8)Priority, MSYS_STARTING_CURSORVAL, (MOUSE_CALLBACK)QuickButtonCallbackMMove, (MOUSE_CALLBACK)QuickButtonCallbackMButn);\r
+\r
+       // Link the MOUSE_REGION to this button\r
+       MSYS_SetRegionUserData(&b->Area,0,ButtonNum);\r
+\r
+       // Set the flags for this button\r
+       b->uiFlags |= ( BUTTON_ENABLED | BType | BUTTON_GENERIC);\r
+\r
+#ifdef _JA2_RENDER_DIRTY\r
+       b->BackRect = -1;\r
+#endif\r
+\r
+       // Add this button to the button list\r
+       #ifdef BUTTONSYSTEM_DEBUGGING\r
+       AssertFailIfIdenticalButtonAttributesFound( b );\r
+       #endif\r
+       ButtonList[ButtonNum]=b;\r
+\r
+       SpecifyButtonSoundScheme( b->IDNum, BUTTON_SOUND_SCHEME_GENERIC );\r
+\r
+       // return the slot number\r
+       return(ButtonNum);\r
+}\r
+\r
+\r
+\r
+//=============================================================================\r
+//     CreateHotSpot\r
+//\r
+//     Creates a button like HotSpot. HotSpots have no graphics associated with\r
+//     them.\r
+//\r
+INT32 CreateHotSpot(INT16 xloc, INT16 yloc, INT16 Width, INT16 Height,INT16 Priority,GUI_CALLBACK MoveCallback,GUI_CALLBACK ClickCallback)\r
+{\r
+       GUI_BUTTON *b;\r
+       INT32   ButtonNum;\r
+       INT16 BType,x;\r
+\r
+       if( xloc < 0 || yloc < 0 || Width < 0 || Height < 0 )\r
+       {\r
+               sprintf( str, "Attempting to CreateHotSpot with invalid coordinates: %d,%d, width: %d, and height: %d.",\r
+                       xloc, yloc, Width, Height );\r
+               AssertMsg( 0, str );\r
+       }\r
+\r
+       BType=0;\r
+\r
+       // Get a button number for this hotspot\r
+       if((ButtonNum = GetNextButtonNumber()) == BUTTON_NO_SLOT)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER,DBG_LEVEL_0,"CreateHotSpot: No more button slots");\r
+               return(-1);\r
+       }\r
+\r
+       // Allocate memory for the GUI_BUTTON structure\r
+       if((b=(GUI_BUTTON *)MemAlloc(sizeof(GUI_BUTTON))) == NULL)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER,DBG_LEVEL_0,"CreateHotSpot: Can't alloc mem for button struct");\r
+               return(-1);\r
+       }\r
+\r
+       // Init the structure values\r
+       b->uiFlags = 0;\r
+       b->uiOldFlags = 0;\r
+       b->IDNum = ButtonNum;\r
+       b->XLoc = xloc;\r
+       b->YLoc = yloc;\r
+       b->ImageNum = 0xffffffff;\r
+       for(x=0;x<4;x++)\r
+               b->UserData[x] = 0;\r
+       b->Group = -1;\r
+       b->string = NULL;\r
+\r
+       // Set the hotspot click callback function (if any)\r
+       if(ClickCallback != BUTTON_NO_CALLBACK)\r
+       {\r
+               b->ClickCallback = ClickCallback;\r
+               BType |= BUTTON_CLICK_CALLBACK;\r
+       }\r
+       else\r
+               b->ClickCallback = BUTTON_NO_CALLBACK;\r
+\r
+       // Set the hotspot's mouse movement callback function (if any)\r
+       if(MoveCallback != BUTTON_NO_CALLBACK)\r
+       {\r
+               b->MoveCallback = MoveCallback;\r
+               BType |= BUTTON_MOVE_CALLBACK;\r
+       }\r
+       else\r
+               b->MoveCallback = BUTTON_NO_CALLBACK;\r
+\r
+       // define a MOUSE_REGION for this hotspot\r
+       MSYS_DefineRegion(&b->Area,(UINT16)xloc,(UINT16)yloc,(UINT16)(xloc+Width),(UINT16)(yloc+Height),\r
+                               (INT8)Priority, MSYS_STARTING_CURSORVAL, (MOUSE_CALLBACK)QuickButtonCallbackMMove, (MOUSE_CALLBACK)QuickButtonCallbackMButn);\r
+\r
+       // Link the MOUSE_REGION to this hotspot\r
+       MSYS_SetRegionUserData(&b->Area,0,ButtonNum);\r
+\r
+       // Set the flags entry for this hotspot\r
+       b->uiFlags |= (BUTTON_ENABLED|BType|BUTTON_HOT_SPOT);\r
+\r
+#ifdef _JA2_RENDER_DIRTY\r
+       b->BackRect = -1;\r
+#endif\r
+\r
+       // Add this button (hotspot) to the button list\r
+       #ifdef BUTTONSYSTEM_DEBUGGING\r
+       AssertFailIfIdenticalButtonAttributesFound( b );\r
+       #endif\r
+       ButtonList[ButtonNum]=b;\r
+\r
+       SpecifyButtonSoundScheme( b->IDNum, BUTTON_SOUND_SCHEME_GENERIC );\r
+\r
+       // return the button slot number\r
+       return(ButtonNum);\r
+}\r
+\r
+\r
+\r
+// ============================================================================\r
+// Addition Oct15/97, Carter\r
+// SetButtonCursor\r
+// will simply set the cursor for the mouse region the button occupies\r
+BOOLEAN SetButtonCursor(INT32 iBtnId, UINT16 crsr)\r
+{\r
+  GUI_BUTTON *b;\r
+  b = ButtonList[iBtnId];\r
+       if (!b)\r
+               return FALSE;\r
+  b->Area.Cursor = crsr;\r
+       return TRUE;\r
+}\r
+\r
+//=============================================================================\r
+//     QuickCreateButton\r
+//\r
+//     Creates a QuickButton. QuickButtons only have graphics associated with\r
+//     them. They cannot be re-sized, nor can the graphic be changed.\r
+//\r
+INT32 QuickCreateButton(UINT32 Image,INT16 xloc,INT16 yloc,INT32 Type,INT16 Priority,GUI_CALLBACK MoveCallback,GUI_CALLBACK ClickCallback)\r
+{\r
+       GUI_BUTTON *b;\r
+       INT32   ButtonNum;\r
+       INT32 BType,x;\r
+\r
+       if( xloc < 0 || yloc < 0 )\r
+       {\r
+               sprintf( str, "Attempting to QuickCreateButton with invalid position of %d,%d", xloc, yloc );\r
+               AssertMsg( 0, str );\r
+       }\r
+       if( Image < 0 || Image >= MAX_BUTTON_PICS )\r
+       {\r
+               sprintf( str, "Attempting to QuickCreateButton with out of range ImageID %d.", Image );\r
+               AssertMsg( 0, str );\r
+       }\r
+\r
+       // Strip off any extraneous bits from button type\r
+       BType = Type & ( BUTTON_TYPE_MASK | BUTTON_NEWTOGGLE );\r
+\r
+       // Is there a QuickButton image in the given image slot?\r
+       if(ButtonPictures[Image].vobj == NULL)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER,DBG_LEVEL_0,"QuickCreateButton: Invalid button image number");\r
+               return(-1);\r
+       }\r
+\r
+       // Get a new button number\r
+       if((ButtonNum = GetNextButtonNumber()) == BUTTON_NO_SLOT)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER,DBG_LEVEL_0,"QuickCreateButton: No more button slots");\r
+               return(-1);\r
+       }\r
+\r
+       // Allocate memory for a GUI_BUTTON structure\r
+       if((b=(GUI_BUTTON *)MemAlloc(sizeof(GUI_BUTTON))) == NULL)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER,DBG_LEVEL_0,"QuickCreateButton: Can't alloc mem for button struct");\r
+               return(-1);\r
+       }\r
+\r
+       // Set the values for this buttn\r
+       b->uiFlags = BUTTON_DIRTY;\r
+       b->uiOldFlags = 0;\r
+\r
+       // Set someflags if of s certain type....\r
+       if ( Type & BUTTON_NEWTOGGLE )\r
+       {\r
+               b->uiFlags |= BUTTON_NEWTOGGLE;\r
+       }\r
+\r
+       // shadow style\r
+       b->bDefaultStatus = DEFAULT_STATUS_NONE;\r
+       b->bDisabledStyle = DISABLED_STYLE_DEFAULT;\r
+\r
+       b->Group = -1;\r
+       //Init string\r
+       b->string = NULL;\r
+       b->usFont = 0;\r
+       b->fMultiColor=FALSE;\r
+       b->sForeColor = 0;\r
+       b->sWrappedWidth = -1;\r
+       b->sShadowColor = -1;\r
+       b->sForeColorDown = -1;\r
+       b->sShadowColorDown = -1;\r
+       b->sForeColorHilited = -1;\r
+       b->sShadowColorHilited = -1;\r
+       b->bJustification = BUTTON_TEXT_CENTER;\r
+       b->bTextXOffset = -1;\r
+       b->bTextYOffset = -1;\r
+       b->bTextXSubOffSet = 0;\r
+       b->bTextYSubOffSet = 0;\r
+       b->fShiftText = TRUE;\r
+       //Init icon\r
+       b->iIconID = -1;\r
+       b->usIconIndex = -1;\r
+       b->bIconXOffset = -1;\r
+       b->bIconYOffset = -1;\r
+       b->fShiftImage = TRUE;\r
+       //Init quickbutton\r
+       b->IDNum = ButtonNum;\r
+       b->ImageNum = Image;\r
+       for(x=0;x<4;x++)\r
+               b->UserData[x] = 0;\r
+\r
+       b->XLoc = xloc;\r
+       b->YLoc = yloc;\r
+\r
+       b->ubToggleButtonOldState = 0;\r
+       b->ubToggleButtonActivated = FALSE;\r
+\r
+       // Set the button click callback function (if any)\r
+       if(ClickCallback != BUTTON_NO_CALLBACK)\r
+       {\r
+               b->ClickCallback = ClickCallback;\r
+               BType |= BUTTON_CLICK_CALLBACK;\r
+       }\r
+       else\r
+               b->ClickCallback = BUTTON_NO_CALLBACK;\r
+\r
+       // Set the button's mouse movement callback function (if any)\r
+       if(MoveCallback != BUTTON_NO_CALLBACK)\r
+       {\r
+               b->MoveCallback = MoveCallback;\r
+               BType |= BUTTON_MOVE_CALLBACK;\r
+       }\r
+       else\r
+               b->MoveCallback = BUTTON_NO_CALLBACK;\r
+\r
+       memset( &b->Area, 0, sizeof( MOUSE_REGION ) );\r
+       // Define a MOUSE_REGION for this QuickButton\r
+       MSYS_DefineRegion(&b->Area,(UINT16)xloc,(UINT16)yloc,\r
+                         (UINT16)(xloc+(INT16)ButtonPictures[Image].MaxWidth),\r
+                               (UINT16)(yloc+(INT16)ButtonPictures[Image].MaxHeight),\r
+                               (INT8)Priority, MSYS_STARTING_CURSORVAL,\r
+                               (MOUSE_CALLBACK)QuickButtonCallbackMMove,\r
+                               (MOUSE_CALLBACK)QuickButtonCallbackMButn);\r
+\r
+       // Link the MOUSE_REGION with this QuickButton\r
+       MSYS_SetRegionUserData(&b->Area,0,ButtonNum);\r
+\r
+       // Set the flags for this button\r
+       b->uiFlags |= BUTTON_ENABLED | BType | BUTTON_QUICK;\r
+#ifdef _JA2_RENDER_DIRTY\r
+       b->BackRect = -1;\r
+#endif\r
+\r
+       // Add this QuickButton to the button list\r
+       #ifdef BUTTONSYSTEM_DEBUGGING\r
+       AssertFailIfIdenticalButtonAttributesFound( b );\r
+       #endif\r
+       ButtonList[ButtonNum]=b;\r
+\r
+       SpecifyButtonSoundScheme( b->IDNum, BUTTON_SOUND_SCHEME_GENERIC );\r
+\r
+       // return the button number (slot)\r
+       return(ButtonNum);\r
+}\r
+\r
+//A hybrid of QuickCreateButton.  Takes a lot less parameters, but makes more assumptions.  It self manages the\r
+//loading, and deleting of the image.  The size of the image determines the size of the button.  It also uses\r
+//the default move callback which emulates Win95.  Finally, it sets the priority to normal.  The function you\r
+//choose also determines the type of button (toggle, notoggle, or newtoggle)\r
+INT32 CreateEasyNoToggleButton ( INT32 x, INT32 y, UINT8 *filename, GUI_CALLBACK ClickCallback )\r
+{\r
+       return CreateSimpleButton( x, y, filename, BUTTON_NO_TOGGLE, MSYS_PRIORITY_NORMAL, ClickCallback );\r
+}\r
+\r
+INT32 CreateEasyToggleButton   ( INT32 x, INT32 y, UINT8 *filename, GUI_CALLBACK ClickCallback )\r
+{\r
+       return CreateSimpleButton( x, y, filename, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, ClickCallback );\r
+}\r
+\r
+INT32 CreateEasyNewToggleButton( INT32 x, INT32 y, UINT8 *filename, GUI_CALLBACK ClickCallback )\r
+{\r
+       return CreateSimpleButton( x, y, filename, BUTTON_NEWTOGGLE, MSYS_PRIORITY_NORMAL, ClickCallback );\r
+}\r
+\r
+//Same as above, but accepts specify toggle type\r
+INT32 CreateEasyButton( INT32 x, INT32 y, UINT8 *filename, INT32 Type, GUI_CALLBACK ClickCallback)\r
+{\r
+       return CreateSimpleButton( x, y, filename, Type, MSYS_PRIORITY_NORMAL, ClickCallback );\r
+}\r
+\r
+//Same as above, but accepts priority specification.\r
+INT32 CreateSimpleButton( INT32 x, INT32 y, UINT8 *filename, INT32 Type, INT16 Priority, GUI_CALLBACK ClickCallback )\r
+{\r
+       INT32 ButPic,ButNum;\r
+\r
+       if( !filename || !strlen(filename) )\r
+               AssertMsg( 0, "Attempting to CreateSimpleButton with null filename." );\r
+\r
+       if( ( ButPic = LoadButtonImage( filename, -1, 1, 2, 3, 4 ) ) == -1)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER,DBG_LEVEL_0,"Can't load button image");\r
+               return( -1 );\r
+       }\r
+\r
+       ButNum = (INT16)QuickCreateButton( ButPic, (INT16)x,(INT16)y, Type, Priority, DEFAULT_MOVE_CALLBACK, ClickCallback);\r
+\r
+       AssertMsg( ButNum != -1, "Failed to CreateSimpleButton." );\r
+\r
+       ButtonList[ ButNum ]->uiFlags |= BUTTON_SELFDELETE_IMAGE;\r
+\r
+       SpecifyDisabledButtonStyle( ButNum, DISABLED_STYLE_SHADED );\r
+\r
+       return( ButNum );\r
+}\r
+\r
+\r
+INT32 CreateIconAndTextButton( INT32 Image, UINT16 *string, UINT32 uiFont,\r
+                                                                                                                        INT16 sForeColor, INT16 sShadowColor,\r
+                                                                                                                        INT16 sForeColorDown, INT16 sShadowColorDown,\r
+                                                                                                                        INT8 bJustification,\r
+                                                                                                                        INT16 xloc, INT16 yloc, INT32 Type, INT16 Priority,\r
+                                                                                                                        GUI_CALLBACK MoveCallback,GUI_CALLBACK ClickCallback)\r
+{\r
+       GUI_BUTTON *b;\r
+       INT32   iButtonID;\r
+       INT32 BType,x;\r
+\r
+       if( xloc < 0 || yloc < 0 )\r
+       {\r
+               sprintf( str, "Attempting to CreateIconAndTextButton with invalid position of %d,%d", xloc, yloc );\r
+               AssertMsg( 0, str );\r
+       }\r
+       if( Image < 0 || Image >= MAX_BUTTON_PICS )\r
+       {\r
+               sprintf( str, "Attemting to CreateIconAndTextButton with out of range ImageID %d.", Image );\r
+               AssertMsg( 0, str );\r
+       }\r
+\r
+       // Strip off any extraneous bits from button type\r
+       BType = Type & ( BUTTON_TYPE_MASK | BUTTON_NEWTOGGLE );\r
+\r
+       // Is there a QuickButton image in the given image slot?\r
+       if(ButtonPictures[Image].vobj == NULL)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER,DBG_LEVEL_0,"QuickCreateButton: Invalid button image number");\r
+               return(-1);\r
+       }\r
+\r
+       // Get a new button number\r
+       if((iButtonID = GetNextButtonNumber()) == BUTTON_NO_SLOT)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER,DBG_LEVEL_0,"QuickCreateButton: No more button slots");\r
+               return(-1);\r
+       }\r
+\r
+       // Allocate memory for a GUI_BUTTON structure\r
+       if((b=(GUI_BUTTON *)MemAlloc(sizeof(GUI_BUTTON))) == NULL)\r
+       {\r
+               DbgMessage(TOPIC_BUTTON_HANDLER,DBG_LEVEL_0,"QuickCreateButton: Can't alloc mem for button struct");\r
+               return(-1);\r
+       }\r
+\r
+       // Set the values for this button\r
+       b->uiFlags = BUTTON_DIRTY;\r
+       b->uiOldFlags = 0;\r
+       b->IDNum = iButtonID;\r
+       b->XLoc = xloc;\r
+       b->YLoc = yloc;\r
+       b->ImageNum = Image;\r
+       for(x=0;x<4;x++)\r
+               b->UserData[x] = 0;\r
+       b->Group = -1;\r
+       b->bDefaultStatus = DEFAULT_STATUS_NONE;\r
+       b->bDisabledStyle = DISABLED_STYLE_DEFAULT;\r
+\r
+       // Allocate memory for the button's text string...\r
+       b->string = NULL;\r
+       if ( string  )\r
+       {\r
+               b->string = (UINT16*)MemAlloc( (wcslen(string)+1)*sizeof(UINT16) );\r
+               AssertMsg( b->string, "Out of memory error:  Couldn't allocate string in CreateIconAndTextButton." );\r
+               wcscpy( b->string, string );\r
+       }\r
+\r
+       b->bJustification = bJustification;\r
+       b->usFont = (UINT16)uiFont;\r
+       b->fMultiColor=FALSE;\r
+       b->sForeColor = sForeColor;\r
+       b->sWrappedWidth = -1;\r
+       b->sShadowColor = sShadowColor;\r
+       b->sForeColorDown = sForeColorDown;\r
+       b->sShadowColorDown = sShadowColorDown;\r
+       b->sForeColorHilited = -1;\r
+       b->sShadowColorHilited = -1;\r
+       b->bTextXOffset = -1;\r
+       b->bTextYOffset = -1;\r
+       b->bTextXSubOffSet = 0;\r
+       b->bTextYSubOffSet = 0;\r
+       b->fShiftText = TRUE;\r
+\r
+       b->iIconID = -1;\r
+       b->usIconIndex = 0;\r
+\r
+       // Set the button click callback function (if any)\r
+       if(ClickCallback != BUTTON_NO_CALLBACK)\r
+       {\r
+               b->ClickCallback = ClickCallback;\r
+               BType |= BUTTON_CLICK_CALLBACK;\r
+       }\r
+       else\r
+               b->ClickCallback = BUTTON_NO_CALLBACK;\r
+\r
+       // Set the button's mouse movement callback function (if any)\r
+       if(MoveCallback != BUTTON_NO_CALLBACK)\r
+       {\r
+               b->MoveCallback = MoveCallback;\r
+               BType |= BUTTON_MOVE_CALLBACK;\r
+       }\r
+       else\r
+               b->MoveCallback = BUTTON_NO_CALLBACK;\r
+\r
+       // Define a MOUSE_REGION for this QuickButton\r
+       MSYS_DefineRegion(&b->Area,(UINT16)xloc,(UINT16)yloc,\r
+                         (UINT16)(xloc+(INT16)ButtonPictures[Image].MaxWidth),\r
+                               (UINT16)(yloc+(INT16)ButtonPictures[Image].MaxHeight),\r
+                               (INT8)Priority, MSYS_STARTING_CURSORVAL,\r
+                               (MOUSE_CALLBACK)QuickButtonCallbackMMove,\r
+                               (MOUSE_CALLBACK)QuickButtonCallbackMButn);\r
+\r
+       // Link the MOUSE_REGION with this QuickButton\r
+       MSYS_SetRegionUserData(&b->Area,0,iButtonID);\r
+\r
+       // Set the flags for this button\r
+       b->uiFlags |= ( BUTTON_ENABLED | BType | BUTTON_QUICK );\r
+\r
+#ifdef _JA2_RENDER_DIRTY\r
+       b->BackRect = -1;\r
+#endif\r
+\r
+       // Add this QuickButton to the button list\r
+       #ifdef BUTTONSYSTEM_DEBUGGING\r
+       AssertFailIfIdenticalButtonAttributesFound( b );\r
+       #endif\r
+       ButtonList[iButtonID]=b;\r
+\r
+       SpecifyButtonSoundScheme( b->IDNum, BUTTON_SOUND_SCHEME_GENERIC );\r
+\r
+       // return the button number (slot)\r
+       return(iButtonID);\r
+}\r
+\r
+//New functions\r
+void SpecifyButtonText( INT32 iButtonID, UINT16 *string )\r
+{\r
+       GUI_BUTTON *b;\r
+\r
+       Assert( iButtonID >= 0 );\r
+       Assert( iButtonID < MAX_BUTTONS );\r
+\r
+       b = ButtonList[ iButtonID ];\r
+\r
+       //free the previous strings memory if applicable\r
+       if( b->string )\r
+               MemFree( b->string );\r
+       b->string = NULL;\r
+\r
+       if( string && wcslen( string ) )\r
+       {\r
+               //allocate memory for the new string\r
+               b->string = (UINT16*)MemAlloc( (wcslen(string)+1)*sizeof(UINT16) );\r
+               Assert( b->string );\r
+               //copy the string to the button\r
+               wcscpy( b->string, string );\r
+               b->uiFlags |= BUTTON_DIRTY;\r
+       }\r
+}\r
+\r
+void SpecifyButtonMultiColorFont(INT32 iButtonID, BOOLEAN fMultiColor)\r
+{\r
+       GUI_BUTTON *b;\r
+       Assert( iButtonID >= 0 );\r
+       Assert( iButtonID < MAX_BUTTONS );\r
+       b = ButtonList[ iButtonID ];\r
+       Assert( b );\r
+       b->fMultiColor = fMultiColor;\r
+       b->uiFlags |= BUTTON_DIRTY ;\r
+}\r
+\r
+void SpecifyButtonFont( INT32 iButtonID, UINT32 uiFont )\r
+{\r
+       GUI_BUTTON *b;\r
+       Assert( iButtonID >= 0 );\r
+       Assert( iButtonID < MAX_BUTTONS );\r
+       b = ButtonList[ iButtonID ];\r
+       Assert( b );\r
+       b->usFont = (UINT16)uiFont;\r
+       b->uiFlags |= BUTTON_DIRTY ;\r
+}\r
+\r
+void SpecifyButtonUpTextColors( INT32 iButtonID, INT16 sForeColor, INT16 sShadowColor )\r
+{\r
+       GUI_BUTTON *b;\r
+       Assert( iButtonID >= 0 );\r
+       Assert( iButtonID < MAX_BUTTONS );\r
+       b = ButtonList[ iButtonID ];\r
+       Assert( b );\r
+       b->sForeColor = sForeColor;\r
+       b->sShadowColor = sShadowColor;\r
+       b->uiFlags |= BUTTON_DIRTY ;\r
+}\r
+\r
+void SpecifyButtonDownTextColors( INT32 iButtonID, INT16 sForeColorDown, INT16 sShadowColorDown )\r
+{\r
+       GUI_BUTTON *b;\r
+       Assert( iButtonID >= 0 );\r
+       Assert( iButtonID < MAX_BUTTONS );\r
+       b = ButtonList[ iButtonID ];\r
+       Assert( b );\r
+       b->sForeColorDown = sForeColorDown;\r
+       b->sShadowColorDown = sShadowColorDown;\r
+       b->uiFlags |= BUTTON_DIRTY ;\r
+}\r
+\r
+void SpecifyButtonHilitedTextColors( INT32 iButtonID, INT16 sForeColorHilited, INT16 sShadowColorHilited )\r
+{\r
+       GUI_BUTTON *b;\r
+       Assert( iButtonID >= 0 );\r
+       Assert( iButtonID < MAX_BUTTONS );\r
+       b = ButtonList[ iButtonID ];\r
+       Assert( b );\r
+       b->sForeColorHilited = sForeColorHilited;\r
+       b->sShadowColorHilited = sShadowColorHilited;\r
+       b->uiFlags |= BUTTON_DIRTY ;\r
+}\r
+\r
+void SpecifyButtonTextJustification( INT32 iButtonID, INT8 bJustification )\r
+{\r
+       GUI_BUTTON *b;\r
+       Assert( iButtonID >= 0 );\r
+       Assert( iButtonID < MAX_BUTTONS );\r
+       b = ButtonList[ iButtonID ];\r
+       Assert( b );\r
+       //Range check:  if invalid, then set it to center justified.\r
+       if( bJustification < BUTTON_TEXT_LEFT || bJustification > BUTTON_TEXT_RIGHT )\r
+               bJustification = BUTTON_TEXT_CENTER;\r
+       b->bJustification = bJustification;\r
+       b->uiFlags |= BUTTON_DIRTY ;\r
+}\r
+\r
+void SpecifyFullButtonTextAttributes( INT32 iButtonID, UINT16 *string, INT32 uiFont,\r
+                                                                                                                                                       INT16 sForeColor, INT16 sShadowColor,\r
+                                                                                                                                                       INT16 sForeColorDown, INT16 sShadowColorDown, INT8 bJustification )\r
+{\r
+       GUI_BUTTON *b;\r
+       Assert( iButtonID >= 0 );\r
+       Assert( iButtonID < MAX_BUTTONS );\r
+       b = ButtonList[ iButtonID ];\r
+       Assert( b );\r
+       //Copy over information\r
+       SpecifyButtonText( iButtonID, string );\r
+       b->usFont = (UINT16)uiFont;\r
+       b->sForeColor = sForeColor;\r
+       b->sShadowColor = sShadowColor;\r
+       b->sForeColorDown = sForeColorDown;\r
+       b->sShadowColorDown = sShadowColorDown;\r
+       //Range check:  if invalid, then set it to center justified.\r
+       if( bJustification < BUTTON_TEXT_LEFT || bJustification > BUTTON_TEXT_RIGHT )\r
+               bJustification = BUTTON_TEXT_CENTER;\r
+       b->bJustification = bJustification;\r
+       b->uiFlags |= BUTTON_DIRTY ;\r
+}\r
+\r
+void SpecifyGeneralButtonTextAttributes( INT32 iButtonID, UINT16 *string, INT32 uiFont,\r
+                                                                                                                                                       INT16 sForeColor, INT16 sShadowColor )\r
+{\r
+       GUI_BUTTON *b;\r
+       Assert( iButtonID >= 0 );\r
+       Assert( iButtonID < MAX_BUTTONS );\r
+       b = ButtonList[ iButtonID ];\r
+       Assert( b );\r
+       //Copy over information\r
+       SpecifyButtonText( iButtonID, string );\r
+       b->usFont = (UINT16)uiFont;\r
+       b->sForeColor = sForeColor;\r
+       b->sShadowColor = sShadowColor;\r
+       b->uiFlags |= BUTTON_DIRTY ;\r
+}\r
+\r
+void SpecifyButtonTextOffsets( INT32 iButtonID, INT8 bTextXOffset, INT8 bTextYOffset, BOOLEAN fShiftText )\r
+{\r
+       GUI_BUTTON *b;\r
+       Assert( iButtonID >= 0 );\r
+       Assert( iButtonID < MAX_BUTTONS );\r
+       b = ButtonList[ iButtonID ];\r
+       Assert( b );\r
+       //Copy over information\r
+       b->bTextXOffset = bTextXOffset;\r
+       b->bTextYOffset = bTextYOffset;\r
+       b->fShiftText = fShiftText;\r
+}\r
+\r
+void SpecifyButtonTextSubOffsets( INT32 iButtonID, INT8 bTextXOffset, INT8 bTextYOffset, BOOLEAN fShiftText )\r
+{\r
+       GUI_BUTTON *b;\r
+       Assert( iButtonID >= 0 );\r
+       Assert( iButtonID < MAX_BUTTONS );\r
+       b = ButtonList[ iButtonID ];\r
+       Assert( b );\r
+       //Copy over information\r
+       b->bTextXSubOffSet = bTextXOffset;\r
+       b->bTextYSubOffSet = bTextYOffset;\r
+       b->fShiftText = fShiftText;\r
+}\r
+\r
+\r
+void SpecifyButtonTextWrappedWidth(INT32 iButtonID, INT16 sWrappedWidth)\r
+{\r
+       GUI_BUTTON *b;\r
+       Assert( iButtonID >= 0 );\r
+       Assert( iButtonID < MAX_BUTTONS );\r
+       b = ButtonList[ iButtonID ];\r
+       Assert( b );\r
+\r
+       b->sWrappedWidth = sWrappedWidth;\r
+}\r
+\r
+void SpecifyDisabledButtonStyle( INT32 iButtonID, INT8 bStyle )\r
+{\r
+       GUI_BUTTON *b;\r
+       Assert( iButtonID >= 0 );\r
+       Assert( iButtonID < MAX_BUTTONS );\r
+       b = ButtonList[ iButtonID ];\r
+       Assert( b );\r
+\r
+       Assert( bStyle >= DISABLED_STYLE_NONE && bStyle <= DISABLED_STYLE_SHADED );\r
+\r
+       b->bDisabledStyle = bStyle;\r
+}\r
+\r
+\r
+//Note:  Text is always on top\r
+//If fShiftImage is true, then the image will shift down one pixel and right one pixel\r
+//just like the text does.\r
+BOOLEAN SpecifyButtonIcon( INT32 iButtonID, INT32 iVideoObjectID, UINT16 usVideoObjectIndex,\r
+                                                                                                        INT8 bXOffset, INT8 bYOffset, BOOLEAN fShiftImage )\r
+{\r
+       GUI_BUTTON *b;\r
+\r
+       Assert( iButtonID >= 0 );\r
+       Assert( iButtonID < MAX_BUTTONS );\r
+       b = ButtonList[ iButtonID ];\r
+       Assert( b );\r
+\r
+       b->iIconID = iVideoObjectID;\r
+       b->usIconIndex = usVideoObjectIndex;\r
+\r
+       if( b->iIconID == -1 )\r
+               return FALSE;\r
+\r
+       b->bIconXOffset = bXOffset;\r
+       b->bIconYOffset = bYOffset;\r
+       b->fShiftImage = TRUE;\r
+\r
+       b->uiFlags |= BUTTON_DIRTY;\r
+\r
+       return TRUE;\r
+}\r
+\r
+void RemoveTextFromButton( INT32 iButtonID )\r
+{\r
+       GUI_BUTTON *b;\r
+\r
+       Assert( iButtonID >= 0 );\r
+       Assert( iButtonID < MAX_BUTTONS );\r
+       b = ButtonList[ iButtonID ];\r
+       Assert( b );\r
+       //Init string\r
+       if( b->string )\r
+               MemFree( b->string );\r
+       b->string = NULL;\r
+       b->usFont = 0;\r
+       b->sForeColor = 0;\r
+       b->sWrappedWidth = -1;\r
+       b->sShadowColor = -1;\r
+       b->sForeColorDown = -1;\r
+       b->sShadowColorDown = -1;\r
+       b->sForeColorHilited = -1;\r
+       b->sShadowColorHilited = -1;\r
+       b->bJustification = BUTTON_TEXT_CENTER;\r
+       b->bTextXOffset = -1;\r
+       b->bTextYOffset = -1;\r
+       b->bTextXSubOffSet = 0;\r
+       b->bTextYSubOffSet = 0;\r
+       b->fShiftText = TRUE;\r
+}\r
+\r
+void RemoveIconFromButton( INT32 iButtonID )\r
+{\r
+       GUI_BUTTON *b;\r
+\r
+       Assert( iButtonID >= 0 );\r
+       Assert( iButtonID < MAX_BUTTONS );\r
+       b = ButtonList[ iButtonID ];\r
+       Assert( b );\r
+       //Clear icon\r
+       b->iIconID = -1;\r
+       b->usIconIndex = -1;\r
+       b->bIconXOffset = -1;\r
+       b->bIconYOffset = -1;\r
+       b->fShiftImage = TRUE;\r
+}\r
+\r
+void AllowDisabledButtonFastHelp( INT32 iButtonID, BOOLEAN fAllow )\r
+{\r
+       GUI_BUTTON *b;\r
+\r
+       Assert( iButtonID >= 0 );\r
+       Assert( iButtonID < MAX_BUTTONS );\r
+       b = ButtonList[ iButtonID ];\r
+       Assert( b );\r
+\r
+       b->Area.uiFlags |= MSYS_ALLOW_DISABLED_FASTHELP;\r
+}\r
+\r
+//=============================================================================\r
+//     SetButtonFastHelpText\r
+//\r
+//     Set the text that will be displayed as the FastHelp\r
+//\r
+void SetButtonFastHelpText(INT32 iButton, UINT16 *Text)\r
+{\r
+       GUI_BUTTON *b;\r
+       if(iButton<0 || iButton>MAX_BUTTONS)\r
+               return;\r
+       b = ButtonList[iButton];\r
+       AssertMsg( b, "Called SetButtonFastHelpText() with a non-existant button." );\r
+       SetRegionFastHelpText( &b->Area, Text );\r
+}\r
+\r
+void SetBtnHelpEndCallback( INT32 iButton, MOUSE_HELPTEXT_DONE_CALLBACK CallbackFxn )\r
+{\r
+       GUI_BUTTON *b;\r
+       if(iButton<0 || iButton>MAX_BUTTONS)\r
+               return;\r
+       b = ButtonList[iButton];\r
+       AssertMsg( b, "Called SetBtnHelpEndCallback() with a non-existant button." );\r
+\r
+       SetRegionHelpEndCallback( &b->Area, CallbackFxn );\r
+}\r
+\r
+//=============================================================================\r
+//     QuickButtonCallbackMMove\r
+//\r
+//     Dispatches all button callbacks for mouse movement. This function gets\r
+//     called by the Mouse System. *DO NOT CALL DIRECTLY*\r
+//\r
+void QuickButtonCallbackMMove(MOUSE_REGION *reg,INT32 reason)\r
+{\r
+       GUI_BUTTON *b;\r
+       INT32 iButtonID;\r
+\r
+\r
+       Assert(reg != NULL);\r
+\r
+       iButtonID = MSYS_GetRegionUserData(reg,0);\r
+\r
+       sprintf( str, "QuickButtonCallbackMMove: Mouse Region #%d (%d,%d to %d,%d) has invalid buttonID %d",\r
+                                               reg->IDNumber, reg->RegionTopLeftX, reg->RegionTopLeftY, reg->RegionBottomRightX, reg->RegionBottomRightY, iButtonID );\r
+\r
+       AssertMsg( iButtonID >= 0, str );\r
+       AssertMsg( iButtonID < MAX_BUTTONS, str );\r
+\r
+       b = ButtonList[ iButtonID ];\r
+\r
+       AssertMsg( b != NULL, str );\r
+\r
+       if( !b )\r
+               return;  //This is getting called when Adding new regions...\r
+\r
+\r
+       if( b->uiFlags & BUTTON_ENABLED &&\r
+                 reason & (MSYS_CALLBACK_REASON_LOST_MOUSE | MSYS_CALLBACK_REASON_GAIN_MOUSE) )\r
+       {\r
+               b->uiFlags |= BUTTON_DIRTY;\r
+       }\r
+\r
+       // Mouse moved on the button, so reset it's timer to maximum.\r
+       if( b->Area.uiFlags & MSYS_CALLBACK_REASON_GAIN_MOUSE )\r
+       {\r
+               //check for sound playing stuff\r
+               if( b->ubSoundSchemeID )\r
+               {\r
+                       if( &b->Area == MSYS_PrevRegion && !gpAnchoredButton )\r
+                       {\r
+                               if( b->uiFlags & BUTTON_ENABLED )\r
+                               {\r
+                                       PlayButtonSound( iButtonID, BUTTON_SOUND_MOVED_ONTO );\r
+                               }\r
+                               else\r
+                               {\r
+                                       PlayButtonSound( iButtonID, BUTTON_SOUND_DISABLED_MOVED_ONTO );\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       else\r
+       {\r
+               //Check if we should play a sound\r
+               if( b->ubSoundSchemeID )\r
+               {\r
+                       if( b->uiFlags & BUTTON_ENABLED )\r
+                       {\r
+                               if( &b->Area == MSYS_PrevRegion && !gpAnchoredButton )\r
+                               {\r
+                                       PlayButtonSound( iButtonID, BUTTON_SOUND_MOVED_OFF_OF );\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               PlayButtonSound( iButtonID, BUTTON_SOUND_DISABLED_MOVED_OFF_OF );\r
+                       }\r
+               }\r
+       }\r
+\r
+       // ATE: New stuff for toggle buttons that work with new Win95 paridigm\r
+       if ( ( b->uiFlags & BUTTON_NEWTOGGLE ) )\r
+       {\r
+               if(reason & MSYS_CALLBACK_REASON_LOST_MOUSE )\r
+               {\r
+                       if ( b->ubToggleButtonActivated )\r
+                       {\r
+                               b->ubToggleButtonActivated = FALSE;\r
+\r
+                               if ( !b->ubToggleButtonOldState )\r
+                               {\r
+                                       b->uiFlags &= (~BUTTON_CLICKED_ON );\r
+                               }\r
+                               else\r
+                               {\r
+                                       b->uiFlags |= BUTTON_CLICKED_ON;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       // If this button is enabled and there is a callback function associated with it,\r
+       // call the callback function.\r
+       if((b->uiFlags & BUTTON_ENABLED) && (b->uiFlags & BUTTON_MOVE_CALLBACK))\r
+               (b->MoveCallback)(b,reason);\r
+}\r
+\r
+\r
+\r
+//=============================================================================\r
+//     QuickButtonCallbackMButn\r
+//\r
+//     Dispatches all button callbacks for button presses. This function is\r
+//     called by the Mouse System. *DO NOT CALL DIRECTLY*\r
+//\r
+void QuickButtonCallbackMButn( MOUSE_REGION *reg, INT32 reason )\r
+{\r
+       GUI_BUTTON *b;\r
+       INT32           iButtonID;\r
+       BOOLEAN MouseBtnDown;\r
+       BOOLEAN StateBefore,StateAfter;\r
+\r
+\r
+       Assert(reg != NULL);\r
+\r
+       iButtonID = MSYS_GetRegionUserData(reg,0);\r
+\r
+       sprintf( str, "QuickButtonCallbackMButn: Mouse Region #%d (%d,%d to %d,%d) has invalid buttonID %d",\r
+                                               reg->IDNumber, reg->RegionTopLeftX, reg->RegionTopLeftY, reg->RegionBottomRightX, reg->RegionBottomRightY, iButtonID );\r
+\r
+       AssertMsg( iButtonID >= 0, str );\r
+       AssertMsg( iButtonID < MAX_BUTTONS, str );\r
+\r
+       b = ButtonList[ iButtonID ];\r
+\r
+       AssertMsg( b != NULL, str );\r
+\r
+       if( !b )\r
+               return;\r
+\r
+\r
+       if( reason & (MSYS_CALLBACK_REASON_LBUTTON_DWN | MSYS_CALLBACK_REASON_RBUTTON_DWN) )\r
+               MouseBtnDown = TRUE;\r
+       else\r
+               MouseBtnDown = FALSE;\r
+\r
+       StateBefore = (b->uiFlags & BUTTON_CLICKED_ON) ? (TRUE) : (FALSE);\r
+\r
+       // ATE: New stuff for toggle buttons that work with new Win95 paridigm\r
+       if( b->uiFlags & BUTTON_NEWTOGGLE && b->uiFlags & BUTTON_ENABLED )\r
+       {\r
+               if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )\r
+               {\r
+                       if ( !b->ubToggleButtonActivated )\r
+                       {\r
+                               if ( !(b->uiFlags & BUTTON_CLICKED_ON ) )\r
+                               {\r
+                                       b->ubToggleButtonOldState = FALSE;\r
+                                       b->uiFlags |= BUTTON_CLICKED_ON;\r
+                               }\r
+                               else\r
+                               {\r
+                                       b->ubToggleButtonOldState = TRUE;\r
+                                       b->uiFlags &= (~BUTTON_CLICKED_ON);\r
+                               }\r
+                               b->ubToggleButtonActivated = TRUE;\r
+                       }\r
+               }\r
+               else if (reason & MSYS_CALLBACK_REASON_LBUTTON_UP )\r
+               {\r
+                       b->ubToggleButtonActivated = FALSE;\r
+               }\r
+       }\r
+\r
+\r
+       //Kris:\r
+       //Set the anchored button incase the user moves mouse off region while still holding\r
+       //down the button, but only if the button is up.  In Win95, buttons that are already\r
+       //down, and anchored never change state, unless you release the mouse in the button area.\r
+\r
+       if( b->MoveCallback == DEFAULT_MOVE_CALLBACK && b->uiFlags & BUTTON_ENABLED )\r
+       {\r
+               if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )\r
+               {\r
+                       gpAnchoredButton =  b;\r
+                       gfAnchoredState = StateBefore;\r
+                       b->uiFlags |= BUTTON_CLICKED_ON;\r
+               }\r
+               else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP && b->uiFlags & BUTTON_NO_TOGGLE )\r
+               {\r
+                       b->uiFlags &= (~BUTTON_CLICKED_ON);\r
+               }\r
+       }\r
+       else if( b->uiFlags & BUTTON_CHECKBOX )\r
+       {\r
+               if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )\r
+               {       //the check box button gets anchored, though it doesn't actually use the anchoring move callback.\r
+                       //The effect is different, we don't want to toggle the button state, but we do want to anchor this\r
+                       //button so that we don't effect any other buttons while we move the mouse around in anchor mode.\r
+                       gpAnchoredButton = b;\r
+                       gfAnchoredState = StateBefore;\r
+\r
+                       //Trick the before state of the button to be different so the sound will play properly as checkbox buttons \r
+                       //are processed differently.\r
+                       StateBefore = (b->uiFlags & BUTTON_CLICKED_ON) ? FALSE : TRUE;\r
+                       StateAfter = !StateBefore;\r
+               }\r
+               else if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )\r
+               {\r
+                       b->uiFlags ^= BUTTON_CLICKED_ON; //toggle the checkbox state upon release inside button area.\r
+                       //Trick the before state of the button to be different so the sound will play properly as checkbox buttons \r
+                       //are processed differently.\r
+                       StateBefore = (b->uiFlags & BUTTON_CLICKED_ON) ? FALSE : TRUE;\r
+                       StateAfter = !StateBefore;\r
+               }\r
+       }\r
+\r
+       // Should we play a sound if clicked on while disabled?\r
+       if( b->ubSoundSchemeID && !(b->uiFlags & BUTTON_ENABLED) && MouseBtnDown )\r
+       {\r
+               PlayButtonSound( iButtonID, BUTTON_SOUND_DISABLED_CLICK );\r
+       }\r
+\r
+       // If this button is disabled, and no callbacks allowed when disabled\r
+       // callback\r
+       if(!(b->uiFlags & BUTTON_ENABLED) && !(b->uiFlags & BUTTON_ALLOW_DISABLED_CALLBACK))\r
+               return;\r
+\r
+       // Button not enabled but allowed to use callback, then do that!\r
+       if(!(b->uiFlags & BUTTON_ENABLED) && (b->uiFlags & BUTTON_ALLOW_DISABLED_CALLBACK))\r
+       {\r
+               if( b->uiFlags & BUTTON_CLICK_CALLBACK )\r
+               {\r
+                       (b->ClickCallback)(b, reason | BUTTON_DISABLED_CALLBACK );\r
+               }\r
+               return;\r
+       }\r
+\r
+       // If there is a callback function with this button, call it\r
+       if(b->uiFlags & BUTTON_CLICK_CALLBACK)\r
+       {\r
+               //Kris:  January 6, 1998\r
+               //Added these checks to avoid a case where it was possible to process a leftbuttonup message when\r
+               //the button wasn't anchored, and should have been.\r
+               gfDelayButtonDeletion = TRUE;\r
+               if( !(reason & MSYS_CALLBACK_REASON_LBUTTON_UP) || b->MoveCallback != DEFAULT_MOVE_CALLBACK ||\r
+                               b->MoveCallback == DEFAULT_MOVE_CALLBACK && gpPrevAnchoredButton == b )\r
+                       (b->ClickCallback)(b,reason);\r
+               gfDelayButtonDeletion = FALSE;\r
+       }\r
+       else if((reason & MSYS_CALLBACK_REASON_LBUTTON_DWN) && !(b->uiFlags & BUTTON_IGNORE_CLICKS))\r
+       {\r
+               // Otherwise, do default action with this button.\r
+               b->uiFlags^=BUTTON_CLICKED_ON;\r
+       }\r
+\r
+       if( b->uiFlags & BUTTON_CHECKBOX )\r
+       {\r
+               StateAfter = (b->uiFlags & BUTTON_CLICKED_ON) ? (TRUE) : (FALSE);\r
+       }\r
+\r
+       // Play sounds for this enabled button (disabled sounds have already been done)\r
+       if( b->ubSoundSchemeID && b->uiFlags & BUTTON_ENABLED )\r
+       {\r
+               if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )\r
+               {\r
+                       if( b->ubSoundSchemeID && StateBefore && !StateAfter )\r
+                       {\r
+                               PlayButtonSound( iButtonID, BUTTON_SOUND_CLICKED_OFF );\r
+                       }\r
+               }\r
+               else if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )\r
+               {\r
+                       if( b->ubSoundSchemeID && !StateBefore && StateAfter)\r
+                       {\r
+                               PlayButtonSound( iButtonID, BUTTON_SOUND_CLICKED_ON );\r
+                       }\r
+               }\r
+       }\r
+\r
+       if( StateBefore != StateAfter )\r
+       {\r
+#ifdef JA2\r
+               InvalidateRegion(b->Area.RegionTopLeftX, b->Area.RegionTopLeftY, b->Area.RegionBottomRightX, b->Area.RegionBottomRightY);\r
+#endif\r
+       }\r
+\r
+       if( gfPendingButtonDeletion )\r
+       {\r
+               RemoveButtonsMarkedForDeletion();\r
+       }\r
+}\r
+\r
+void RenderButtons(void)\r
+{\r
+       INT32                   iButtonID;\r
+       BOOLEAN         fOldButtonDown, fOldEnabled;\r
+       GUI_BUTTON *b;\r
+\r
+       SaveFontSettings();\r
+       for(iButtonID=0;iButtonID<MAX_BUTTONS;iButtonID++)\r
+       {\r
+               // If the button exists, and it's not owned by another object, draw it\r
+               //Kris:  and make sure that the button isn't hidden.\r
+               b = ButtonList[iButtonID];\r
+               if( b && b->Area.uiFlags & MSYS_REGION_ENABLED )\r
+               {\r
+                       // Check for buttonchanged status\r
+                       fOldButtonDown = (BOOLEAN)(b->uiFlags & BUTTON_CLICKED_ON);\r
+\r
+                       if ( fOldButtonDown != ( b->uiOldFlags & BUTTON_CLICKED_ON ) )\r
+                       {\r
+                               //Something is different, set dirty!\r
+                               b->uiFlags |= BUTTON_DIRTY;\r
+                       }\r
+\r
+                       // Check for button dirty flags\r
+                       fOldEnabled = (BOOLEAN)(b->uiFlags & BUTTON_ENABLED);\r
+\r
+                       if ( fOldEnabled != ( b->uiOldFlags & BUTTON_ENABLED ) )\r
+                       {\r
+                               //Something is different, set dirty!\r
+                               b->uiFlags |= BUTTON_DIRTY;\r
+                       }\r
+\r
+                       // If we ABSOLUTELY want to render every frame....\r
+                       if ( b->uiFlags & BUTTON_SAVEBACKGROUND )\r
+                       {\r
+                               b->uiFlags |= BUTTON_DIRTY;\r
+                       }\r
+\r
+                       // Set old flags\r
+                       b->uiOldFlags = b->uiFlags;\r
+\r
+                       if ( b->uiFlags & BUTTON_FORCE_UNDIRTY )\r
+                       {\r
+                               b->uiFlags &= ~( BUTTON_DIRTY );\r
+                               b->uiFlags &= ~( BUTTON_FORCE_UNDIRTY );\r
+                       }\r
+\r
+                       // Check if we need to update!\r
+                       if ( b->uiFlags & BUTTON_DIRTY )\r
+                       {\r
+                               // Turn off dirty flag\r
+                               b->uiFlags &= (~BUTTON_DIRTY);\r
+                               DrawButtonFromPtr(b);\r
+\r
+#ifdef JA2\r
+                               InvalidateRegion(b->Area.RegionTopLeftX, b->Area.RegionTopLeftY, b->Area.RegionBottomRightX, b->Area.RegionBottomRightY);\r
+//#else\r
+//                             InvalidateRegion(b->Area.RegionTopLeftX, b->Area.RegionTopLeftY, b->Area.RegionBottomRightX, b->Area.RegionBottomRightY, FALSE);\r
+#endif\r
+\r
+                       }\r
+               }\r
+       }\r
+\r
+       // check if we want to render 1 frame later?\r
+       if( ( fPausedMarkButtonsDirtyFlag == TRUE ) && ( fDisableHelpTextRestoreFlag == FALSE ) )\r
+       {\r
+               fPausedMarkButtonsDirtyFlag = FALSE;\r
+               MarkButtonsDirty( );\r
+       }\r
+\r
+       RestoreFontSettings();\r
+}\r
+\r
+//*****************************************************************************\r
+// MarkAButtonDirty\r
+//\r
+void MarkAButtonDirty( INT32 iButtonNum )\r
+{\r
+  // surgical dirtying -> marks a user specified button dirty, without dirty the whole lot of them\r
+\r
+\r
+  // If the button exists, and it's not owned by another object, draw it\r
+               if( ButtonList[ iButtonNum ] )\r
+               {\r
+                       // Turn on dirty flag\r
+                       ButtonList[ iButtonNum ]->uiFlags |= BUTTON_DIRTY;\r
+               }\r
+\r
+}\r
+\r
+//=============================================================================\r
+//     MarkButtonsDirty\r
+//\r
+void MarkButtonsDirty( void )\r
+{\r
+       INT32 x;\r
+       for(x=0;x<MAX_BUTTONS;x++)\r
+       {\r
+               // If the button exists, and it's not owned by another object, draw it\r
+               if( ButtonList[x] )\r
+               {\r
+                       // Turn on dirty flag\r
+                       ButtonList[x]->uiFlags |= BUTTON_DIRTY;\r
+               }\r
+       }\r
+}\r
+\r
+\r
+void UnMarkButtonDirty( INT32 iButtonIndex )\r
+{\r
+  if ( ButtonList[ iButtonIndex ] )\r
+  {\r
+         ButtonList[ iButtonIndex ]->uiFlags &= ~( BUTTON_DIRTY );\r
+  }\r
+}\r
+\r
+void UnmarkButtonsDirty( void )\r
+{\r
+       INT32 x;\r
+       for(x=0;x<MAX_BUTTONS;x++)\r
+       {\r
+               // If the button exists, and it's not owned by another object, draw it\r
+               if( ButtonList[x] )\r
+               {\r
+                       UnMarkButtonDirty( x );\r
+               }\r
+       }\r
+}\r
+\r
+void ForceButtonUnDirty( INT32 iButtonIndex )\r
+{\r
+       ButtonList[ iButtonIndex ]->uiFlags &= ~( BUTTON_DIRTY );\r
+       ButtonList[ iButtonIndex ]->uiFlags |= BUTTON_FORCE_UNDIRTY;\r
+}\r
+\r
+//=============================================================================\r
+// PauseMarkButtonsDirty\r
+//\r
+\r
+void PausedMarkButtonsDirty( void )\r
+{\r
+       // set flag for frame after the next rendering of buttons\r
+       fPausedMarkButtonsDirtyFlag = TRUE;\r
+\r
+       return;\r
+}\r
+\r
+//=============================================================================\r
+//     DrawButton\r
+//\r
+//     Draws a single button on the screen.\r
+//\r
+BOOLEAN DrawButton(INT32 iButtonID )\r
+{\r
+       // Fail if button handle out of range\r
+       if( iButtonID < 0 || iButtonID > MAX_BUTTONS )\r
+               return FALSE;\r
+\r
+       // Fail if button handle is invalid\r
+       if( !ButtonList[ iButtonID ] )\r
+               return FALSE;\r
+\r
+       if( ButtonList[ iButtonID ]->string )\r
+               SaveFontSettings();\r
+       // Draw this button\r
+  if( ButtonList[ iButtonID ]->Area.uiFlags & MSYS_REGION_ENABLED )\r
+  {\r
+         DrawButtonFromPtr( ButtonList[ iButtonID ] );\r
+  }\r
+\r
+       if( ButtonList[ iButtonID ]->string )\r
+               RestoreFontSettings();\r
+       return TRUE;\r
+}\r
+\r
+\r
+\r
+//=============================================================================\r
+//     DrawButtonFromPtr\r
+//\r
+//     Given a pointer to a GUI_BUTTON structure, draws the button on the\r
+//     screen.\r
+//\r
+void DrawButtonFromPtr(GUI_BUTTON *b)\r
+{\r
+       Assert( b );\r
+       // Draw the appropriate button according to button type\r
+       gbDisabledButtonStyle = DISABLED_STYLE_NONE;\r
+       switch(b->uiFlags & BUTTON_TYPES)\r
+       {\r
+               case BUTTON_QUICK:\r
+                       DrawQuickButton(b);\r
+                       break;\r
+               case BUTTON_GENERIC:\r
+                       DrawGenericButton(b);\r
+                       break;\r
+               case BUTTON_HOT_SPOT:\r
+                       if(b->uiFlags & BUTTON_NO_TOGGLE)\r
+                               b->uiFlags &= (~BUTTON_CLICKED_ON);\r
+                       return;  //hotspots don't have text, but if you want to, change this to a break!\r
+               case BUTTON_CHECKBOX:\r
+                       DrawCheckBoxButton(b);\r
+                       break;\r
+       }\r
+       //If button has an icon, overlay it on current button.\r
+       if( b->iIconID != -1 )\r
+               DrawIconOnButton( b );\r
+       //If button has text, draw it now\r
+       if( b->string )\r
+               DrawTextOnButton( b );\r
+       //If the button is disabled, and a style has been calculated, then\r
+       //draw the style last.\r
+       switch( gbDisabledButtonStyle )\r
+       {\r
+               case DISABLED_STYLE_HATCHED:\r
+                       DrawHatchOnButton( b );\r
+                       break;\r
+               case DISABLED_STYLE_SHADED:\r
+                       DrawShadeOnButton( b );\r
+                       break;\r
+       }\r
+       if( b->bDefaultStatus )\r
+       {\r
+               DrawDefaultOnButton( b );\r
+       }\r
+}\r
+\r
+//=============================================================================\r
+//     DrawQuickButton\r
+//\r
+//     Draws a QuickButton type button on the screen.\r
+//\r
+void DrawQuickButton(GUI_BUTTON *b)\r
+{\r
+       INT32 UseImage;\r
+       UseImage=0;\r
+       // Is button Enabled, or diabled but no "Grayed" image associated with this QuickButton?\r
+       if(b->uiFlags & BUTTON_ENABLED )\r
+       {\r
+               // Is the button's state ON?\r
+               if(b->uiFlags & BUTTON_CLICKED_ON)\r
+               {\r
+                       // Is the mouse over this area, and we have a hilite image?\r
+                       if((b->Area.uiFlags & MSYS_MOUSE_IN_AREA) && gfRenderHilights &&\r
+                                       (ButtonPictures[b->ImageNum].OnHilite != -1))\r
+                               UseImage = ButtonPictures[b->ImageNum].OnHilite;                        // Use On-Hilite image\r
+                       else if(ButtonPictures[b->ImageNum].OnNormal != -1)\r
+                               UseImage = ButtonPictures[b->ImageNum].OnNormal;                        // Use On-Normal image\r
+               }\r
+               else\r
+               {\r
+                       // Is the mouse over the button, and do we have hilite image?\r
+                       if((b->Area.uiFlags & MSYS_MOUSE_IN_AREA) && gfRenderHilights &&\r
+                                       (ButtonPictures[b->ImageNum].OffHilite != -1))\r
+                               UseImage = ButtonPictures[b->ImageNum].OffHilite;                       // Use Off-Hilite image\r
+                       else if(ButtonPictures[b->ImageNum].OffNormal != -1)\r
+                               UseImage = ButtonPictures[b->ImageNum].OffNormal;                       // Use Off-Normal image\r
+               }\r
+       }\r
+       else if( ButtonPictures[b->ImageNum].Grayed != -1)\r
+       {       // Button is diabled so use the "Grayed-out" image\r
+               UseImage = ButtonPictures[b->ImageNum].Grayed;\r
+       }\r
+       else\r
+       {\r
+               UseImage = ButtonPictures[b->ImageNum].OffNormal;\r
+               switch( b->bDisabledStyle )\r
+               {\r
+                       case DISABLED_STYLE_DEFAULT:\r
+                               gbDisabledButtonStyle = b->string ? DISABLED_STYLE_SHADED : DISABLED_STYLE_HATCHED;\r
+                               break;\r
+                       case DISABLED_STYLE_HATCHED:\r
+                       case DISABLED_STYLE_SHADED:\r
+                               gbDisabledButtonStyle = b->bDisabledStyle;\r
+                               break;\r
+               }\r
+       }\r
+\r
+       // Display the button image\r
+       BltVideoObject(ButtonDestBuffer, ButtonPictures[b->ImageNum].vobj,\r
+                                                                (UINT16)UseImage, b->XLoc, b->YLoc,\r
+                                                                VO_BLT_SRCTRANSPARENCY, NULL);\r
+}\r
+\r
+void DrawHatchOnButton( GUI_BUTTON *b )\r
+{\r
+       UINT8    *pDestBuf;\r
+       UINT32 uiDestPitchBYTES;\r
+       SGPRect ClipRect;\r
+       ClipRect.iLeft = b->Area.RegionTopLeftX;\r
+       ClipRect.iRight = b->Area.RegionBottomRightX - 1;\r
+       ClipRect.iTop = b->Area.RegionTopLeftY;\r
+       ClipRect.iBottom = b->Area.RegionBottomRightY - 1;\r
+       pDestBuf = LockVideoSurface( ButtonDestBuffer, &uiDestPitchBYTES );\r
+       Blt16BPPBufferHatchRect( (UINT16*)pDestBuf, uiDestPitchBYTES, &ClipRect );\r
+       UnLockVideoSurface( ButtonDestBuffer );\r
+}\r
+\r
+void DrawShadeOnButton( GUI_BUTTON *b )\r
+{\r
+       UINT8 *pDestBuf;\r
+       UINT32 uiDestPitchBYTES;\r
+       SGPRect ClipRect;\r
+       ClipRect.iLeft = b->Area.RegionTopLeftX;\r
+       ClipRect.iRight = b->Area.RegionBottomRightX-1;\r
+       ClipRect.iTop = b->Area.RegionTopLeftY;\r
+       ClipRect.iBottom = b->Area.RegionBottomRightY-1;\r
+       pDestBuf = LockVideoSurface( ButtonDestBuffer, &uiDestPitchBYTES );\r
+       Blt16BPPBufferShadowRect( (UINT16*)pDestBuf, uiDestPitchBYTES, &ClipRect );\r
+       UnLockVideoSurface( ButtonDestBuffer );\r
+}\r
+\r
+void DrawDefaultOnButton( GUI_BUTTON *b )\r
+{\r
+       UINT8 *pDestBuf;\r
+       UINT32 uiDestPitchBYTES;\r
+       pDestBuf = LockVideoSurface( ButtonDestBuffer, &uiDestPitchBYTES );\r
+       SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, 640, 480 );\r
+       if( b->bDefaultStatus == DEFAULT_STATUS_DARKBORDER || b->bDefaultStatus == DEFAULT_STATUS_WINDOWS95 )\r
+       { \r
+               //left (one thick)\r
+               LineDraw( TRUE, b->Area.RegionTopLeftX-1, b->Area.RegionTopLeftY-1, b->Area.RegionTopLeftX-1, b->Area.RegionBottomRightY+1, 0, pDestBuf );\r
+               //top (one thick)\r
+               LineDraw( TRUE, b->Area.RegionTopLeftX-1, b->Area.RegionTopLeftY-1, b->Area.RegionBottomRightX+1, b->Area.RegionTopLeftY-1, 0, pDestBuf );\r
+               //right (two thick)\r
+               LineDraw( TRUE, b->Area.RegionBottomRightX, b->Area.RegionTopLeftY-1, b->Area.RegionBottomRightX, b->Area.RegionBottomRightY+1, 0, pDestBuf );\r
+               LineDraw( TRUE, b->Area.RegionBottomRightX+1, b->Area.RegionTopLeftY-1, b->Area.RegionBottomRightX+1, b->Area.RegionBottomRightY+1, 0, pDestBuf );\r
+               //bottom (two thick)\r
+               LineDraw( TRUE, b->Area.RegionTopLeftX-1, b->Area.RegionBottomRightY, b->Area.RegionBottomRightX+1, b->Area.RegionBottomRightY, 0, pDestBuf );\r
+               LineDraw( TRUE, b->Area.RegionTopLeftX-1, b->Area.RegionBottomRightY+1, b->Area.RegionBottomRightX+1, b->Area.RegionBottomRightY+1, 0, pDestBuf );\r
+               #ifdef JA2\r
+               InvalidateRegion( b->Area.RegionTopLeftX-1, b->Area.RegionTopLeftY-1, b->Area.RegionBottomRightX+1, b->Area.RegionBottomRightY+1 );\r
+               #endif\r
+       }\r
+       if( b->bDefaultStatus == DEFAULT_STATUS_DOTTEDINTERIOR || b->bDefaultStatus == DEFAULT_STATUS_WINDOWS95 )\r
+       { //Draw an internal dotted rectangle.\r
+\r
+       }\r
+       UnLockVideoSurface( ButtonDestBuffer );\r
+}\r
+\r
+void DrawCheckBoxButtonOn( INT32 iButtonID )\r
+{\r
+       GUI_BUTTON *b;\r
+       BOOLEAN fLeftButtonState = gfLeftButtonState;\r
+\r
+       Assert( iButtonID >= 0 );\r
+       Assert( iButtonID < MAX_BUTTONS);\r
+       b = ButtonList[ iButtonID ];\r
+       Assert( b );\r
+\r
+       gfLeftButtonState = TRUE;\r
+       b->Area.uiFlags |= MSYS_MOUSE_IN_AREA;\r
+\r
+       DrawButton( iButtonID );\r
+\r
+       gfLeftButtonState = fLeftButtonState;\r
+}\r
+\r
+void DrawCheckBoxButtonOff( INT32 iButtonID )\r
+{\r
+       GUI_BUTTON *b;\r
+       BOOLEAN fLeftButtonState = gfLeftButtonState;\r
+\r
+       Assert( iButtonID >= 0 );\r
+       Assert( iButtonID < MAX_BUTTONS);\r
+       b = ButtonList[ iButtonID ];\r
+       Assert( b );\r
+\r
+       gfLeftButtonState = FALSE;\r
+       b->Area.uiFlags |= MSYS_MOUSE_IN_AREA;\r
+\r
+       DrawButton( iButtonID );\r
+\r
+       gfLeftButtonState = fLeftButtonState;\r
+}\r
+\r
+\r
+void DrawCheckBoxButton( GUI_BUTTON *b )\r
+{\r
+       INT32 UseImage;\r
+\r
+       UseImage=0;\r
+       // Is button Enabled, or diabled but no "Grayed" image associated with this QuickButton?\r
+       if( b->uiFlags & BUTTON_ENABLED )\r
+       {\r
+               // Is the button's state ON?\r
+               if(b->uiFlags & BUTTON_CLICKED_ON)\r
+               {\r
+                       // Is the mouse over this area, and we have a hilite image?\r
+                       if( b->Area.uiFlags & MSYS_MOUSE_IN_AREA && gfRenderHilights &&\r
+                                       gfLeftButtonState &&\r
+                                       ButtonPictures[b->ImageNum].OnHilite != -1 )\r
+                               UseImage = ButtonPictures[b->ImageNum].OnHilite;                        // Use On-Hilite image\r
+                       else if(ButtonPictures[b->ImageNum].OnNormal != -1)\r
+                               UseImage = ButtonPictures[b->ImageNum].OnNormal;                        // Use On-Normal image\r
+               }\r
+               else\r
+               {\r
+                       // Is the mouse over the button, and do we have hilite image?\r
+                       if( b->Area.uiFlags & MSYS_MOUSE_IN_AREA && gfRenderHilights &&\r
+                                 gfLeftButtonState &&\r
+                                       ButtonPictures[b->ImageNum].OffHilite != -1 )\r
+                               UseImage = ButtonPictures[b->ImageNum].OffHilite;                       // Use Off-Hilite image\r
+                       else if(ButtonPictures[b->ImageNum].OffNormal != -1)\r
+                               UseImage = ButtonPictures[b->ImageNum].OffNormal;                       // Use Off-Normal image\r
+               }\r
+       }\r
+       else if( ButtonPictures[b->ImageNum].Grayed != -1 )\r
+       {       // Button is disabled so use the "Grayed-out" image\r
+               UseImage = ButtonPictures[b->ImageNum].Grayed;\r
+       }\r
+       else //use the disabled style\r
+       {\r
+               if( b->uiFlags & BUTTON_CLICKED_ON )\r
+                       UseImage = ButtonPictures[b->ImageNum].OnHilite;\r
+               else\r
+                       UseImage = ButtonPictures[b->ImageNum].OffHilite;\r
+               switch( b->bDisabledStyle )\r
+               {\r
+                       case DISABLED_STYLE_DEFAULT:\r
+                               gbDisabledButtonStyle = DISABLED_STYLE_HATCHED;\r
+                               break;\r
+                       case DISABLED_STYLE_HATCHED:\r
+                       case DISABLED_STYLE_SHADED:\r
+                               gbDisabledButtonStyle = b->bDisabledStyle;\r
+                               break;\r
+               }\r
+       }\r
+\r
+       // Display the button image\r
+       BltVideoObject(ButtonDestBuffer, ButtonPictures[b->ImageNum].vobj,\r
+                                                                (UINT16)UseImage, b->XLoc, b->YLoc,\r
+                                                                VO_BLT_SRCTRANSPARENCY, NULL);\r
+}\r
+\r
+void DrawIconOnButton(GUI_BUTTON *b)\r
+{\r
+       INT32 xp,yp,width,height,IconX,IconY;\r
+       INT32 IconW,IconH;\r
+       SGPRect NewClip,OldClip;\r
+       ETRLEObject             *pTrav;\r
+       HVOBJECT        hvObject;\r
+\r
+       // If there's an actual icon on this button, try to show it.\r
+       if(b->iIconID >= 0)\r
+       {\r
+               // Get width and height of button area\r
+               width = b->Area.RegionBottomRightX - b->Area.RegionTopLeftX;\r
+               height = b->Area.RegionBottomRightY - b->Area.RegionTopLeftY;\r
+\r
+               // Compute viewable area (inside borders)\r
+               NewClip.iLeft = b->XLoc + 3;\r
+               NewClip.iRight = b->XLoc + width - 3;\r
+               NewClip.iTop = b->YLoc + 2;\r
+               NewClip.iBottom = b->YLoc + height - 2;\r
+\r
+               // Get Icon's blit start coordinates\r
+               IconX = NewClip.iLeft;\r
+               IconY = NewClip.iTop;\r
+\r
+               // Get current clip area\r
+               GetClippingRect(&OldClip);\r
+\r
+               // Clip button's viewable area coords to screen\r
+               if(NewClip.iLeft < OldClip.iLeft)\r
+                       NewClip.iLeft = OldClip.iLeft;\r
+\r
+               // Is button right off the right side of the screen?\r
+               if(NewClip.iLeft > OldClip.iRight)\r
+                       return;\r
+\r
+               if(NewClip.iRight > OldClip.iRight)\r
+                       NewClip.iRight = OldClip.iRight;\r
+\r
+               // Is button completely off the left side of the screen?\r
+               if(NewClip.iRight < OldClip.iLeft)\r
+                       return;\r
+\r
+               if(NewClip.iTop < OldClip.iTop)\r
+                       NewClip.iTop = OldClip.iTop;\r
+\r
+               // Are we right off the bottom of the screen?\r
+               if(NewClip.iTop > OldClip.iBottom)\r
+                       return;\r
+\r
+               if(NewClip.iBottom > OldClip.iBottom)\r
+                       NewClip.iBottom = OldClip.iBottom;\r
+\r
+               // Are we off the top?\r
+               if(NewClip.iBottom < OldClip.iTop)\r
+                       return;\r
+\r
+               // Did we clip the viewable area out of existance?\r
+               if((NewClip.iRight <= NewClip.iLeft) || (NewClip.iBottom <= NewClip.iTop))\r
+                       return;\r
+\r
+               // Get the width and height of the icon itself\r
+               if( b->uiFlags & BUTTON_GENERIC )\r
+                       pTrav = &(GenericButtonIcons[b->iIconID]->pETRLEObject[b->usIconIndex]);\r
+               else\r
+               {\r
+                       GetVideoObject( &hvObject, b->iIconID );\r
+                       pTrav = &(hvObject->pETRLEObject[b->usIconIndex] );\r
+               }\r
+               IconH = (UINT32)(pTrav->usHeight+pTrav->sOffsetY);\r
+               IconW = (UINT32)(pTrav->usWidth+pTrav->sOffsetX);\r
+\r
+               // Compute coordinates for centering the icon on the button or\r
+               // use the offset system.\r
+               if( b->bIconXOffset == -1 )\r
+                       xp = (((width-6)-IconW) / 2) + IconX;\r
+               else\r
+                       xp = b->Area.RegionTopLeftX + b->bIconXOffset;\r
+               if( b->bIconYOffset == -1 )\r
+                       yp = (((height-4)-IconH) / 2) + IconY;\r
+               else\r
+                       yp = b->Area.RegionTopLeftY + b->bIconYOffset;\r
+\r
+               // Was the button clicked on? if so, move the image slightly for the illusion\r
+               // that the image moved into the screen.\r
+               if( b->uiFlags & BUTTON_CLICKED_ON && b->fShiftImage )\r
+               {\r
+                       xp++;\r
+                       yp++;\r
+               }\r
+\r
+               // Set the clipping rectangle to the viewable area of the button\r
+               SetClippingRect(&NewClip);\r
+               // Blit the icon\r
+               if( b->uiFlags & BUTTON_GENERIC )\r
+                       BltVideoObject( ButtonDestBuffer,GenericButtonIcons[b->iIconID], b->usIconIndex, (INT16)xp, (INT16)yp,\r
+                                                                                 VO_BLT_SRCTRANSPARENCY, NULL);\r
+               else\r
+                       BltVideoObject( ButtonDestBuffer, hvObject, b->usIconIndex, (INT16)xp, (INT16)yp,\r
+