diff --git a/src/editor/f_main.pas b/src/editor/f_main.pas
index d3193006eebd27184d3b0bc384de61a50d60962e..a63b81e0b75abf83576ca7c4b60416b2253ef72b 100644 (file)
--- a/src/editor/f_main.pas
+++ b/src/editor/f_main.pas
LCLIntf, LCLType, LMessages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, ImgList, StdCtrls, Buttons,
ComCtrls, ValEdit, Types, ToolWin, Menus, ExtCtrls,
- CheckLst, Grids;
+ CheckLst, Grids, OpenGLContext;
type
+
+ { TMainForm }
+
TMainForm = class(TForm)
+ lLoad: TLabel;
// Главное меню:
MainMenu: TMainMenu;
// "Файл":
// Панель инструментов:
MainToolBar: TToolBar;
+ pbLoad: TProgressBar;
+ pLoadProgress: TPanel;
+ RenderPanel: TOpenGLControl;
tbNewMap: TToolButton;
tbOpenMap: TToolButton;
tbSaveMap: TToolButton;
// Панель карты:
PanelMap: TPanel;
- // Панель отображения карты:
- RenderPanel: TPanel;
- // Панель загрузки:
- pLoadProgress: TPanel;
- lLoad: TLabel;
- pbLoad: TProgressBar;
// Полосы прокрутки:
sbHorizontal: TScrollBar;
sbVertical: TScrollBar;
procedure RenderPanelMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure RenderPanelMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
procedure RenderPanelMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
+ procedure RenderPanelPaint(Sender: TObject);
procedure RenderPanelResize(Sender: TObject);
procedure vleObjectPropertyEditButtonClick(Sender: TObject);
procedure vleObjectPropertyGetPickList(Sender: TObject; const KeyName: String; Values: TStrings);
implementation
uses
- f_options, e_graphics, e_log, dglOpenGL, Math,
+ f_options, e_graphics, e_log, GL, GLExt, Math,
f_mapoptions, g_basic, f_about, f_mapoptimization,
f_mapcheck, f_addresource_texture, g_textures,
f_activationtype, f_keys, MAPWRITER, MAPSTRUCT,
- MAPREADER, f_selectmap, f_savemap, WADEDITOR, MAPDEF,
+ MAPREADER, f_selectmap, f_savemap, WADEDITOR, WADSTRUCT, MAPDEF,
g_map, f_saveminimap, f_addresource, CONFIG, f_packmap,
f_addresource_sound, f_maptest, f_choosetype,
- g_language, f_selectlang, ClipBrd, Windows;
+ g_language, f_selectlang, ClipBrd;
const
UNDO_DELETE_PANEL = 1;
TCopyRecArray = Array of TCopyRec;
var
- hDC: THandle;
- hRC: THandle;
gEditorFont: DWORD;
+ gDataLoaded: Boolean = False;
ShowMap: Boolean = False;
DrawRect: PRect = nil;
SnapToGrid: Boolean = True;
function AddTexture(aWAD, aSection, aTex: String; silent: Boolean): Boolean;
var
- a: Integer;
+ a, FrameLen: Integer;
ok: Boolean;
FileName: String;
ResourceName: String;
if IsAnim(FullResourceName) then
begin // Аним. текстура
- GetFrame(FullResourceName, Data, Width, Height);
+ GetFrame(FullResourceName, Data, FrameLen, Width, Height);
- if g_CreateTextureMemorySize(Data, ResourceName, 0, 0, Width, Height, 1) then
+ if g_CreateTextureMemorySize(Data, FrameLen, ResourceName, 0, 0, Width, Height, 1) then
a := MainForm.lbTextureList.Items.Add(ResourceName);
end
else // Обычная текстура
OptionsForm.ShowModal();
end;
-procedure TMainForm.FormCreate(Sender: TObject);
+procedure LoadStdFont(cfgres, texture: string; var FontID: DWORD);
var
- PixelFormat: GLuint;
- pfd: TPIXELFORMATDESCRIPTOR;
+ cwdt, chgt: Byte;
+ spc: ShortInt;
+ ID: DWORD;
+ wad: TWADEditor_1;
+ cfgdata: Pointer;
+ cfglen: Integer;
config: TConfig;
- i: Integer;
- s: String;
begin
- Randomize();
+ cfglen := 0;
- EditorDir := ExtractFilePath(Application.ExeName);
+ wad := TWADEditor_1.Create;
+ if wad.ReadFile(EditorDir+'data\Game.wad') then
+ wad.GetResource('FONTS', cfgres, cfgdata, cfglen);
+ wad.Free();
- e_InitLog(EditorDir+'Editor.log', WM_NEWFILE);
+ if cfglen <> 0 then
+ begin
+ if not g_CreateTextureWAD('FONT_STD', EditorDir+'data\Game.wad:FONTS\'+texture) then
+ e_WriteLog('ERROR ERROR ERROR', MSG_WARNING);
- e_WriteLog('Init OpenGL', MSG_NOTIFY);
+ config := TConfig.CreateMem(cfgdata, cfglen);
+ cwdt := Min(Max(config.ReadInt('FontMap', 'CharWidth', 0), 0), 255);
+ chgt := Min(Max(config.ReadInt('FontMap', 'CharHeight', 0), 0), 255);
+ spc := Min(Max(config.ReadInt('FontMap', 'Kerning', 0), -128), 127);
- InitOpenGL();
- hDC := GetDC(RenderPanel.Handle);
+ if g_GetTexture('FONT_STD', ID) then
+ e_TextureFontBuild(ID, FontID, cwdt, chgt, spc-2);
- FillChar(pfd, SizeOf(pfd), 0);
- with pfd do
- begin
- nSize := SizeOf(pfd);
- nVersion := 1;
- dwFlags := PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
- dwLayerMask := PFD_MAIN_PLANE;
- iPixelType := PFD_TYPE_RGBA;
- cColorBits := 24;
- cDepthBits := 32;
- iLayerType := PFD_MAIN_PLANE;
- end;
- PixelFormat := ChoosePixelFormat (hDC, @pfd);
- SetPixelFormat(hDC, PixelFormat, @pfd);
+ config.Free();
+ end
+ else
+ e_WriteLog('Could not load FONT_STD', MSG_WARNING);
- hRC := wglCreateContext(hDC);
- ActivateRenderingContext(hDC, hRC);
+ if cfglen <> 0 then FreeMem(cfgdata);
+end;
- e_InitGL(False);
+procedure TMainForm.FormCreate(Sender: TObject);
+var
+ config: TConfig;
+ i: Integer;
+ s: String;
+begin
+ Randomize();
- gEditorFont := e_SimpleFontCreate('Arial Cyr', 12, FW_BOLD, hDC);
+ EditorDir := ExtractFilePath(Application.ExeName);
- slInvalidTextures := TStringList.Create;
+ e_InitLog(EditorDir+'Editor.log', WM_NEWFILE);
- e_WriteLog('Loading data', MSG_NOTIFY);
- LoadData();
+ slInvalidTextures := TStringList.Create;
ShowLayer(LAYER_BACK, True);
ShowLayer(LAYER_WALLS, True);
Application.OnIdle := OnIdle;
end;
+procedure PrintBlack(X, Y: Integer; Text: string; FontID: DWORD);
+begin
+ // NOTE: all the font printing routines assume CP1251
+ e_TextureFontPrintEx(X, Y, Text, FontID, 0, 0, 0, 1.0);
+end;
+
procedure TMainForm.Draw();
var
- ps: TPaintStruct;
x, y: Integer;
a, b: Integer;
- ID: DWORD;
+ ID, PID: DWORD;
Width, Height: Word;
Rect: TRectWH;
ObjCount: Word;
aX, aY, aX2, aY2, XX, ScaleSz: Integer;
begin
- BeginPaint(Handle, ps);
e_BeginRender();
e_Clear(GL_COLOR_BUFFER_BIT,
if not g_GetTexture(SelectedTexture(), ID) then
g_GetTexture('NOTEXTURE', ID);
g_GetTextureSizeByID(ID, Width, Height);
- e_DrawFillQuad(RenderPanel.Width-Width-2, RenderPanel.Height-Height-2,
- RenderPanel.Width-1, RenderPanel.Height-1,
- GetRValue(PreviewColor), GetGValue(PreviewColor), GetBValue(PreviewColor), 0);
- e_Draw(ID, RenderPanel.Width-Width-1, RenderPanel.Height-Height-1, 0, True, False);
+ if g_GetTexture('PREVIEW', PID) then
+ e_DrawFill(PID, RenderPanel.Width-Width, RenderPanel.Height-Height, Width div 16 + 1, Height div 16 + 1, 0, True, False);
+ e_Draw(ID, RenderPanel.Width-Width, RenderPanel.Height-Height, 0, True, False);
end;
// Подсказка при выборе точки Телепорта:
e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 192, 192, 192, 127);
e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 255, 255, 255);
- e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_TELEPORT]), gEditorFont, 0, 0, 0);
+ PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_TELEPORT], gEditorFont);
end;
// Подсказка при выборе точки появления:
0, 0, 255);
e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 192, 192, 192, 127);
e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 255, 255, 255);
- e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_SPAWN]), gEditorFont, 0, 0, 0);
+ PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_SPAWN], gEditorFont);
end;
// Подсказка при выборе панели двери:
begin
e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 192, 192, 192, 127);
e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 255, 255, 255);
- e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_PANEL_DOOR]), gEditorFont, 0, 0, 0);
+ PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_PANEL_DOOR], gEditorFont);
end;
// Подсказка при выборе панели с текстурой:
begin
e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+196, MousePos.Y+18, 192, 192, 192, 127);
e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+196, MousePos.Y+18, 255, 255, 255);
- e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_PANEL_TEXTURE]), gEditorFont, 0, 0, 0);
+ PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_PANEL_TEXTURE], gEditorFont);
end;
// Подсказка при выборе панели индикации выстрела:
begin
e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+316, MousePos.Y+18, 192, 192, 192, 127);
e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+316, MousePos.Y+18, 255, 255, 255);
- e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_PANEL_SHOT]), gEditorFont, 0, 0, 0);
+ PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_PANEL_SHOT], gEditorFont);
end;
// Подсказка при выборе панели лифта:
begin
e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 192, 192, 192, 127);
e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+180, MousePos.Y+18, 255, 255, 255);
- e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_PANEL_LIFT]), gEditorFont, 0, 0, 0);
+ PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_PANEL_LIFT], gEditorFont);
end;
// Подсказка при выборе монстра:
begin
e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+120, MousePos.Y+18, 192, 192, 192, 127);
e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+120, MousePos.Y+18, 255, 255, 255);
- e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_MONSTER]), gEditorFont, 0, 0, 0);
+ PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_MONSTER], gEditorFont);
end;
// Подсказка при выборе области воздействия:
begin
e_DrawFillQuad(MousePos.X, MousePos.Y, MousePos.X+204, MousePos.Y+18, 192, 192, 192, 127);
e_DrawQuad(MousePos.X, MousePos.Y, MousePos.X+204, MousePos.Y+18, 255, 255, 255);
- e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(_lc[I_HINT_EXT_AREA]), gEditorFont, 0, 0, 0);
+ PrintBlack(MousePos.X+2, MousePos.Y+2, _glc[I_HINT_EXT_AREA], gEditorFont);
end;
// Рисуем текстуры, если чертим панель:
if MouseAction in [MOUSEACTION_DRAWPANEL, MOUSEACTION_DRAWTRIGGER] then
begin // Чертим новый
- e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(Format(_lc[I_HINT_WIDTH],
- [Abs(MousePos.X-MouseLDownPos.X)])), gEditorFont, 0, 0, 0);
- e_SimpleFontPrint(MousePos.X+8, MousePos.Y+28, PChar(Format(_lc[I_HINT_HEIGHT],
- [Abs(MousePos.Y-MouseLDownPos.Y)])), gEditorFont, 0, 0, 0);
+ PrintBlack(MousePos.X+2, MousePos.Y+2, Format(_glc[I_HINT_WIDTH],
+ [Abs(MousePos.X-MouseLDownPos.X)]), gEditorFont);
+ PrintBlack(MousePos.X+2, MousePos.Y+14, Format(_glc[I_HINT_HEIGHT],
+ [Abs(MousePos.Y-MouseLDownPos.Y)]), gEditorFont);
end
else // Растягиваем существующий
if SelectedObjects[GetFirstSelected].ObjectType in [OBJECT_PANEL, OBJECT_TRIGGER] then
Height := gTriggers[SelectedObjects[GetFirstSelected].ID].Height;
end;
- e_SimpleFontPrint(MousePos.X+8, MousePos.Y+14, PChar(Format(_lc[I_HINT_WIDTH], [Width])),
- gEditorFont, 0, 0, 0);
- e_SimpleFontPrint(MousePos.X+8, MousePos.Y+28, PChar(Format(_lc[I_HINT_HEIGHT], [Height])),
- gEditorFont, 0, 0, 0);
+ PrintBlack(MousePos.X+2, MousePos.Y+2, Format(_glc[I_HINT_WIDTH], [Width]),
+ gEditorFont);
+ PrintBlack(MousePos.X+2, MousePos.Y+14, Format(_glc[I_HINT_HEIGHT], [Height]),
+ gEditorFont);
end;
end;
end; // Мини-карта
e_EndRender();
- SwapBuffers(hDC);
- EndPaint(Handle, ps);
+ RenderPanel.SwapBuffers();
end;
procedure TMainForm.FormResize(Sender: TObject);
trigger.Key := Trigger.Key or KEY_BLUETEAM;
// Параметры триггера:
- ZeroMemory(@trigger.Data.Default[0], 128);
+ FillByte(trigger.Data.Default[0], 128, 0);
case trigger.TriggerType of
// Переключаемая панель:
end;
end;
+procedure TMainForm.RenderPanelPaint(Sender: TObject);
+begin
+ Draw();
+end;
+
procedure TMainForm.RenderPanelMouseMove(Sender: TObject;
Shift: TShiftState; X, Y: Integer);
var
begin
if DrawRect = nil then
New(DrawRect);
- DrawRect.TopLeft := MouseRDownPos;
- DrawRect.BottomRight := MousePos;
+ DrawRect.Top := MouseRDownPos.y;
+ DrawRect.Left := MouseRDownPos.x;
+ DrawRect.Bottom := MousePos.y;
+ DrawRect.Right := MousePos.x;
end
else
// Двигаем выделенные объекты:
begin
if DrawRect = nil then
New(DrawRect);
- DrawRect.TopLeft := MouseLDownPos;
- DrawRect.BottomRight := MousePos;
+ DrawRect.Top := MouseLDownPos.y;
+ DrawRect.Left := MouseLDownPos.x;
+ DrawRect.Bottom := MousePos.y;
+ DrawRect.Right := MousePos.x;
end
else // Двигаем карту:
if MouseAction = MOUSEACTION_MOVEMAP then
CanClose := MessageBox(0, PChar(_lc[I_MSG_EXIT_PROMT]),
PChar(_lc[I_MSG_EXIT]),
MB_ICONQUESTION or MB_YESNO or
- MB_TASKMODAL or MB_DEFBUTTON1) = idYes;
+ MB_DEFBUTTON1) = idYes;
end;
procedure TMainForm.aExitExecute(Sender: TObject);
config.Free();
slInvalidTextures.Free;
-
- wglDeleteContext(hRC);
end;
procedure TMainForm.RenderPanelResize(Sender: TObject);
TRIGGER_EXIT:
begin
s := vleObjectProperty.Values[_lc[I_PROP_TR_NEXT_MAP]];
- ZeroMemory(@Data.MapName[0], 16);
+ FillByte(Data.MapName[0], 16, 0);
if s <> '' then
- CopyMemory(@Data.MapName[0], @s[1], Min(Length(s), 16));
+ Move(Data.MapName[0], s[1], Min(Length(s), 16));
end;
TRIGGER_TEXTURE:
TRIGGER_SOUND:
begin
s := vleObjectProperty.Values[_lc[I_PROP_TR_SOUND_NAME]];
- ZeroMemory(@Data.SoundName[0], 64);
+ FillByte(Data.SoundName[0], 64, 0);
if s <> '' then
- CopyMemory(@Data.SoundName[0], @s[1], Min(Length(s), 64));
+ Move(Data.SoundName[0], s[1], Min(Length(s), 64));
Data.Volume := Min(StrToIntDef(vleObjectProperty.Values[_lc[I_PROP_TR_SOUND_VOLUME]], 0), 255);
Data.Pan := Min(StrToIntDef(vleObjectProperty.Values[_lc[I_PROP_TR_SOUND_PAN]], 0), 255);
TRIGGER_MUSIC:
begin
s := vleObjectProperty.Values[_lc[I_PROP_TR_MUSIC_NAME]];
- ZeroMemory(@Data.MusicName[0], 64);
+ FillByte(Data.MusicName[0], 64, 0);
if s <> '' then
- CopyMemory(@Data.MusicName[0], @s[1], Min(Length(s), 64));
+ Move(Data.MusicName[0], s[1], Min(Length(s), 64));
if vleObjectProperty.Values[_lc[I_PROP_TR_MUSIC_ACT]] = _lc[I_PROP_TR_MUSIC_ON] then
Data.MusicAction := 1
Data.MessageSendTo := 5;
s := vleObjectProperty.Values[_lc[I_PROP_TR_MESSAGE_TEXT]];
- ZeroMemory(@Data.MessageText[0], 100);
+ FillByte(Data.MessageText[0], 100, 0);
if s <> '' then
- CopyMemory(@Data.MessageText[0], @s[1], Min(Length(s), 100));
+ Move(Data.MessageText[0], s[1], Min(Length(s), 100));
Data.MessageTime := Min(Max(
StrToIntDef(vleObjectProperty.Values[_lc[I_PROP_TR_MESSAGE_TIME]], 0), 0), 65535);
[SelectedTexture()])),
PChar(_lc[I_MSG_DEL_TEXTURE]),
MB_ICONQUESTION or MB_YESNO or
- MB_TASKMODAL or MB_DEFBUTTON1) <> idYes then
+ MB_DEFBUTTON1) <> idYes then
Exit;
if gPanels <> nil then
if (MessageBox(0, PChar(_lc[I_MSG_CLEAR_MAP_PROMT]),
PChar(_lc[I_MSG_CLEAR_MAP]),
MB_ICONQUESTION or MB_YESNO or
- MB_TASKMODAL or MB_DEFBUTTON1) = mrYes) then
+ MB_DEFBUTTON1) = mrYes) then
FullClear();
end;
begin
str := SelectMapForm.lbMapList.Items[SelectMapForm.lbMapList.ItemIndex];
MapName := '';
- CopyMemory(@MapName[0], @str[1], Min(16, Length(str)));
+ Move(MapName[0], str[1], Min(16, Length(str)));
if MessageBox(0, PChar(Format(_lc[I_MSG_DELETE_MAP_PROMT],
[MapName, OpenDialog.FileName])),
PChar(_lc[I_MSG_DELETE_MAP]),
MB_ICONQUESTION or MB_YESNO or
- MB_TASKMODAL or MB_DEFBUTTON2) <> mrYes then
+ MB_DEFBUTTON2) <> mrYes then
Exit;
WAD.RemoveResource('', MapName);
[MapName])),
PChar(_lc[I_MSG_MAP_DELETED]),
MB_ICONINFORMATION or MB_OK or
- MB_TASKMODAL or MB_DEFBUTTON1);
+ MB_DEFBUTTON1);
WAD.SaveTo(OpenDialog.FileName);
procedure TMainForm.OnIdle(Sender: TObject; var Done: Boolean);
begin
+ // FIXME: this is a shitty hack
+ if not gDataLoaded then
+ begin
+ e_WriteLog('Init OpenGL', MSG_NOTIFY);
+ e_InitGL();
+ e_WriteLog('Loading data', MSG_NOTIFY);
+ LoadStdFont('STDTXT', 'STDFONT', gEditorFont);
+ LoadData();
+ gDataLoaded := True;
+ MainForm.FormResize(nil);
+ end;
Draw();
end;
Application.Minimize();
if ExecuteProcess(TestD2dExe, cmd) < 0 then
begin
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM,
- nil, GetLastError(), LANG_SYSTEM_DEFAULT,
- @lpMsgBuf, 0, nil);
- MessageBox(0, lpMsgBuf,
+ MessageBox(0, 'FIXME',
PChar(_lc[I_MSG_EXEC_ERROR]),
MB_OK or MB_ICONERROR);
end;