📄 nexus.pas
字号:
//////////////////////////////////////////////////////////////////////
// //
// nexus.pas: Mappy VM core interface and common utility functions //
// //
// The contents of this file are subject to the Bottled Light //
// Public License Version 1.0 (the "License"); you may not use this //
// file except in compliance with the License. You may obtain a //
// copy of the License at http://www.bottledlight.com/BLPL/ //
// //
// Software distributed under the License is distributed on an //
// "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or //
// implied. See the License for the specific language governing //
// rights and limitations under the License. //
// //
// The Original Code is the Mappy VM User Interface, released //
// April 1st, 2003. The Initial Developer of the Original Code is //
// Bottled Light, Inc. Portions created by Bottled Light, Inc. are //
// Copyright (C) 2001-2003 Bottled Light, Inc. All Rights Reserved. //
// //
// Author(s): //
// Michael Noland (joat), michael@bottledlight.com //
// //
// Changelog: //
// 1.0: First public release (April 1st, 2003) //
// //
// Notes: //
// None at present. //
// //
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
unit nexus; //////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
interface ////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
uses
Windows, Classes, Menus, Graphics, SysUtils, ShellApi, TypInfo,
AddressSpace;
//////////////////////////////////////////////////////////////////////
type
TvmPluginHeader = packed record
// Filled in by the plugin writer
author: PChar;
name: PChar;
version: integer;
description: PChar;
Init: procedure; cdecl;
Destroy: procedure; cdecl;
// The caption to display in the tools menu (return nil
// if there is no OnUpdate), not implemented yet
ObserverCaption: PChar;
Update: procedure; cdecl;
// the caption for ShowConfig (return nil if theres no config.)
configCaption: PChar;
ShowConfig: procedure; cdecl;
// the caption for Trigger (return nil if there is no trigger)
triggerCaption: PChar;
Trigger: procedure; cdecl;
// Filled in by Mappy VM
mem: TvmMemoryLock1;
OnStatus: function (progress: integer): boolean; cdecl;
// OnClose: procedure; cdecl;
// LogWrite(st: PChar);
end;
PvmPluginHeader = ^TvmPluginHeader;
//////////////////////////////////////////////////////////////////////
var
vmReset: procedure ;
vmExecute: function (numCycles: integer): uint32;
vmStep: procedure ;
vmGetRegister: function (index: uint32): uint32;
vmGetRegisters: procedure (var copy: TvmRegisterFile);
vmSetRegister: procedure (index, value: uint32);
vmSetRegisters: procedure (const copy: TvmRegisterFile);
vmStartProfile: function : TvmProfileToken;
vmStopProfile: function (const token: TvmProfileToken): int64;
vmCurrentPC: function : uint32;
vmHitBP: function : boolean;
vmRenderFrame: procedure;
vmGetLayerID: function (x: integer): byte;
vmDrawScanline: function (y, width: integer): Puint16;
vmRenderSprite: procedure (i: integer; y: integer; line: Puint16);
vmReadByte: function (address: uint32): uint8;
vmReadHalfword: function (address: uint32): uint16;
vmReadWord: function (address: uint32): uint32;
vmWriteByte: procedure (address: uint32; data: uint8);
vmWriteHalfword: procedure (address: uint32; data: uint16);
vmWriteWord: procedure (address: uint32; data: uint32);
vmAddBreakpoint: procedure (address: uint32; soft: boolean);
vmRemoveBreakpoint: procedure (address: uint32; mask: TBreakpointModes);
vmSoftBreakpoints: procedure (active: boolean);
vmIsBreakpoint: function (address: uint32): TBreakpointModes;
vmInsertCartridge: procedure (data: pointer; size: integer);
vmRemoveCartridge: procedure;
vmLockMemory: procedure (var banks: TvmMemoryLock1);
vmUnlockMemory: procedure (const banks: TvmMemoryLock1);
vmKeyInput: procedure (mask: integer);
vmSetOnSound: procedure (callback: TvmOnSoundReady);
vmSetOnVideo: procedure (callback: TvmOnVideoReady);
vmSetOnConsole: procedure (callback: TvmOnConsoleReady);
vmSetAudioRate: procedure (cyclesPerSample: integer);
vmGetAudioData: procedure (var data: pointer; var length: integer);
vmGetCartInfo: function (info: PvmOpaqueChunk): integer;
vmSetCartInfo: procedure (size: integer; info: PvmOpaqueChunk);
vmSaveState: function (save: PvmSavestate): integer;
vmLoadState: procedure (save: PvmSavestate);
vmGetOption: function (st: PChar): boolean;
vmSetOption: procedure (st: PChar; enabled: boolean);
//////////////////////////////////////////////////////////////////////
var
coreLoaded: boolean;
cpuSourceDebug: boolean;
helpFiles: TStringList;
translation: TStringList;
appIniFile: string;
//////////////////////////////////////////////////////////////////////
procedure vmLoadCore(filename: PChar);
procedure vmUnloadCore;
function LinkHelp(url: string): integer;
procedure ShowWebPage(url: string);
procedure LoadTranslation(root: TComponent; list: TStringList);
procedure SaveTranslation(root: TComponent; list: TStringList);
//////////////////////////////////////////////////////////////////////
implementation ///////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
var
DLLHandle: uint32;
//////////////////////////////////////////////////////////////////////
function LinkHelp(url: string): integer;
var
i: integer;
begin
url := 'file://' + ExtractFilePath(ParamStr(0)) + 'help/' + url;
i := helpFiles.IndexOf(url);
if i = -1 then i := helpFiles.Add(url);
Result := i+1;
end;
//////////////////////////////////////////////////////////////////////
procedure ShowWebPage(url: string);
begin
ShellExecute(0, nil, PChar(url), nil, nil, SW_NORMAL);
end;
//////////////////////////////////////////////////////////////////////
procedure vmLoadCore(filename: PChar);
begin
if coreLoaded then vmUnloadCore;
DLLHandle := LoadLibrary(filename);
if DLLHandle >= 32 then begin
vmReset := GetProcAddress(DLLHandle, 'vmReset');
vmExecute := GetProcAddress(DLLHandle, 'vmExecute');
vmStep := GetProcAddress(DLLHandle, 'vmStep');
vmGetRegister := GetProcAddress(DLLHandle, 'vmGetRegister');
vmGetRegisters := GetProcAddress(DLLHandle, 'vmGetRegisters');
vmSetRegister := GetProcAddress(DLLHandle, 'vmSetRegister');
vmSetRegisters := GetProcAddress(DLLHandle, 'vmSetRegisters');
vmStartProfile := GetProcAddress(DLLHandle, 'vmStartProfile');
vmStopProfile := GetProcAddress(DLLHandle, 'vmStopProfile');
vmCurrentPC := GetProcAddress(DLLHandle, 'vmCurrentPC');
vmHitBP := GetProcAddress(DLLHandle, 'vmHitBP');
vmRenderFrame := GetProcAddress(DLLHandle, 'vmRenderFrame');
vmGetLayerID := GetProcAddress(DLLHandle, 'vmGetLayerID');
vmDrawScanline := GetProcAddress(DLLHandle, 'vmDrawScanline');
vmRenderSprite := GetProcAddress(DLLHandle, 'vmRenderSprite');
vmReadByte := GetProcAddress(DLLHandle, 'vmReadByte');
vmReadHalfword := GetProcAddress(DLLHandle, 'vmReadHalfword');
vmReadWord := GetProcAddress(DLLHandle, 'vmReadWord');
vmWriteByte := GetProcAddress(DLLHandle, 'vmWriteByte');
vmWriteHalfword := GetProcAddress(DLLHandle, 'vmWriteHalfword');
vmWriteWord := GetProcAddress(DLLHandle, 'vmWriteWord');
vmAddBreakpoint := GetProcAddress(DLLHandle, 'vmAddBreakpoint');
vmRemoveBreakpoint := GetProcAddress(DLLHandle, 'vmRemoveBreakpoint');
vmSoftBreakpoints := GetProcAddress(DLLHandle, 'vmSoftBreakpoints');
vmIsBreakpoint := GetProcAddress(DLLHandle, 'vmIsBreakpoint');
vmInsertCartridge := GetProcAddress(DLLHandle, 'vmInsertCartridge');
vmRemoveCartridge := GetProcAddress(DLLHandle, 'vmRemoveCartridge');
vmLockMemory := GetProcAddress(DLLHandle, 'vmLockMemory');
vmUnlockMemory := GetProcAddress(DLLHandle, 'vmUnlockMemory');
vmKeyInput := GetProcAddress(DLLHandle, 'vmKeyInput');
vmSetOnSound := GetProcAddress(DLLHandle, 'vmSetOnSound');
vmSetOnVideo := GetProcAddress(DLLHandle, 'vmSetOnVideo');
vmSetOnConsole := GetProcAddress(DLLHandle, 'vmSetOnConsole');
vmSetAudioRate := GetProcAddress(DLLHandle, 'vmSetAudioRate');
vmGetAudioData := GetProcAddress(DLLHandle, 'vmGetAudioData');
vmGetCartInfo := GetProcAddress(DLLHandle, 'vmGetCartInfo');
vmSetCartInfo := GetProcAddress(DLLHandle, 'vmSetCartInfo');
vmSaveState := GetProcAddress(DLLHandle, 'vmSaveState');
vmLoadState := GetProcAddress(DLLHandle, 'vmLoadState');
vmGetOption := GetProcAddress(DLLHandle, 'vmGetOption');
vmSetOption := GetProcAddress(DLLHandle, 'vmSetOption');
coreLoaded := true;
end else
coreLoaded := false;
end;
//////////////////////////////////////////////////////////////////////
procedure vmUnloadCore;
begin
FreeLibrary(DLLHandle);
coreLoaded := false;
end;
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
function SplitString(var st: string): string;
var
i: integer;
begin
i := Pos('.', st);
Result := Copy(st, 1, i-1);
Delete(st, 1, i);
end;
//////////////////////////////////////////////////////////////////////
procedure LoadTranslation(root: TComponent; list: TStringList);
var
i: integer;
c: TComponent;
prop: string;
begin
for i := 0 to list.Count - 1 do begin
prop := list.Names[i];
if SplitString(prop) = root.Name then begin
c := root.FindComponent(SplitString(prop));
if assigned(c) then begin
if prop = 'caption' then
SetStrProp(c, prop, list.values[list.Names[i]])
else if prop = 'shortcut' then
SetOrdProp(c, prop, TextToShortCut(list.values[list.names[i]]))
else if prop = 'color' then
SetOrdProp(c, prop, StringToColor(list.values[list.names[i]]));
end;
end;
end;
end;
//////////////////////////////////////////////////////////////////////
procedure SaveTranslation(root: TComponent; list: TStringList);
var
i: integer;
c: TComponent;
st: string;
begin
for i := 0 to root.ComponentCount - 1 do begin
c := root.Components[i];
if c.Name <> '' then begin
if IsPublishedProp(c, 'caption') then begin
st := GetStrProp(c, 'caption');
if (st <> '') and (st <> '-') then list.add(root.Name + '.' + c.Name + '.caption=' + st);
end else st := '';
if st <> '-' then begin
if IsPublishedProp(c, 'shortcut') then list.add(root.Name + '.' + c.Name + '.shortcut=' + ShortCutToText(GetOrdProp(c, 'shortcut')));
if IsPublishedProp(c, 'color') then list.add(root.Name + '.' + c.Name + '.color=' + ColorToString(GetOrdProp(c, 'color')));
end;
end;
end;
end;
//////////////////////////////////////////////////////////////////////
initialization
helpFiles := TStringList.Create;
translation := TStringList.Create;
if FileExists(ExtractFilePath(ParamStr(0)) + 'baseline.trs') then
translation.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'baseline.trs');
appIniFile := ExtractFilePath(ParamStr(0)) + 'settings.ini';
finalization
translation.Free;
helpFiles.Free;
if coreLoaded then vmUnloadCore;
end.
//////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -