library Vision; {$mode delphi}{$H+} {$R *.res} uses Classes { you can add units after this } , Mainform ,uHCDefines , uHCGCI, uHCGlobals, uHCTypeDefs, uHCEventHelpers, uHCDateTime , uHCAnnexDefs, uHCAnnexHelpers, uLazGUIGlobals, uHCUtils , Windows, Forms, ShellAPI, SysUtils ,Types ,Dialogs, Interfaces, Controls, FileInfo; const DLLVERN = 1; DLLVERINTN = 42; //39 var frmMain: TfrmMain; // intGameTime: Long; FileVersionInfo: TFileVersionInfo; strFileVers, strGEVers: String; {*** Return DLL internal version, i.e. revision 5 of my DLL ***} function DLLVer():word;export;cdecl; begin result := DLLVERN; end; {*** Return DLL interface version, i.e. revision 1 of my HCE interface spec ***} function DLLVerInt():word;export;cdecl; begin result := DLLVERINTN; end; {*** Return DLL description, 255 characters max ***} function DLLDesc():PAnsiChar;export;cdecl; begin result := 'use with HC to provide assistance for sight impared by Don Thomas'; end; {*** Free DLL ***} procedure DLLFree();export;cdecl; begin // Do any cleanup here, this is the end frmMain.WindowState:= wsMinimized; // 240906 frmMain.Free; end; {*** Init DLL ***} procedure DLLInit(hwndHC: HWND; pathHC: PAnsiChar; verHC: PAnsiChar; verSaveGame: LongWord; funcRefs: PHCDLL_FUNC_REF; PGEClosing: Pointer; PDLLBusy: Pointer; verInterface: LongWord; srandSeed: longword; harpoon_uuid_session: PAnsiChar; hclicense_dt_expire: Int64; hclicense_licensee: PAnsiChar; usblicense_desc: PAnsiChar; RESRSRStructureVersion: ulong; AnnexVersion: ushort //; GameComponent: uchar; pLosTable: PHCLosTable );export;cdecl; var funcTmp: PHCDLL_FUNC_REF; begin // here we initialize globals and such for the life of the DLL Application.Initialize; // ALE 20120410 Freezes HC Application.Run; uLazGUIGlobals.PGEClosing:=PGEClosing; uLazGUIGlobals.PDLLBusy:=PDLLBusy; uLazGUIGlobals.hwndHC:=hwndHC; // 20230405 version update uLazGUIGlobals.intVerInterface:=verInterface; uLazGUIGlobals.intVerSaveGame:=verSaveGame; FileVersionInfo:= TFileVersionInfo.Create(nil); FileVersionInfo.ReadFileInfo; frmMain := TfrmMain.Create(nil); // frmMain.ParentWindow := hwndHC; // 230407 reside in harpwindow 250608 strFileVers:= FileVersionInfo.VersionStrings.Values['FileVersion']; FileVersionInfo.Free; if Length(strFileVers) = 0 then strFileVers := '1.0.2'; frmMain.Caption := 'Vision V ' + strFileVers + ', ExportDLL Interface v ' + IntToStr(DLLVERINTN) + 'for GE v 2023.003+'; // ALE 20130908 List the function pointers sent over by the GE // then capture one of them for example usage funcTmp := funcRefs; while (funcTmp <> nil) do begin if (funcTmp^.funcName = 'NewPtr') then frmMain.NewPtr := funcTmp^.funcPtr else if (funcTmp^.funcName = 'DispPtr') then frmMain.DisposPtr := funcTmp^.funcPtr else if (funcTmp^.funcName = 'del_HarpoonEvent_list') then frmMain.del_HarpoonEvent_list := PHCDLL_FUNC_REF(PHCDLL_FUNC_REF(funcRefs^.next).next).funcPtr else if (funcTmp^.funcName = 'QueueHarpoonEvent') then frmMain.HCQueueHarpoonEvent := THCQueueHarpoonEvent(funcTmp^.funcPtr) else if (funcTmp^.funcName = 'dllCheckLatLonDepth') then frmMain.HCdllCheckLatLonDepth := THCdllCheckLatLonDepth(funcTmp^.funcPtr) else if (funcTmp^.funcName = 'annex_id_to_disk_id') then frmMain.HCannex_id_to_disk_id := THCannex_id_to_disk_id(funcTmp^.funcPtr) else if (funcTmp^.funcName = 'disk_id_to_annex_id') then frmMain.HCdisk_id_to_annex_id := THCdisk_id_to_annex_id(funcTmp^.funcPtr) else if (funcTmp^.funcName = 'free_Unit') then frmMain.HCfree_Unit := THCfree_Unit(funcTmp^.funcPtr) else if (funcTmp^.funcName = 'free_Group') then frmMain.HCfree_Group := THCfree_Group(funcTmp^.funcPtr) else if (funcTmp^.funcName = 'ChangeActGroupPtr') then frmMain.HCChangeActGroupPtr := THCChangeActGroupPtr(funcTmp^.funcPtr) else if (funcTmp^.funcName = 'ChangeActUnitPtr') then frmMain.HCChangeActUnitPtr := THCChangeActUnitPtr(funcTmp^.funcPtr) ; funcTmp := funcTmp^.next; end; frmMain.Show; frmMain.WindowState:= wsMaximized; // 250608 // frmMain.Top:= 10; // frmMain.Left:= 0; // 250525 user is blind so stick top left? frmMain.BringToFront; frmMain.PageControl1.ActivePage:= frmMain.tshStartGroup; frmMain.tshStartGroup.SetFocus; frmMain.SGlbxGroups.SetFocus; // 250608 strGEVers:= verHC; end; procedure ScenLoad(strHarpPath: PAnsiChar; intScenNum: SmallInt; strScenFPath: PAnsiChar; intBSNum: ShortInt; strBSFName: PAnsiChar; intSide: byte; intGameTimeIn: Long; intGameTimeLeftIn: Long; // 20230405 dt_scen_start_in: PHCDateTimeRec; AnnexDataIn: PHCAnnexes_disk; DatabaseVersionDBIn: PHCDATABASE_VERSION; ScenDataIn: PHCSCENARIO_DATA; ScenSaveDataIn: PHCSCENARIO_SAVE_DATA; GlobalsIn: PHCGlobals);export;cdecl; var intIdx: NativeUInt; pLoadout: PHCAnnexY1_disk; pShip: PHCAnnexA1_disk; pSub: PHCAnnexA2_disk; pAir: PHCAnnexB1_disk; pBase: PHCAnnexP1_disk; pGun: PHCAnnexC1_disk; pMissile: PHCAnnexD1_disk; pBomb: PHCAnnexG1_disk; pECM: PHCAnnexG2_disk; pNuke: PHCAnnexI1_disk; pRadar: PHCAnnexJ1_disk; pSonar: PHCAnnexM1_disk; pMount: PHCAnnexZ1_disk; pMulti: PHCAnnexZ2_disk; strScenNum, strBatSetName: string; TimeNowTimeRec: THCDateTimeRec; begin frmMain.intPSide:= intSide; intGameTime := intGameTimeIn; // ALE 20150712 Now that we receive the game time here, store it intGameTimeLeft := intGameTimeLeftIn; frmMain.gTicker:= 0; frmMain.SGButtonRefresh.Click; // 250610 frmMain.SGlbxGroups.SetFocus; // 250610 end; procedure DBLoaded(AnnexDataIn: PHCAnnexes_disk; AnnexDataMemIn: PHCAnnexes_mem) export; cdecl; begin if (AnnexDataMemIn = nil) then begin AnnexData := AnnexDataIn; HCAnnexHelper := THCAnnexHelper.Create(AnnexDataIn, frmMain.HCannex_id_to_disk_id, uLazGUIGlobals.intVerInterface, uLazGUIGlobals.intVerSaveGame); end else begin AnnexData_mem := AnnexDataMemIn; HCAnnexMemHelper := THCAnnexMemHelper.Create(AnnexDataMemIn, frmMain.HCannex_id_to_disk_id); end; end; procedure StartGroup(StartGroup: PHCGroup);export;cdecl; var PHCGThis: PHCGroup; begin frmMain.PStartGroup:=StartGroup; end; procedure ActGroupPtr(ActGroup: PHCGroup); export; cdecl; // 240624 begin frmMain.gPActGroup:= ActGroup; if ActGroup <> nil then // if there is an active group and it is myside reset Surf/sub // 250610 if ActGroup^.side = frmMain.intPSide then frmMain.SGButtonRefresh.Click; end; procedure UnitTop(topUnit: PHCUnit);export;cdecl; begin frmMain.gPHCtopUnit:= topUnit; end; procedure GameTime(GameTime: Long; GameTimeLeft: Long); export; cdecl; begin frmMain.gTicker:= frmMain.gTicker + 1; if frmMain.gTicker > 600 then begin frmMain.gTicker:= 0; frmMain.SGButtonDepthChk.Click; end; end; procedure HarpoonEventHead(HarpEventHead: PHCHarpoonEvent);export;cdecl; begin If HarpEventHead <> nil then begin frmMain.PHCEventHead:= HarpEventHead; end; end; function Staff(side: short; button: short; picnum: short; message: pchar; unit_involved: PHCUNIT; outcome: plong): CBOOL; export; cdecl; var lThisUnitStr, lThisGroupStr: String; PThisGroup: PHCGroup; begin result := CFALSE; // keep use in game interface outcome^ := 2; // IDCANCEL ???? if unit_involved <> nil then begin // 250623 PThisGroup:= unit_involved^.Group; lThisGroupStr:= PThisGroup^.id + ':'; end else begin lThisGroupStr:= ''; PThisGroup:= nil; end; frmMain.PostMessage(message, PThisGroup); end; procedure MsgLog(MsgLine: PAnsiChar);export;cdecl; var lGroup: PHCGroup; begin lGroup:= nil; if Pos('ITER',MSGLine) = 0 then // filter out report of iterative saves frmMain.PostMessage(MsgLine,lGroup); // 20250704 end; exports DLLVer, DLLVerInt, DLLDesc, DLLFree, DLLInit, ScenLoad, StartGroup, UnitTop, HarpoonEventHead, Staff, DBLoaded ,GameTime ,ActGroupPtr , MsgLog // ,ActUnitPtr ; end.