1051 lines
27 KiB
C
1051 lines
27 KiB
C
//=======================================================================
|
|
// Copyright XashXT Group 2007 ©
|
|
// editor.c - game editor dll
|
|
//=======================================================================
|
|
|
|
#include "editor.h"
|
|
|
|
#define IDI_ICON1 101
|
|
|
|
#define MAIN_WND_WIDTH 640
|
|
#define MAIN_WND_HEIGHT 480
|
|
#define OPTS_WND_WIDTH 420
|
|
#define OPTS_WND_HEIGHT 380
|
|
#define C_PAGES 3
|
|
|
|
#define EDITOR_CONSOLE "Xash Editor Console"
|
|
#define EDITOR_SETTINGS "Xash Editor Settings"
|
|
|
|
|
|
static MSG msg;
|
|
static window_t g_MainWindow;
|
|
static window_t g_IdleWindow;
|
|
HINSTANCE platform_dll;
|
|
|
|
typedef struct tag_dlghdr
|
|
{
|
|
HWND hwndTab; // tab control
|
|
HWND hwndDisplay; // current child dialog box
|
|
RECT rcDisplay; // display rectangle for the tab control
|
|
DLGTEMPLATE *apRes[C_PAGES];
|
|
}DLGHDR;
|
|
|
|
GUI_Form s_gui;
|
|
wnd_options_t w_opts; //window options
|
|
platform_exp_t *pi;//platform utils
|
|
static bool editor_init = false;
|
|
static char textbuffer[MAX_INPUTLINE];
|
|
|
|
/*
|
|
=============================================================================
|
|
|
|
GUI Set Font
|
|
|
|
=============================================================================
|
|
*/
|
|
|
|
void GUI_AddToolTip( HWND hwnd, const char *text )
|
|
{
|
|
TOOLINFO ti;
|
|
|
|
memset (&ti, 0, sizeof (TOOLINFO));
|
|
ti.cbSize = sizeof (TOOLINFO);
|
|
ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
|
|
ti.uId = (UINT)hwnd;
|
|
ti.lpszText = (LPTSTR) text;
|
|
SendMessage (s_gui.hTips, TTM_ADDTOOL, 0, (LPARAM) &ti);
|
|
}
|
|
|
|
static void GUI_AddButton( HWND parent, const char *name, int x, int y, int id )
|
|
{
|
|
HWND btn;
|
|
btn = CreateWindow( "button", name, WS_CHILD | WS_VISIBLE, x, y, 78, 26,
|
|
parent, (HMENU)id, s_gui.gHinst, NULL);
|
|
GUI_ApplyFont( btn );
|
|
GUI_AddToolTip( btn, "test" );
|
|
}
|
|
|
|
void GUI_DisplayTooltips( HWND hwnd, DWORD dParam )
|
|
{
|
|
switch( dParam )
|
|
{
|
|
case IDB_CHOOSEFONT:
|
|
Msg("display help\n");
|
|
//MessageBox(hwnd, "Choose default font for editor", "Help", MB_OK|MB_ICONINFORMATION);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
// DoLockDlgRes - loads and locks a dialog box template resource.
|
|
// Returns the address of the locked resource.
|
|
// lpszResName - name of the resource
|
|
|
|
DLGTEMPLATE *WINAPI DoLockDlgRes(LPCSTR lpszResName)
|
|
{
|
|
HGLOBAL hglb;
|
|
HRSRC hrsrc = FindResource(GetModuleHandle("editor"), lpszResName, RT_DIALOG);
|
|
|
|
if(!hrsrc) Sys_Error("not found res\n");
|
|
|
|
hglb = LoadResource(GetModuleHandle("editor"), hrsrc);
|
|
return (DLGTEMPLATE *)LockResource(hglb);
|
|
}
|
|
|
|
// OnChildDialogInit - Positions the child dialog box to fall
|
|
// within the display area of the tab control.
|
|
|
|
void WINAPI OnChildDialogInit(HWND hwndDlg)
|
|
{
|
|
HWND hwndParent = GetParent(hwndDlg);
|
|
DLGHDR *pHdr = (DLGHDR *) GetWindowLong( hwndParent, GWL_USERDATA);
|
|
SetWindowPos(hwndDlg, HWND_TOP, pHdr->rcDisplay.left, pHdr->rcDisplay.top, 0, 0, SWP_NOSIZE);
|
|
ShowWindow(hwndDlg, SW_SHOWNORMAL);
|
|
GUI_AddToolTip(GetDlgItem(hwndDlg, IDB_CHOOSEFONT), "Choose font" );
|
|
}
|
|
|
|
void GUI_UpdateOptions( WPARAM wParam );
|
|
|
|
static LRESULT CALLBACK ChildDialogProc(HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HELPINFO *hi;
|
|
|
|
switch( uMessage )
|
|
{
|
|
case WM_INITDIALOG:
|
|
OnChildDialogInit( hwnd );
|
|
break;
|
|
//return true;
|
|
case WM_COMMAND:
|
|
GUI_UpdateOptions(wParam);
|
|
break;
|
|
case WM_HELP:
|
|
hi = (HELPINFO *)lParam;
|
|
GUI_DisplayTooltips( hwnd, hi->iCtrlId );
|
|
break;
|
|
}
|
|
return DefWindowProc (hwnd, uMessage, wParam, lParam);
|
|
}
|
|
|
|
|
|
// OnSelChanged - processes the TCN_SELCHANGE notification.
|
|
// hwndDlg - handle to the parent dialog box.
|
|
void WINAPI OnSelChanged(HWND hwndDlg)
|
|
{
|
|
DLGHDR *pHdr = (DLGHDR *) GetWindowLong( hwndDlg, GWL_USERDATA);
|
|
int iSel = TabCtrl_GetCurSel(pHdr->hwndTab);
|
|
|
|
// Destroy the current child dialog box, if any.
|
|
if (pHdr->hwndDisplay != NULL) DestroyWindow(pHdr->hwndDisplay);
|
|
|
|
// Create the new child dialog box.
|
|
pHdr->hwndDisplay = CreateDialogIndirect(s_gui.gHinst, pHdr->apRes[iSel], hwndDlg, ChildDialogProc);
|
|
}
|
|
|
|
void WINAPI OnTabbedDialogInit( HWND hwndDlg )
|
|
{
|
|
DLGHDR *pHdr = (DLGHDR *)LocalAlloc(LPTR, sizeof(DLGHDR));
|
|
DWORD dwDlgBase = GetDialogBaseUnits();
|
|
int cxMargin = LOWORD(dwDlgBase) / 4;
|
|
int cyMargin = HIWORD(dwDlgBase) / 8;
|
|
TCITEM tie;
|
|
RECT rcTab;
|
|
int i;
|
|
|
|
// Save a pointer to the DLGHDR structure.
|
|
SetWindowLong(hwndDlg, GWL_USERDATA, (LONG) pHdr);
|
|
|
|
// Create the tab control.
|
|
pHdr->hwndTab = CreateWindow( WC_TABCONTROL, "", WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
|
|
0, 0, OPTS_WND_WIDTH, OPTS_WND_HEIGHT, hwndDlg, NULL, s_gui.gHinst, NULL );
|
|
if (pHdr->hwndTab == NULL)
|
|
{
|
|
// handle error
|
|
GUI_Error("can't create hwnd dialog\n" );
|
|
return;
|
|
}
|
|
|
|
GUI_ApplyFont( pHdr->hwndTab );
|
|
|
|
// Add a tab for each of the three child dialog boxes.
|
|
tie.mask = TCIF_TEXT | TCIF_IMAGE;
|
|
tie.iImage = -1;
|
|
tie.pszText = "General";
|
|
TabCtrl_InsertItem(pHdr->hwndTab, 0, &tie);
|
|
tie.pszText = "Compilers";
|
|
TabCtrl_InsertItem(pHdr->hwndTab, 1, &tie);
|
|
tie.pszText = "QuakeC";
|
|
TabCtrl_InsertItem(pHdr->hwndTab, 2, &tie);
|
|
|
|
// Lock the resources for the three child dialog boxes.
|
|
pHdr->apRes[0] = DoLockDlgRes(MAKEINTRESOURCE(DLG_FIRST));
|
|
pHdr->apRes[1] = DoLockDlgRes(MAKEINTRESOURCE(DLG_SECOND));
|
|
pHdr->apRes[2] = DoLockDlgRes(MAKEINTRESOURCE(DLG_THIRD));
|
|
|
|
// Determine the bounding rectangle for all child dialog boxes.
|
|
SetRectEmpty(&rcTab);
|
|
|
|
for (i = 0; i < C_PAGES; i++)
|
|
{
|
|
if (pHdr->apRes[i]->cx > rcTab.right)
|
|
rcTab.right = pHdr->apRes[i]->cx;
|
|
if (pHdr->apRes[i]->cy > rcTab.bottom)
|
|
rcTab.bottom = pHdr->apRes[i]->cy;
|
|
}
|
|
|
|
rcTab.right = rcTab.right * LOWORD(dwDlgBase) / 4;
|
|
rcTab.bottom = rcTab.bottom * HIWORD(dwDlgBase) / 8;
|
|
|
|
// Calculate how large to make the tab control, so
|
|
// the display area can accommodate all the child dialog boxes.
|
|
TabCtrl_AdjustRect(pHdr->hwndTab, TRUE, &rcTab);
|
|
OffsetRect(&rcTab, cxMargin - rcTab.left, cyMargin - rcTab.top);
|
|
|
|
// Calculate the display rectangle.
|
|
CopyRect(&pHdr->rcDisplay, &rcTab);
|
|
TabCtrl_AdjustRect(pHdr->hwndTab, FALSE, &pHdr->rcDisplay);
|
|
|
|
// Set the size and position of the tab control, buttons,
|
|
// and dialog box.
|
|
SetWindowPos(pHdr->hwndTab, NULL, rcTab.left, rcTab.top, OPTS_WND_WIDTH + 10, OPTS_WND_HEIGHT, SWP_NOZORDER);
|
|
|
|
// Size the dialog box.
|
|
SetWindowPos(hwndDlg, NULL, 0, 0, OPTS_WND_WIDTH + 10, OPTS_WND_HEIGHT, SWP_NOMOVE | SWP_NOZORDER);
|
|
|
|
s_gui.hTips = CreateWindowEx (0, TOOLTIPS_CLASS, "", WS_POPUP | WS_EX_TOPMOST, 0, 0, 0, 0, pHdr->hwndTab, NULL, s_gui.gHinst, NULL);
|
|
|
|
|
|
// Simulate selection of the first item.
|
|
OnSelChanged( hwndDlg );
|
|
}
|
|
|
|
/*
|
|
=============================================================================
|
|
|
|
GUI Table Options
|
|
|
|
=============================================================================
|
|
*/
|
|
void GUI_ResizeTab(HWND hwnd)
|
|
{
|
|
TC_ITEM ti;
|
|
|
|
int index = TabCtrl_GetCurSel (hwnd);
|
|
|
|
if( index >= 0 )
|
|
{
|
|
ti.mask = TCIF_PARAM;
|
|
TabCtrl_GetItem (hwnd, index, &ti);
|
|
if (s_gui.hOptions)
|
|
{
|
|
RECT rc, rc2;
|
|
HDWP hdwp;
|
|
|
|
GetWindowRect (hwnd, &rc);
|
|
ScreenToClient (s_gui.hTabs, (LPPOINT) &rc.left);
|
|
ScreenToClient (s_gui.hTabs, (LPPOINT) &rc.right);
|
|
|
|
TabCtrl_GetItemRect (hwnd, index, &rc2);
|
|
rc.top += (rc2.bottom - rc2.top) - 6;
|
|
|
|
hdwp = BeginDeferWindowPos (2);
|
|
DeferWindowPos (hdwp, s_gui.hTabs, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
|
|
DeferWindowPos (hdwp, s_gui.hTabs, HWND_TOP, rc.left + 3, rc.top - 8, rc.right - rc.left, rc.bottom - rc.top, SWP_SHOWWINDOW);
|
|
EndDeferWindowPos (hdwp);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void GUI_AddTab( const char *name )
|
|
{
|
|
TC_ITEM ti;
|
|
|
|
ti.mask = TCIF_TEXT | TCIF_PARAM;
|
|
ti.pszText = (LPSTR)name;
|
|
|
|
TabCtrl_InsertItem (s_gui.hTabs, TabCtrl_GetItemCount(s_gui.hTabs), &ti);
|
|
GUI_ResizeTab(s_gui.hTabs);
|
|
}
|
|
|
|
bool GUI_CloseOptions( void )
|
|
{
|
|
ShowWindow( s_gui.hOptions, SW_HIDE );
|
|
|
|
//return to main window
|
|
EnableWindow( s_gui.hWnd, true );
|
|
SetFocus( s_gui.hWnd );
|
|
|
|
return false;
|
|
}
|
|
|
|
bool GUI_ApplyOptions( void )
|
|
{
|
|
//TODO:
|
|
//1. copy parameters from temporary struct to global
|
|
//2. apply some changes immediately if needed
|
|
//3. save settings into "bin/editor.dat"
|
|
|
|
|
|
return GUI_CloseOptions();
|
|
}
|
|
|
|
void GUI_UpdateOptions( WPARAM wParam )
|
|
{
|
|
CHOOSEFONT cf;
|
|
static LOGFONT lf; // logical font structure
|
|
static DWORD rgbCurrent; // current text color
|
|
|
|
ZeroMemory(&cf, sizeof(cf));
|
|
cf.lStructSize = sizeof (cf);
|
|
cf.hwndOwner = s_gui.hWnd;
|
|
cf.lpLogFont = &lf;
|
|
cf.rgbColors = rgbCurrent;
|
|
cf.Flags = CF_SCREENFONTS | CF_EFFECTS;
|
|
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDOK:
|
|
GUI_ApplyOptions();
|
|
break;
|
|
case IDCANCEL:
|
|
GUI_CloseOptions();
|
|
break;
|
|
case IDB_CHOOSEFONT:
|
|
if(ChooseFont(&cf))
|
|
{
|
|
Msg("apply font %s\n", cf.lpLogFont->lfFaceName);
|
|
strcpy(w_opts.fontname, cf.lpLogFont->lfFaceName);
|
|
//Msg("apply font %d\n", cf.lpLogFont->lfHeight -MulDiv(cf.iPointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72));
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
static LRESULT CALLBACK OptWndProc (HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HDC hdc;
|
|
PAINTSTRUCT ps;
|
|
|
|
switch( uMessage )
|
|
{
|
|
case WM_CREATE:
|
|
OnTabbedDialogInit( hwnd );
|
|
break;
|
|
case WM_PAINT:
|
|
hdc = BeginPaint(hwnd, (LPPAINTSTRUCT)&ps);
|
|
EndPaint(hwnd,(LPPAINTSTRUCT)&ps);
|
|
return TRUE;
|
|
break;
|
|
case WM_COMMAND:
|
|
GUI_UpdateOptions(wParam);
|
|
break;
|
|
case WM_NOTIFY:
|
|
switch (((LPNMHDR)lParam)->code)
|
|
{
|
|
case TCN_SELCHANGE:
|
|
OnSelChanged( hwnd );
|
|
break;
|
|
}
|
|
break;
|
|
return true;
|
|
case WM_SIZE:
|
|
break;
|
|
case WM_CLOSE:
|
|
return GUI_CloseOptions();
|
|
break;
|
|
}
|
|
return DefWindowProc (hwnd, uMessage, wParam, lParam);
|
|
}
|
|
|
|
void GUI_CreateOptionsWindow( void )
|
|
{
|
|
WNDCLASS wc;
|
|
RECT rect;
|
|
|
|
int w_pos, h_pos;
|
|
//int WNDSTYLE = WS_POPUP | WS_BORDER | WS_CAPTION | WS_MINIMIZEBOX;
|
|
int WNDSTYLE = WS_POPUP | WS_BORDER | WS_SYSMENU | WS_CAPTION;
|
|
int TABSTYLE = WS_CHILD | WS_VISIBLE | WS_TABSTOP | TCS_TOOLTIPS;
|
|
int bpos_x, bpos_y;
|
|
|
|
memset( &wc, 0, sizeof( wc ));
|
|
|
|
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
|
|
wc.lpfnWndProc = OptWndProc;
|
|
wc.cbClsExtra = 0;
|
|
wc.cbWndExtra = 0;
|
|
wc.hInstance = s_gui.gHinst;
|
|
wc.hIcon = LoadIcon(NULL, NULL);
|
|
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
|
|
wc.hbrBackground = (HBRUSH) COLOR_3DSHADOW;
|
|
wc.lpszMenuName = NULL;
|
|
wc.lpszClassName = EDITOR_SETTINGS;
|
|
|
|
if (!RegisterClass (&wc)) GUI_Error("Can't create options window\n");
|
|
|
|
//move window into center of screen
|
|
rect.left = 0;
|
|
rect.right = OPTS_WND_WIDTH;
|
|
rect.top = 0;
|
|
rect.bottom = OPTS_WND_HEIGHT;
|
|
|
|
AdjustWindowRect( &rect, WNDSTYLE, FALSE );
|
|
|
|
w_pos = ( s_gui.scr_width - OPTS_WND_WIDTH ) / 2;
|
|
h_pos = ( s_gui.scr_height - OPTS_WND_HEIGHT ) / 2;
|
|
|
|
s_gui.hOptions = CreateWindowEx( WS_EX_CLIENTEDGE | WS_EX_CONTEXTHELP, EDITOR_SETTINGS, "Settings", WNDSTYLE,
|
|
w_pos, h_pos, rect.right - rect.left, rect.bottom - rect.top, s_gui.hWnd, NULL, s_gui.gHinst, NULL);
|
|
|
|
GetClientRect(s_gui.hOptions, &rect);
|
|
|
|
bpos_x = rect.right - rect.left - 78 - 5;
|
|
bpos_y = rect.bottom - rect.top - 26 - 5;
|
|
|
|
GUI_AddButton( s_gui.hOptions, "&Cancel", bpos_x, bpos_y, IDCANCEL );
|
|
bpos_x -= 78 + 5;//move next button
|
|
GUI_AddButton( s_gui.hOptions, "&OK", bpos_x, bpos_y, IDOK );
|
|
}
|
|
|
|
/*
|
|
=============================================================================
|
|
|
|
GUI Acellerators
|
|
|
|
=============================================================================
|
|
*/
|
|
|
|
|
|
void GUI_ResetWndOptions( void )
|
|
{
|
|
//get info about debug mode
|
|
if(CheckParm ("-debug")) debug_mode = true;
|
|
s_gui.gHinst = (HINSTANCE) GetModuleHandle( NULL );
|
|
|
|
//reset options
|
|
w_opts.id = IDEDITORHEADER;
|
|
w_opts.version = (int)EDITOR_VERSION;
|
|
w_opts.csize = sizeof(wnd_options_t);
|
|
w_opts.show_console = true;
|
|
w_opts.con_scale = 6L;
|
|
w_opts.exp_scale = 5L;
|
|
|
|
w_opts.font_size = 7;
|
|
strcpy(w_opts.fontname, "Courier");
|
|
w_opts.font_type = CFM_BOLD | CFM_FACE | CFM_COLOR;
|
|
w_opts.font_color = RGB(0,0,0);
|
|
}
|
|
|
|
bool GUI_LoadPlatfrom( char *funcname, int argc, char **argv )
|
|
{
|
|
stdinout_api_t pistd;//platform callback
|
|
platform_t CreatePlat;
|
|
|
|
//create callbacks for platform.dll
|
|
pistd.printf = GUI_Msg;
|
|
pistd.dprintf = GUI_MsgDev;
|
|
pistd.wprintf = GUI_MsgWarn;
|
|
pistd.error = GUI_Error;
|
|
pistd.exit = std.exit;
|
|
pistd.print = GUI_Print;
|
|
|
|
//loading platform.dll
|
|
if (( platform_dll = LoadLibrary( "bin/platform.dll" )) == 0 )
|
|
{
|
|
GUI_Error("couldn't find platform.dll\n");
|
|
return false;
|
|
}
|
|
if ((CreatePlat = (void *)GetProcAddress( platform_dll, "CreateAPI" ) ) == 0 )
|
|
{
|
|
GUI_Error("platform.dll has no valid entry point\n");
|
|
return false;
|
|
}
|
|
pi = CreatePlat( pistd );//make links
|
|
|
|
//initialziing platform.dll
|
|
pi->Init( argc, argv );
|
|
|
|
pi->Fs.ClearSearchPath();
|
|
pi->AddGameHierarchy( "bin" );
|
|
|
|
return true;
|
|
}
|
|
|
|
HWND GUI_CreateConsole( bool readonly )
|
|
{
|
|
HWND newwnd;
|
|
DWORD dwStyle = WS_CHILD | WS_HSCROLL |
|
|
WS_VSCROLL | ES_LEFT | ES_WANTRETURN | ES_MULTILINE | ES_AUTOVSCROLL;
|
|
|
|
if (readonly) dwStyle |= ES_READONLY;
|
|
if (!s_gui.richedit) s_gui.richedit = LoadLibrary("riched32.dll");
|
|
|
|
newwnd = CreateWindowEx(WS_EX_CLIENTEDGE, s_gui.richedit ? RICHEDIT_CLASS:"EDIT", "",
|
|
dwStyle, 0, 0, 0, 0, s_gui.hWnd, NULL, s_gui.gHinst, NULL);
|
|
|
|
if (!newwnd)
|
|
{
|
|
//fall back to the earlier version
|
|
newwnd = CreateWindowEx(WS_EX_CLIENTEDGE, s_gui.richedit ? RICHEDIT_CLASS10A : "EDIT", "",
|
|
dwStyle, 0, 0, 0, 0, s_gui.hWnd, NULL, s_gui.gHinst, NULL);
|
|
|
|
}
|
|
if (!newwnd)
|
|
{
|
|
//we don't have RICHEDIT installed properly
|
|
FreeLibrary(s_gui.richedit);
|
|
s_gui.richedit = NULL;
|
|
|
|
newwnd = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", dwStyle, 0, 0, 0, 0,
|
|
s_gui.hWnd, NULL, s_gui.gHinst, NULL);
|
|
}
|
|
|
|
GUI_SetFont( newwnd );
|
|
if (s_gui.richedit) SendMessage(newwnd, EM_EXLIMITTEXT, 0, 1<<20);
|
|
|
|
return newwnd;
|
|
}
|
|
|
|
|
|
void GUI_CreateEditorWindow( void )
|
|
{
|
|
s_gui.hWnd = CreateWindowEx( WS_EX_CLIENTEDGE, CLASSNAME, "Xash Resource Editor", WS_OVERLAPPEDWINDOW,
|
|
s_gui.top, s_gui.bottom, s_gui.width, s_gui.height, NULL, NULL, s_gui.gHinst, NULL);
|
|
|
|
s_gui.hConsole = GUI_CreateConsole( true );
|
|
}
|
|
|
|
|
|
/*
|
|
=============================================================================
|
|
|
|
GUI Console System
|
|
|
|
=============================================================================
|
|
*/
|
|
void GUI_PrintIntoBuffer(const char *pMsg)
|
|
{
|
|
strcat(textbuffer, pMsg );
|
|
}
|
|
|
|
void GUI_ExecuteBuffer(void)
|
|
{
|
|
editor_init = true;
|
|
GUI_Print(textbuffer);
|
|
}
|
|
|
|
/*
|
|
====================
|
|
GUI_Print
|
|
|
|
stdout into editor internal console
|
|
====================
|
|
*/
|
|
void GUI_Print(const char *pMsg)
|
|
{
|
|
CHARFORMAT cf;
|
|
char buffer[MAX_INPUTLINE*2];
|
|
char *b = buffer;
|
|
const char *msg;
|
|
int bufLen;
|
|
int i = 0;
|
|
int color = RGB(0, 0, 0);
|
|
static unsigned long s_totalChars;
|
|
|
|
if(!editor_init)
|
|
{
|
|
GUI_PrintIntoBuffer( pMsg );
|
|
return;
|
|
}
|
|
|
|
// if the message is REALLY long, use just the last portion of it
|
|
if ( strlen( pMsg ) > MAX_INPUTLINE - 1 )
|
|
msg = pMsg + strlen( pMsg ) - MAX_INPUTLINE + 1;
|
|
else msg = pMsg;
|
|
|
|
// copy into an intermediate buffer
|
|
while ( msg[i] && ( ( b - buffer ) < sizeof( buffer ) - 1 ) )
|
|
{
|
|
if ( msg[i] == '\n' && msg[i+1] == '\r' )
|
|
{
|
|
b[0] = '\r';
|
|
b[1] = '\n';
|
|
b += 2;
|
|
i++;
|
|
}
|
|
else if ( msg[i] == '\r' )
|
|
{
|
|
b[0] = '\r';
|
|
b[1] = '\n';
|
|
b += 2;
|
|
}
|
|
else if ( msg[i] == '\n' )
|
|
{
|
|
b[0] = '\r';
|
|
b[1] = '\n';
|
|
b += 2;
|
|
}
|
|
else if ( IsColorString( &msg[i] ))
|
|
{
|
|
int code = 0;
|
|
i++;
|
|
code = atoi( &msg[i] );
|
|
if(code == 5) color = RGB(255, 0, 0);
|
|
}
|
|
else
|
|
{
|
|
*b= msg[i];
|
|
b++;
|
|
}
|
|
i++;
|
|
}
|
|
*b = 0;
|
|
bufLen = b - buffer;
|
|
s_totalChars += bufLen;
|
|
|
|
//Edit_SetSel(s_gui.hConsole, 0, s_totalChars);
|
|
memset(&cf, 0, sizeof(cf));
|
|
cf.cbSize = sizeof(cf);
|
|
cf.dwMask = CFM_COLOR;
|
|
cf.crTextColor = color;
|
|
|
|
// replace selection instead of appending if we're overflowing
|
|
if ( s_totalChars > 0x7fff )
|
|
{
|
|
SendMessage( s_gui.hConsole, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);
|
|
//SendMessage( s_gui.hConsole, EM_SETSEL, 0, -1 );
|
|
s_totalChars = bufLen;
|
|
//Edit_SetSel(s_gui.hConsole, bufLen, s_totalChars);
|
|
}
|
|
|
|
// put this text into the windows console
|
|
SendMessage( s_gui.hConsole, EM_LINESCROLL, 0, 0xffff );
|
|
SendMessage( s_gui.hConsole, EM_SCROLLCARET, 0, 0 );
|
|
SendMessage( s_gui.hConsole, EM_REPLACESEL, 0, (LPARAM) buffer );
|
|
}
|
|
|
|
/*
|
|
================
|
|
GUI_Msg
|
|
|
|
formatted message
|
|
================
|
|
*/
|
|
void GUI_Msg( const char *pMsg, ... )
|
|
{
|
|
va_list argptr;
|
|
char text[MAX_INPUTLINE];
|
|
|
|
va_start (argptr, pMsg);
|
|
vsprintf (text, pMsg, argptr);
|
|
va_end (argptr);
|
|
|
|
GUI_Print( text );
|
|
|
|
//echo into system console
|
|
std.print( text );
|
|
}
|
|
|
|
void GUI_MsgDev( const char *pMsg, ... )
|
|
{
|
|
va_list argptr;
|
|
char text[MAX_INPUTLINE];
|
|
|
|
if(debug_mode)
|
|
{
|
|
va_start (argptr, pMsg);
|
|
vsprintf (text, pMsg, argptr);
|
|
va_end (argptr);
|
|
GUI_Print( text );
|
|
|
|
//echo into system console
|
|
std.print( text );
|
|
}
|
|
}
|
|
|
|
void GUI_MsgWarn( const char *pMsg, ... )
|
|
{
|
|
va_list argptr;
|
|
char text[MAX_INPUTLINE];
|
|
|
|
if(debug_mode)
|
|
{
|
|
va_start (argptr, pMsg);
|
|
vsprintf (text, pMsg, argptr);
|
|
va_end (argptr);
|
|
GUI_Print( text );
|
|
|
|
//echo into system console
|
|
std.print( text );
|
|
}
|
|
}
|
|
|
|
void GUI_Error( const char *pMsg, ... )
|
|
{
|
|
va_list argptr;
|
|
char text[MAX_INPUTLINE];
|
|
|
|
va_start (argptr, pMsg);
|
|
vsprintf (text, pMsg, argptr);
|
|
va_end (argptr);
|
|
|
|
GUI_DisableMenus();
|
|
GUI_Print( text );
|
|
std.print( text );//echo into system console
|
|
|
|
//3. waiting for user input
|
|
|
|
//std.exit();
|
|
}
|
|
|
|
void GUI_CreateMenus( void )
|
|
{
|
|
int TREESTYLE = WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES;
|
|
|
|
//create root menu
|
|
s_gui.menu = CreateMenu();
|
|
|
|
//create volumes
|
|
s_gui.file = CreateMenu(); AppendMenu(s_gui.menu, MF_POPUP, (UINT)s_gui.file, "&File");
|
|
s_gui.edit = CreateMenu(); AppendMenu(s_gui.menu, MF_POPUP, (UINT)s_gui.edit, "&Edit");
|
|
s_gui.cmds = CreateMenu(); AppendMenu(s_gui.menu, MF_POPUP, (UINT)s_gui.cmds, "&Tools");
|
|
s_gui.help = CreateMenu(); AppendMenu(s_gui.menu, MF_POPUP, (UINT)s_gui.help, "&Help");
|
|
|
|
//build menu "file"
|
|
GUI_AddMenuItem(s_gui.file, "&New... Ctrl + N", IDM_CREATE, VK_N );
|
|
GUI_AddMenuItem(s_gui.file, "&Open... Ctrl + O", IDM_OPEN, VK_O );
|
|
GUI_AddMenuItem(s_gui.file, "&Close", IDM_CLOSE, 0 );
|
|
GUI_AddMenuItem(s_gui.file, "", 0, 0 );//separator
|
|
GUI_AddMenuItem(s_gui.file, "&Save... Ctrl + S", IDM_SAVE, VK_S );
|
|
GUI_AddMenuItem(s_gui.file, "Save &As...", IDM_SAVEAS, 0 );
|
|
GUI_AddMenuItem(s_gui.file, "", 0, 0 );//separator
|
|
GUI_AddMenuItem(s_gui.file, "E&xit", IDM_QUIT, 0 );
|
|
|
|
//build menu "edit"
|
|
GUI_AddMenuItem(s_gui.edit, "&Undo Ctrl + Z", IDM_UNDO, VK_Z );
|
|
GUI_AddMenuItem(s_gui.edit, "&Redo Ctrl + Y", IDM_REDO, VK_Y );
|
|
GUI_AddMenuItem(s_gui.edit, "", 0, 0 );//separator
|
|
GUI_AddMenuItem(s_gui.edit, "Cu&t Ctrl + X", IDM_CUT, VK_X );
|
|
GUI_AddMenuItem(s_gui.edit, "&Copy Ctrl + C", IDM_COPY, VK_C );
|
|
GUI_AddMenuItem(s_gui.edit, "&Paste Ctrl + V", IDM_PASTE, VK_V );
|
|
GUI_AddMenuItem(s_gui.edit, "&Delete Del", IDM_DELETE, VK_DELETE );
|
|
GUI_AddMenuItem(s_gui.edit, "", 0, 0 );//separator
|
|
GUI_AddMenuItem(s_gui.edit, "&Find Ctrl + F", IDM_FIND, VK_F );
|
|
GUI_AddMenuItem(s_gui.edit, "R&eplace Ctrl + H", IDM_REPLACE, VK_H );
|
|
GUI_AddMenuItem(s_gui.edit, "&Go to... Ctrl + G", IDM_GOTO, VK_G );
|
|
|
|
//build menu "tools"
|
|
GUI_AddMenuItem(s_gui.cmds, "&Compile... F7", IDM_COMPILE, VK_F7 );
|
|
GUI_AddMenuItem(s_gui.cmds, "D&ump Info... F3", IDM_GETINFO, VK_F3 );
|
|
GUI_AddMenuItem(s_gui.cmds, "", 0, 0 );//separator
|
|
GUI_AddMenuItem(s_gui.cmds, "&Settings... F10", IDM_SETTINGS, VK_F10 );
|
|
|
|
AppendMenu(s_gui.cmds, MF_CHECKED, IDM_SHOWCONSOLE, "Show console");
|
|
RegisterHotKey(s_gui.hWnd, IDH_HIDECONSOLE, 0, VK_ESCAPE );
|
|
|
|
//fill menu "help"
|
|
AppendMenu(s_gui.help, 0, IDM_ABOUT, "&About");
|
|
|
|
SetMenu(s_gui.hWnd, s_gui.menu);
|
|
|
|
s_gui.hTree = CreateWindowEx (WS_EX_CLIENTEDGE, WC_TREEVIEW, "", TREESTYLE,
|
|
0, 0, 127, 380, s_gui.hWnd, (HMENU)IDM_FIRSTCHILD, s_gui.gHinst, NULL);
|
|
|
|
GUI_CreateAccelTable();
|
|
ShowWindow(s_gui.hTree, SW_SHOWDEFAULT);
|
|
}
|
|
|
|
void GUI_DisableMenus( void )
|
|
{
|
|
EnableMenuItem(s_gui.file, IDM_CREATE, MF_GRAYED);
|
|
EnableMenuItem(s_gui.file, IDM_OPEN, MF_GRAYED);
|
|
EnableMenuItem(s_gui.file, IDM_CLOSE, MF_GRAYED);
|
|
EnableMenuItem(s_gui.file, IDM_SAVE, MF_GRAYED);
|
|
EnableMenuItem(s_gui.file, IDM_SAVEAS, MF_GRAYED);
|
|
|
|
EnableMenuItem(s_gui.edit, IDM_UNDO, MF_GRAYED);
|
|
EnableMenuItem(s_gui.edit, IDM_REDO, MF_GRAYED);
|
|
EnableMenuItem(s_gui.edit, IDM_CUT, MF_GRAYED);
|
|
EnableMenuItem(s_gui.edit, IDM_COPY, MF_GRAYED);
|
|
EnableMenuItem(s_gui.edit, IDM_PASTE, MF_GRAYED);
|
|
EnableMenuItem(s_gui.edit, IDM_DELETE, MF_GRAYED);
|
|
EnableMenuItem(s_gui.edit, IDM_FIND, MF_GRAYED);
|
|
EnableMenuItem(s_gui.edit, IDM_REPLACE, MF_GRAYED);
|
|
EnableMenuItem(s_gui.edit, IDM_GOTO, MF_GRAYED);
|
|
|
|
EnableMenuItem(s_gui.cmds, IDM_COMPILE, MF_GRAYED);
|
|
EnableMenuItem(s_gui.cmds, IDM_GETINFO, MF_GRAYED);
|
|
|
|
EnableMenuItem(s_gui.cmds, IDM_SETTINGS, MF_GRAYED);
|
|
}
|
|
|
|
void GUI_ShowConsole( void )
|
|
{
|
|
w_opts.show_console = true;
|
|
ShowWindow( s_gui.hConsole, SW_SHOWNORMAL );
|
|
SendMessage( s_gui.hConsole, EM_LINESCROLL, 0, 0xffff );
|
|
CheckMenuItem(s_gui.cmds, IDM_SHOWCONSOLE, MF_CHECKED);
|
|
SendMessage( s_gui.hWnd, WM_SIZE, 1, 0 );
|
|
}
|
|
|
|
void GUI_HideConsole( void )
|
|
{
|
|
w_opts.show_console = false;
|
|
ShowWindow(s_gui.hConsole, SW_HIDE);
|
|
CheckMenuItem(s_gui.cmds, IDM_SHOWCONSOLE, MF_UNCHECKED);
|
|
SendMessage( s_gui.hWnd, WM_SIZE, 1, 0 );//update windows
|
|
}
|
|
|
|
void GUI_UpdateDefault( WPARAM wParam )
|
|
{
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDM_DELETE:
|
|
Msg("delete accel\n");
|
|
break;
|
|
case IDM_COMPILE:
|
|
break;
|
|
case IDM_GETINFO:
|
|
break;
|
|
case IDM_SETTINGS:
|
|
ShowWindow( s_gui.hOptions, SW_SHOWNORMAL );
|
|
SetFocus( s_gui.hOptions );
|
|
EnableWindow( s_gui.hWnd, false );
|
|
break;
|
|
case IDM_SHOWCONSOLE:
|
|
if(w_opts.show_console) GUI_HideConsole();
|
|
else GUI_ShowConsole();
|
|
break;
|
|
case IDM_ABOUT:
|
|
if(!w_opts.show_console) GUI_ShowConsole();
|
|
Msg("Xash Resource Editor. Ver %g\n", EDITOR_VERSION );
|
|
Msg("Copyright XashXT Group 2007 ©.\n");
|
|
break;
|
|
}
|
|
}
|
|
|
|
void GUI_UpdateMenu( WPARAM wParam )
|
|
{
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDM_CREATE:
|
|
Msg("Create new file\n");
|
|
break;
|
|
case IDM_OPEN:
|
|
Msg("open file\n");
|
|
break;
|
|
case IDM_CLOSE:
|
|
break;
|
|
case IDM_SAVE:
|
|
break;
|
|
case IDM_SAVEAS:
|
|
break;
|
|
case IDM_QUIT:
|
|
PostQuitMessage (0);
|
|
break;
|
|
default:
|
|
GUI_UpdateDefault( wParam );
|
|
break;
|
|
}
|
|
}
|
|
|
|
void GUI_HotKeys( WPARAM wParam )
|
|
{
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDH_HIDECONSOLE:
|
|
if(w_opts.show_console)
|
|
GUI_HideConsole();
|
|
break;
|
|
default:
|
|
MsgWarn("GUI_HotKeys: call unused hotkey %d\n", LOWORD(wParam));
|
|
break;
|
|
}
|
|
}
|
|
|
|
static LRESULT CALLBACK WndProc (HWND hwnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HDC hdc;
|
|
PAINTSTRUCT ps;
|
|
|
|
switch (uMessage)
|
|
{
|
|
case WM_CREATE:
|
|
break;
|
|
case WM_PAINT:
|
|
hdc = BeginPaint(hwnd, (LPPAINTSTRUCT)&ps);
|
|
EndPaint(hwnd,(LPPAINTSTRUCT)&ps);
|
|
return TRUE;
|
|
break;
|
|
case WM_HOTKEY:
|
|
GUI_HotKeys( wParam );
|
|
break;
|
|
case WM_CHILDACTIVATE:
|
|
Msg("process child\n");
|
|
break;
|
|
case WM_SIZE:
|
|
if(s_gui.hWnd)
|
|
{
|
|
int con_w, con_h, con_y;
|
|
int exp_w, exp_h, coffs;
|
|
RECT rect;
|
|
|
|
GetClientRect(s_gui.hWnd, &rect);
|
|
con_h = (rect.bottom - rect.top) / w_opts.con_scale; //console scale factor
|
|
con_y = rect.bottom - rect.top - con_h; //console hight
|
|
con_w = rect.right - rect.left;
|
|
|
|
if(s_gui.hConsole && IsWindowVisible(s_gui.hConsole)) coffs = con_h;
|
|
else coffs = 0;
|
|
|
|
exp_w = (rect.right - rect.left) / w_opts.exp_scale; //explorer scale factor
|
|
exp_h = rect.bottom - rect.top - coffs; //explorer height
|
|
|
|
//make me sure what handle is valid
|
|
if(s_gui.hConsole) SetWindowPos(s_gui.hConsole, NULL, 0, con_y, con_w, con_h, 0);
|
|
if(s_gui.hTree) SetWindowPos(s_gui.hTree, NULL, 0, 0, exp_w, exp_h, 0);
|
|
}
|
|
break;
|
|
case WM_COMMAND:
|
|
GUI_UpdateMenu(wParam);
|
|
break;
|
|
case WM_CLOSE:
|
|
if (hwnd == s_gui.hWnd) PostQuitMessage (0);
|
|
else ShowWindow (hwnd, SW_HIDE);
|
|
return 0;
|
|
break;
|
|
}
|
|
|
|
return DefWindowProc (hwnd, uMessage, wParam, lParam);
|
|
}
|
|
|
|
void InitEditor ( char *funcname, int argc, char **argv )
|
|
{
|
|
HDC hDC;
|
|
WNDCLASS wc;
|
|
RECT rect;
|
|
int WNDSTYLE = WS_OVERLAPPEDWINDOW;
|
|
int iErrors = 0;
|
|
|
|
memset( &wc, 0, sizeof( wc ));
|
|
|
|
com_argc = argc;
|
|
memcpy(com_argv, argv, MAX_NUM_ARGVS );
|
|
GUI_ResetWndOptions();//load default settings
|
|
|
|
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
|
|
wc.lpfnWndProc = WndProc;
|
|
wc.cbClsExtra = 0;
|
|
wc.cbWndExtra = 0;
|
|
wc.hInstance = s_gui.gHinst;
|
|
wc.hIcon = LoadIcon (wc.hInstance, MAKEINTRESOURCE(IDI_ICON1));
|
|
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
|
|
wc.hbrBackground = (HBRUSH) COLOR_WINDOW;
|
|
wc.lpszMenuName = NULL;
|
|
wc.lpszClassName = CLASSNAME;
|
|
|
|
if (!wc.hIcon) wc.hIcon = LoadIcon (NULL, IDI_WINLOGO);
|
|
if (!RegisterClass (&wc)) Sys_Error("Can't create editor window\n");
|
|
|
|
//move window into center of screen
|
|
rect.left = 0;
|
|
rect.right = MAIN_WND_WIDTH;
|
|
rect.top = 0;
|
|
rect.bottom = MAIN_WND_HEIGHT;
|
|
|
|
AdjustWindowRect( &rect, WNDSTYLE, FALSE );
|
|
|
|
hDC = GetDC( GetDesktopWindow() );
|
|
s_gui.scr_width = GetDeviceCaps( hDC, HORZRES );
|
|
s_gui.scr_height = GetDeviceCaps( hDC, VERTRES );
|
|
ReleaseDC( GetDesktopWindow(), hDC );
|
|
|
|
s_gui.width = rect.right - rect.left;
|
|
s_gui.height = rect.bottom - rect.top;
|
|
s_gui.top = ( s_gui.scr_width - MAIN_WND_WIDTH ) / 2;
|
|
s_gui.bottom = ( s_gui.scr_height - MAIN_WND_HEIGHT ) / 2;
|
|
|
|
InitCommonControls ();
|
|
|
|
if(GUI_LoadPlatfrom( funcname, argc, argv )) //load config
|
|
{
|
|
wnd_options_t *config_dat;
|
|
int config_size;
|
|
|
|
config_dat = (wnd_options_t *)pi->Fs.LoadFile( "editor.dat", &config_size );
|
|
|
|
if(config_dat) //verify our config before read
|
|
{
|
|
if(config_dat->id != IDEDITORHEADER)
|
|
{
|
|
MsgWarn("InitEditor: editor.dat have mismath header!\n");
|
|
iErrors++;
|
|
}
|
|
if(config_dat->version != (int)EDITOR_VERSION)
|
|
{
|
|
MsgWarn("InitEditor: editor.dat have mismath version!\n");
|
|
iErrors++;
|
|
}
|
|
if(config_dat->csize != config_size)
|
|
{
|
|
MsgWarn("InitEditor: editor.dat have mismath size!\n");
|
|
iErrors++;
|
|
}
|
|
//copy settings into main structure
|
|
if(!iErrors) memcpy( &w_opts, config_dat, sizeof(w_opts));
|
|
}
|
|
}
|
|
else iErrors++;
|
|
|
|
GUI_CreateEditorWindow();
|
|
GUI_CreateMenus();
|
|
GUI_CreateOptionsWindow();
|
|
|
|
//apply chnages
|
|
if(w_opts.show_console) GUI_ShowConsole();
|
|
else GUI_HideConsole();
|
|
|
|
if(iErrors) GUI_DisableMenus(); // apply error
|
|
GUI_ExecuteBuffer(); //show all messages
|
|
|
|
//end of all initializations
|
|
ShowWindow(s_gui.hWnd, SW_SHOWDEFAULT);
|
|
MsgDev("------- Xash Recource Editor ver. %g initialized -------\n", EDITOR_VERSION );
|
|
}
|
|
|
|
void EditorMain ( void )
|
|
{
|
|
// wait for the user to quit
|
|
while(msg.message != WM_QUIT)
|
|
{
|
|
if(GetMessage (&msg, 0, 0, 0))
|
|
{
|
|
if (!LookupAccelTable( msg ))
|
|
{
|
|
TranslateMessage (&msg);
|
|
DispatchMessage (&msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(platform_dll)
|
|
{
|
|
// save our settings
|
|
pi->Fs.WriteFile("editor.dat", &w_opts, w_opts.csize );
|
|
}
|
|
}
|
|
|
|
void FreeEditor ( void )
|
|
{
|
|
//free richedit32
|
|
if (s_gui.richedit) FreeLibrary( s_gui.richedit );
|
|
//free platform
|
|
if(platform_dll)
|
|
{
|
|
pi->Shutdown();
|
|
FreeLibrary(platform_dll);
|
|
}
|
|
|
|
GUI_RemoveAccelTable();
|
|
UnregisterClass (CLASSNAME, s_gui.gHinst);
|
|
} |