From ecf8930ed265704e1cf9093de03122ed3fb3d484 Mon Sep 17 00:00:00 2001 From: Spoike Date: Wed, 25 Aug 2004 03:42:49 +0000 Subject: [PATCH] extra files needed for windows gui compiler. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@41 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/qclib/gui.h | 2 + engine/qclib/qccgui.c | 1721 ++++++++++++++++++++++++++++++++++++ engine/qclib/qccguistuff.c | 44 + 3 files changed, 1767 insertions(+) create mode 100644 engine/qclib/gui.h create mode 100644 engine/qclib/qccgui.c create mode 100644 engine/qclib/qccguistuff.c diff --git a/engine/qclib/gui.h b/engine/qclib/gui.h new file mode 100644 index 000000000..b031cca3e --- /dev/null +++ b/engine/qclib/gui.h @@ -0,0 +1,2 @@ +void GoToDefinition(char *name); +void EditFile(char *name, int line); diff --git a/engine/qclib/qccgui.c b/engine/qclib/qccgui.c new file mode 100644 index 000000000..6141f64f9 --- /dev/null +++ b/engine/qclib/qccgui.c @@ -0,0 +1,1721 @@ +#include +#include +#include +#include +#include +#include + +#include "qcc.h" +#include "gui.h" + +#define Edit_Redo(hwndCtl) ((BOOL)(DWORD)SNDMSG((hwndCtl), EM_REDO, 0L, 0L)) + + +#define MAIN_WINDOW_CLASS_NAME "FTEMAINWINDOW" +#define EDIT_WINDOW_CLASS_NAME "FTEEDITWINDOW" +#define OPTIONS_WINDOW_CLASS_NAME "FTEOPTIONSWINDOW" + +#define EM_GETSCROLLPOS (WM_USER + 221) +#define EM_SETSCROLLPOS (WM_USER + 222) + +static pbool fl_hexen2; +static pbool fl_nokeywords_coexist; +static pbool fl_autohighlight; +static pbool fl_compileonstart; +static pbool fl_autoprototype; + +char parameters[16384]; + +char progssrcname[256]; +char progssrcdir[256]; + + +int GUIprintf(const char *msg, ...); +void GUIPrint(HWND wnd, char *msg); +char *QCC_ReadFile (char *fname, void *buffer, int len); +int QCC_FileSize (char *fname); +pbool QCC_WriteFile (char *name, void *data, int len); + +void RunCompiler(char *args); + +HINSTANCE ghInstance; +HMODULE richedit; + + + +HWND mainwindow; +HWND outputbox; + +struct{ + char *text; + HWND hwnd; + int washit; +} buttons[] = { + {"Compile"}, + {"Edit"}, + {"Options"}, + {"Quit"} +}; + +#define ID_COMPILE 0 +#define ID_EDIT 1 +#define ID_OPTIONS 2 +#define ID_QUIT 3 + +#define NUMBUTTONS sizeof(buttons)/sizeof(buttons[0]) + + + +enum { + IDM_OPENDOCU=32, + IDM_OPENNEW, + IDM_GOTODEF, + IDM_SAVE, + IDM_FIND, + IDM_QUIT, + IDM_UNDO, + IDM_REDO, + IDM_ABOUT, + IDM_HIGHTLIGHT, + + IDI_O_LEVEL0, + IDI_O_LEVEL1, + IDI_O_LEVEL2, + IDI_O_LEVEL3, + IDI_O_DEFAULT, + IDI_O_DEBUG, + IDI_CHANGE_PROGS_SRC +}; + + +typedef struct editor_s { + char filename[MAX_PATH]; //abs + HWND window; + HWND editpane; + struct editor_s *next; +} editor_t; + +editor_t *editors; + +int EditorSave(editor_t *edit); +void EditFile(char *name, int line); +pbool EditorModified(editor_t *e); +int Rehighlight(editor_t *edit); + +void QueryOpenFile(void) +{ + char filename[MAX_PATH]; + char oldpath[MAX_PATH+10]; + OPENFILENAME ofn; + memset(&ofn, 0, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hInstance = ghInstance; + ofn.lpstrFile = filename; + ofn.nMaxFile = sizeof(filename)-1; + memset(filename, 0, sizeof(filename)); + GetCurrentDirectory(sizeof(oldpath)-1, oldpath); + if (GetOpenFileName(&ofn)) + EditFile(filename, -1); + SetCurrentDirectory(oldpath); +} + +static LONG CALLBACK EditorWndProc(HWND hWnd,UINT message, + WPARAM wParam,LPARAM lParam) +{ + RECT rect; + HDC hdc; + PAINTSTRUCT ps; + + editor_t *editor; + for (editor = editors; editor; editor = editor->next) + { + if (editor->window == hWnd) + break; + } + if (!editor) + return DefWindowProc(hWnd,message,wParam,lParam); + + switch (message) + { + case WM_CLOSE: + case WM_QUIT: + if (EditorModified(editor)) + { + switch (MessageBox(hWnd, "Would you like to save?", editor->filename, MB_YESNOCANCEL)) + { + case IDCANCEL: + return false; + case IDYES: + if (!EditorSave(editor)) + return false; + case IDNO: + default: + break; + } + } + DestroyWindow(editor->window); + break; + case WM_DESTROY: + { + editor_t *e; + if (editor == editors) + { + editors = editor->next; + free(editor); + return 0; + } + for (e = editors; e; e = e->next) + { + if (e->next == editor) + { + e->next = editor->next; + free(editor); + return 0; + } + } + MessageBox(0, "Couldn't destroy file reference", "WARNING", 0); + } + break; + case WM_SIZE: + GetClientRect(editor->window, &rect); + SetWindowPos(editor->editpane, NULL, 0, 0, rect.right-rect.left, rect.bottom-rect.top, 0); + break; + case WM_PAINT: + hdc=BeginPaint(hWnd,(LPPAINTSTRUCT)&ps); + + EndPaint(hWnd,(LPPAINTSTRUCT)&ps); + return TRUE; + break; + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDM_OPENNEW: + QueryOpenFile(); + break; + case IDM_OPENDOCU: + { + char buffer[1024]; + int total; + total = SendMessage(editor->editpane, EM_GETSELTEXT, (WPARAM)sizeof(buffer)-1, (LPARAM)buffer); + buffer[total]='\0'; + if (!total) + { + MessageBox(NULL, "There is no name currently selected.", "Whoops", 0); + break; + } + else + EditFile(buffer, -1); + } + break; + case IDM_SAVE: + EditorSave(editor); + break; + case IDM_GOTODEF: + { + char buffer[1024]; + int total; + total = SendMessage(editor->editpane, EM_GETSELTEXT, (WPARAM)sizeof(buffer)-1, (LPARAM)buffer); + buffer[total]='\0'; + if (!total) + { + MessageBox(NULL, "There is no name currently selected.", "Whoops", 0); + break; + } + else + GoToDefinition(buffer); + } + break; + case IDM_ABOUT: + MessageBox(NULL, "FTE QuakeC Compiler\nWritten by Forethough Entertainment.\nBasically that means it was written by Spike.\n\nIt has a few cool features, like a useful IDE.\n\nSupports:\nPrecompiler (with macros)\nArrays\n+= / -= / *= / /= operations.\nSwitch statements\nfor loops\nLots of optimisations.", "About", 0); + break; + case IDM_HIGHTLIGHT: + Rehighlight(editor); + break; + + case IDM_UNDO: + Edit_Undo(editor->editpane); + break; + case IDM_REDO: + Edit_Redo(editor->editpane); + break; + } + return DefWindowProc(hWnd,message,wParam,lParam); + case WM_NOTIFY: + { + NMHDR *nmhdr; + SELCHANGE *sel; + char message[2048]; + nmhdr = (NMHDR *)lParam; + switch(nmhdr->code) + { + case EN_SELCHANGE: + sel = (SELCHANGE *)nmhdr; + sprintf(message, "%s:%i - FTEQCC Editor", editor->filename, 1+Edit_LineFromChar(editor->editpane, sel->chrg.cpMin)); + SetWindowText(editor->window, message); + break; + } + } + return DefWindowProc(hWnd,message,wParam,lParam); + default: + return DefWindowProc(hWnd,message,wParam,lParam); + } + return 0; +} + +static DWORD lastcolour; +int GUIEmitText(HWND wnd, int start, char *text, int len) +{ + int c, cr; + DWORD colour; + CHARFORMAT cf; + + if (!len) + return start; + + c = text[len]; + text[len] = '\0'; + Edit_SetSel(wnd,start,start); + Edit_ReplaceSel(wnd,text); + + if (!strcmp(text, "void")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "float")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "vector")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "entity")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "local")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "string")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "struct")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "class")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "union")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "const")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "var")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "nosave")) + colour = RGB(0, 0, 255); + + else if (!strcmp(text, "goto")) + colour = RGB(255, 0, 0); + else if (!strcmp(text, "thinktime")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "if")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "else")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "switch")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "case")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "default")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "break")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "continue")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "do")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "while")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "for")) + colour = RGB(0, 0, 255); + else if (!strcmp(text, "return")) + colour = RGB(0, 0, 255); + + else if (!strcmp(text, "self")) + colour = RGB(0, 0, 127); + else if (!strcmp(text, "this")) + colour = RGB(0, 0, 127); + else if (!strcmp(text, "other")) + colour = RGB(0, 0, 127); + else if (!strcmp(text, "world")) + colour = RGB(0, 0, 127); + else if (!strcmp(text, "time")) + colour = RGB(0, 0, 127); + + + else if (!strcmp(text, "#define")) + colour = RGB(0, 128, 255); + else if (!strcmp(text, "#ifdef")) + colour = RGB(0, 128, 255); + else if (!strcmp(text, "#ifndef")) + colour = RGB(0, 128, 255); + else if (!strcmp(text, "#else")) + colour = RGB(0, 128, 255); + else if (!strcmp(text, "#endif")) + colour = RGB(0, 128, 255); + else if (!strcmp(text, "#undef")) + colour = RGB(0, 128, 255); + else if (!strcmp(text, "#pragma")) + colour = RGB(0, 128, 255); + else if (!strcmp(text, "#includelist")) + colour = RGB(0, 128, 255); + else if (!strcmp(text, "#endlist")) + colour = RGB(0, 128, 255); + + + else if (*text == '\"') + colour = RGB(128, 0, 0); + + else if (!strncmp(text, "//", 2)) + colour = RGB(0, 127, 0); + else if (!strncmp(text, "/*", 2)) + colour = RGB(0, 127, 0); + else + colour = RGB(0, 0, 0); + + text[len] = c; + + cr = 0; + for (c = 0; c < len; c++) + if (text[c] == '\r') + cr++; + if (cr) + len-=cr; + + if (colour == lastcolour) + return start+len; + + lastcolour = colour; + + Edit_SetSel(wnd,start,start+len); + memset(&cf, 0, sizeof(cf)); + cf.cbSize = sizeof(cf); + cf.dwMask = CFM_COLOR; + cf.crTextColor = colour; + SendMessage(wnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); + Edit_SetSel(wnd,start+len,start+len); + + return start + len; +} +void GUIFormattingPrint(HWND wnd, char *msg) +{ + int len=Edit_GetTextLength(wnd); + char *start; + CHARRANGE chrg; + lastcolour = RGB(0,0,0); + SendMessage(wnd, WM_SETREDRAW, false, 0); + chrg.cpMin = chrg.cpMax = 0; + SendMessage(wnd, EM_EXSETSEL, 0, (LPARAM) &chrg); + for(start = msg;;) + { + if (!*msg) + break; + else if (*msg == '/' && msg[1] == '/') + { + len = GUIEmitText(wnd, len, start, msg - start); + start = msg; + + msg+=2; + while(*msg && *msg != '\n' && *msg != '\r') + msg++; + } + else if (*msg == '/' && msg[1] == '*') + { + len = GUIEmitText(wnd, len, start, msg - start); + start = msg; + msg+=2; + while(*msg) + { + if (msg[0] == '*' && msg[1] == '/') + { + msg+=2; + break; + } + msg++; + } + } + else if (*msg == '#' || *msg == '_' || (*msg >= 'A' && *msg <= 'Z') || (*msg >= 'a' && *msg <= 'z')) + { + len = GUIEmitText(wnd, len, start, msg - start); + start = msg; + msg++; + while (*msg == '_' || (*msg >= 'A' && *msg <= 'Z') || (*msg >= 'a' && *msg <= 'z' || *msg >= '0' && *msg <= '9')) + msg++; + } + else if (*msg == '\"') + { + len = GUIEmitText(wnd, len, start, msg - start); + start = msg; + msg++; + while(*msg) + { + if (*msg == '\\') + msg++; + else if (*msg == '\"') + { + msg++; + break; + } + + msg++; + } + } +/* else if (*msg <= ' ') + { + while (*msg <= ' ' && *msg) + msg++; + }*/ + else + { + msg++; + continue; + } + + len = GUIEmitText(wnd, len, start, msg - start); + start = msg; + } + len = GUIEmitText(wnd, len, start, msg - start); + start = msg; + SendMessage(wnd, WM_SETREDRAW, true, 0); +} + +int Rehighlight(editor_t *edit) +{ + int len; + char *file; + + CHARRANGE chrg; + POINT scrollpos; + + SendMessage(edit->editpane, EM_SETEVENTMASK, 0, 0); + + SendMessage(edit->editpane, EM_GETSCROLLPOS, 0, (LPARAM)&scrollpos); + SendMessage(edit->editpane, EM_EXGETSEL, 0, (LPARAM) &chrg); + + len = Edit_GetTextLength(edit->editpane); + file = malloc(len+1); + if (!file) + { + MessageBox(NULL, "Save failed - not enough mem", "Error", 0); + return false; + } + Edit_GetText(edit->editpane, file, len); + file[len] = '\0'; + + SetWindowText(edit->editpane,""); + +// GUIPrint(edit->editpane, file); + GUIFormattingPrint(edit->editpane, file); + free(file); + +// Edit_SetSel(edit->editpane, Edit_LineIndex(neweditor->editpane, 0), Edit_LineIndex(neweditor->editpane, 0)); + + SendMessage(edit->editpane, EM_SETEVENTMASK, 0, ENM_SELCHANGE); + + SendMessage(edit->editpane, EM_SETSCROLLPOS, 0, (LPARAM)&scrollpos); + SendMessage(edit->editpane, EM_EXSETSEL, 0, (LPARAM) &chrg); + + InvalidateRect(edit->editpane, NULL, true); + UpdateWindow(edit->editpane); + + return true; +} + +void EditFile(char *name, int line) +{ + char title[1024]; + int flen; + char *file; + editor_t *neweditor; + WNDCLASS wndclass; + HMENU menu, menufile, menuhelp, menunavig; + + for (neweditor = editors; neweditor; neweditor = neweditor->next) + { + if (neweditor->window && !strcmp(neweditor->filename, name)) + { + if (line >= 0) + { + Edit_SetSel(neweditor->editpane, Edit_LineIndex(neweditor->editpane, line), Edit_LineIndex(neweditor->editpane, line+1)); + Edit_ScrollCaret(neweditor->editpane); + } + SetFocus(neweditor->window); + SetFocus(neweditor->editpane); + return; + } + } + + flen = QCC_FileSize(name); + if (flen == -1) + { + MessageBox(NULL, "File not found.", "Error", 0); + return; + } + + neweditor = malloc(sizeof(editor_t)); + if (!neweditor) + { + MessageBox(NULL, "Low memory", "Error", 0); + return; + } + + neweditor->next = editors; + editors = neweditor; + + strncpy(neweditor->filename, name, sizeof(neweditor->filename)-1); + + menu = CreateMenu(); + menufile = CreateMenu(); + menuhelp = CreateMenu(); + menunavig = CreateMenu(); + AppendMenu(menu, MF_POPUP, (UINT)menufile, "&File"); + AppendMenu(menu, MF_POPUP, (UINT)menunavig, "&Navigation"); + AppendMenu(menu, MF_POPUP, (UINT)menuhelp, "&Help"); + AppendMenu(menufile, 0, IDM_OPENNEW, "Open &new file "); + AppendMenu(menufile, 0, IDM_SAVE, "&Save "); +// AppendMenu(menufile, 0, IDM_FIND, "&Find"); + AppendMenu(menufile, 0, IDM_UNDO, "&Undo Ctrl+Z"); + AppendMenu(menufile, 0, IDM_REDO, "&Redo Ctrl+Y"); + AppendMenu(menunavig, 0, IDM_GOTODEF, "Go to definition"); + AppendMenu(menunavig, 0, IDM_OPENDOCU, "Open selected file"); + AppendMenu(menuhelp, 0, IDM_ABOUT, "About"); + AppendMenu(menu, 0, IDM_HIGHTLIGHT, "H&ighlight"); + + + + + wndclass.style = 0; + wndclass.lpfnWndProc = (WNDPROC)EditorWndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = ghInstance; + wndclass.hIcon = 0; + wndclass.hCursor = LoadCursor (NULL,IDC_ARROW); + wndclass.hbrBackground = (void *)COLOR_WINDOW; + wndclass.lpszMenuName = 0; + wndclass.lpszClassName = EDIT_WINDOW_CLASS_NAME; + RegisterClass(&wndclass); + + sprintf(title, "%s - FTEEditor", name); + neweditor->window=CreateWindow(EDIT_WINDOW_CLASS_NAME, title, WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, NULL, NULL, ghInstance, NULL); + + SetMenu(neweditor->window, menu); + + if (!neweditor->window) + { + MessageBox(NULL, "Failed to create editor window", "Error", 0); + return; + } + + richedit = LoadLibrary("RICHED32.DLL"); + neweditor->editpane=CreateWindowEx(WS_EX_CLIENTEDGE, + richedit?RICHEDIT_CLASS:"EDIT", + "", + WS_CHILD /*| ES_READONLY*/ | WS_VISIBLE | + WS_HSCROLL | WS_VSCROLL | ES_LEFT | ES_WANTRETURN | + ES_MULTILINE | ES_AUTOVSCROLL, + 0, 0, 0, 0, + neweditor->window, + NULL, + ghInstance, + NULL); + + if (richedit) + { + SendMessage(neweditor->editpane, EM_EXLIMITTEXT, 0, 1<<20); + + SendMessage(neweditor->editpane, EM_SETUNDOLIMIT, 256, 256); + } + + flen = QCC_FileSize(name); + file = malloc(flen+1); + QCC_ReadFile(name, file, flen); + file[flen] = 0; + + SendMessage(neweditor->editpane, EM_SETEVENTMASK, 0, 0); + + if (!fl_autohighlight) + { + GUIPrint(neweditor->editpane, file); + } + else + { + GUIFormattingPrint(neweditor->editpane, file); + } + + SendMessage(neweditor->editpane, EM_SETEVENTMASK, 0, ENM_SELCHANGE); + + if (line >= 0) + Edit_SetSel(neweditor->editpane, Edit_LineIndex(neweditor->editpane, line), Edit_LineIndex(neweditor->editpane, line+1)); + else + Edit_SetSel(neweditor->editpane, Edit_LineIndex(neweditor->editpane, 0), Edit_LineIndex(neweditor->editpane, 0)); + + Edit_ScrollCaret(neweditor->editpane); + + ShowWindow(neweditor->window, SW_SHOWDEFAULT); + SetFocus(neweditor->window); + SetFocus(neweditor->editpane); +} + +int EditorSave(editor_t *edit) +{ + int len; + char *file; + len = Edit_GetTextLength(edit->editpane); + file = malloc(len+1); + if (!file) + { + MessageBox(NULL, "Save failed - not enough mem", "Error", 0); + return false; + } + Edit_GetText(edit->editpane, file, len); + if (!QCC_WriteFile(edit->filename, file, len)) + { + MessageBox(NULL, "Save failed\nCheck path and ReadOnly flags", "Failure", 0); + return false; + } + free(file); + + return true; +} +void EditorsRun(void) +{ +} + + +char *GUIReadFile(char *fname, void *buffer, int blen) +{ + editor_t *e; + for (e = editors; e; e = e->next) + { + if (e->window && !strcmp(e->filename, fname)) + { + int elen = Edit_GetTextLength(e->editpane); + Edit_GetText(e->editpane, buffer, blen); + return buffer; + } + } + + return QCC_ReadFile(fname, buffer, blen); +} + +int GUIFileSize(char *fname) +{ + editor_t *e; + for (e = editors; e; e = e->next) + { + if (e->window && !strcmp(e->filename, fname)) + { + int len = Edit_GetTextLength(e->editpane); + return len; + } + } + return QCC_FileSize(fname); +} + +pbool EditorModified(editor_t *e) +{ + char *buffer; + int elen, flen; + elen = Edit_GetTextLength(e->editpane); + flen = QCC_FileSize(e->filename); + + if (elen != flen) + return true; + + buffer = malloc(elen+flen); + Edit_GetText(e->editpane, buffer, elen); + QCC_ReadFile(e->filename, buffer+elen, flen); + if (memcmp(buffer, buffer+elen, elen)) + { + free(buffer); + return true; + } + free(buffer); + + return false; +} + + + + + + + + + + + + + +HWND optionsmenu; +HWND hexen2item; +HWND nokeywords_coexistitem; +HWND autoprototype_item; +HWND autohighlight_item; +HWND extraparmsitem; +static LONG CALLBACK OptionsWndProc(HWND hWnd,UINT message, + WPARAM wParam,LPARAM lParam) +{ + int i; + switch (message) + { + case WM_DESTROY: + optionsmenu = NULL; + break; + + case WM_COMMAND: + switch(wParam) + { + case IDRETRY: + case IDOK: + for (i = 0; optimisations[i].enabled; i++) + { + if (Button_GetCheck(optimisations[i].guiinfo)) + optimisations[i].flags |= 8; + else + optimisations[i].flags &= ~8; + } + fl_hexen2 = Button_GetCheck(hexen2item); + fl_nokeywords_coexist = Button_GetCheck(nokeywords_coexistitem); + fl_autohighlight = Button_GetCheck(autohighlight_item); + fl_autoprototype = Button_GetCheck(autoprototype_item); + Edit_GetText(extraparmsitem, parameters, sizeof(parameters)-1); + + if (wParam == IDRETRY) + buttons[ID_COMPILE].washit = true; + break; + case IDI_CHANGE_PROGS_SRC: + { + char *s, *s2; + char filename[MAX_PATH]; + char oldpath[MAX_PATH+10]; + OPENFILENAME ofn; + memset(&ofn, 0, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hInstance = ghInstance; + ofn.lpstrFile = filename; + ofn.lpstrTitle = "Please find progs.src"; + ofn.nMaxFile = sizeof(filename)-1; + ofn.lpstrFilter = "QuakeC source\0*.src\0All files\0*.*\0"; + memset(filename, 0, sizeof(filename)); + GetCurrentDirectory(sizeof(oldpath)-1, oldpath); + ofn.lpstrInitialDir = oldpath; + if (GetOpenFileName(&ofn)) + { + strcpy(progssrcdir, filename); + for(s = progssrcdir; s; s = s2) + { + s2 = strchr(s+1, '\\'); + if (!s2) + break; + s = s2; + } + if (s) + { + *s = '\0'; + strcpy(progssrcname, s+1); + } + else + strcpy(progssrcname, filename); + + SetCurrentDirectory(progssrcdir); + *progssrcdir = '\0'; + } + } + break; + case IDI_O_LEVEL0: + case IDI_O_LEVEL1: + case IDI_O_LEVEL2: + case IDI_O_LEVEL3: + for (i = 0; optimisations[i].enabled; i++) + { + if (optimisations[i].optimisationlevel<=(int)wParam-IDI_O_LEVEL0) + Button_SetCheck(optimisations[i].guiinfo, 1); + else + Button_SetCheck(optimisations[i].guiinfo, 0); + } + break; + case IDI_O_DEBUG: + for (i = 0; optimisations[i].enabled; i++) + { + if (optimisations[i].flags&1) + Button_SetCheck(optimisations[i].guiinfo, 0); + } + break; + case IDI_O_DEFAULT: + for (i = 0; optimisations[i].enabled; i++) + { + if (optimisations[i].flags & 2) + Button_SetCheck(optimisations[i].guiinfo, 1); + else + Button_SetCheck(optimisations[i].guiinfo, 0); + } + break; + } + break; + + default: + return DefWindowProc(hWnd,message,wParam,lParam); + } + return 0; +} +void OptionsDialog(void) +{ + HWND subsection; + RECT r; + WNDCLASS wndclass; + HWND wnd; + int i; + + int y; + int height; + + if (optionsmenu) + { + BringWindowToTop(optionsmenu); + return; + } + + + memset(&wndclass, 0, sizeof(wndclass)); + wndclass.style = 0; + wndclass.lpfnWndProc = (WNDPROC)OptionsWndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = ghInstance; + wndclass.hIcon = 0; + wndclass.hCursor = LoadCursor (NULL,IDC_ARROW); + wndclass.hbrBackground = (void *)COLOR_WINDOW; + wndclass.lpszMenuName = 0; + wndclass.lpszClassName = OPTIONS_WINDOW_CLASS_NAME; + RegisterClass(&wndclass); + + height = 0; + for (i = 0; optimisations[i].enabled; i++) + height++; + + height = ((height-1)/2)*16; + + height += 88+40; + + r.left = GetSystemMetrics(SM_CXSCREEN)/2-320; + r.top = GetSystemMetrics(SM_CYSCREEN)/2-240; + r.right = r.left + 640; + r.bottom = r.top + height; + + AdjustWindowRectEx (&r, WS_CAPTION|WS_SYSMENU, FALSE, 0); + + optionsmenu=CreateWindow(OPTIONS_WINDOW_CLASS_NAME, "Options - FTE QuakeC compiler", WS_CAPTION|WS_SYSMENU, + r.left, r.top, r.right-r.left, r.bottom-r.top, NULL, NULL, ghInstance, NULL); + + subsection = CreateWindow("BUTTON", "Optimisations", WS_CHILD|WS_VISIBLE|BS_GROUPBOX, + 0, 0, 400, height-48, optionsmenu, NULL, ghInstance, NULL); + + for (i = 0; optimisations[i].enabled; i++) + { + optimisations[i].guiinfo = wnd = CreateWindow("BUTTON",optimisations[i].fullname, + WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, + 8+200*(i&1),16+16*(i/2),200-16,16, + subsection, + (HMENU)i, + ghInstance, + NULL); + + if (optimisations[i].flags&8) + Button_SetCheck(wnd, 1); + else + Button_SetCheck(wnd, 0); + } + + CreateWindow("BUTTON","O0", + WS_CHILD | WS_VISIBLE, + 8,height-88,64,32, + optionsmenu, + (HMENU)IDI_O_LEVEL0, + ghInstance, + NULL); + CreateWindow("BUTTON","O1", + WS_CHILD | WS_VISIBLE, + 8+64,height-88,64,32, + optionsmenu, + (HMENU)IDI_O_LEVEL1, + ghInstance, + NULL); + CreateWindow("BUTTON","O2", + WS_CHILD | WS_VISIBLE, + 8+64*2,height-88,64,32, + optionsmenu, + (HMENU)IDI_O_LEVEL2, + ghInstance, + NULL); + CreateWindow("BUTTON","O3", + WS_CHILD | WS_VISIBLE, + 8+64*3,height-88,64,32, + optionsmenu, + (HMENU)IDI_O_LEVEL3, + ghInstance, + NULL); + CreateWindow("BUTTON","Debug", + WS_CHILD | WS_VISIBLE, + 8+64*4,height-88,64,32, + optionsmenu, + (HMENU)IDI_O_DEBUG, + ghInstance, + NULL); + CreateWindow("BUTTON","Default", + WS_CHILD | WS_VISIBLE, + 8+64*5,height-88,64,32, + optionsmenu, + (HMENU)IDI_O_DEFAULT, + ghInstance, + NULL); + CreateWindow("BUTTON","Apply", + WS_CHILD | WS_VISIBLE, + 8,height-40,64,32, + optionsmenu, + (HMENU)IDOK, + ghInstance, + NULL); + CreateWindow("BUTTON","Use", + WS_CHILD | WS_VISIBLE, + 8+64,height-40,64,32, + optionsmenu, + (HMENU)IDRETRY, + ghInstance, + NULL); + CreateWindow("BUTTON","progs.src", + WS_CHILD | WS_VISIBLE, + 8+64*2,height-40,64,32, + optionsmenu, + (HMENU)IDI_CHANGE_PROGS_SRC, + ghInstance, + NULL); + + + + y=4; + hexen2item = wnd = CreateWindow("BUTTON","HexenC", + WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, + 408,y,200-16,16, + optionsmenu, + (HMENU)i, + ghInstance, + NULL); + y+=16; + if (fl_hexen2) + Button_SetCheck(wnd, 1); + else + Button_SetCheck(wnd, 0); + + nokeywords_coexistitem = wnd = CreateWindow("BUTTON","Disable Keywords", + WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, + 408,y,200-16,16, + optionsmenu, + (HMENU)i, + ghInstance, + NULL); + y+=16; + if (fl_nokeywords_coexist) + Button_SetCheck(wnd, 1); + else + Button_SetCheck(wnd, 0); + + autohighlight_item = wnd = CreateWindow("BUTTON","Syntax Highlighting", + WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, + 408,y,200-16,16, + optionsmenu, + (HMENU)i, + ghInstance, + NULL); + y+=16; + if (fl_autohighlight) + Button_SetCheck(wnd, 1); + else + Button_SetCheck(wnd, 0); + + autoprototype_item = wnd = CreateWindow("BUTTON","Automate prototypes", + WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, + 408,y,200-16,16, + optionsmenu, + (HMENU)i, + ghInstance, + NULL); + y+=16; + if (fl_autoprototype) + Button_SetCheck(wnd, 1); + else + Button_SetCheck(wnd, 0); + + CreateWindow("STATIC","Extra Parameters:", + WS_CHILD | WS_VISIBLE, + 408,y,200-16,16, + optionsmenu, + (HMENU)IDOK, + ghInstance, + NULL); + y+=16; + extraparmsitem = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT",parameters, + WS_CHILD | WS_VISIBLE|ES_LEFT | ES_WANTRETURN | + ES_MULTILINE | ES_AUTOVSCROLL, + 408,y,240-16+16-12,height-y-4, + optionsmenu, + (HMENU)IDI_O_DEFAULT, + ghInstance, + NULL); + + ShowWindow(optionsmenu, SW_SHOWDEFAULT); +} + + + + + + + + + + + +#undef printf + + + +static LONG CALLBACK MainWndProc(HWND hWnd,UINT message, + WPARAM wParam,LPARAM lParam) +{ + int width; + int i; + RECT rect; + HDC hdc; + PAINTSTRUCT ps; + switch (message) + { + case WM_DESTROY: + mainwindow = NULL; + break; + + case WM_SIZE: + GetClientRect(mainwindow, &rect); + SetWindowPos(outputbox, NULL, 0, 0, rect.right-rect.left, rect.bottom-rect.top - 32, 0); + width = (rect.right-rect.left); + width/=NUMBUTTONS; + for (i = 0; i < NUMBUTTONS; i++) + { + SetWindowPos(buttons[i].hwnd, NULL, width*i, rect.bottom-rect.top - 32, width, 32, 0); + } + break; + case WM_PAINT: + hdc=BeginPaint(hWnd,(LPPAINTSTRUCT)&ps); + + EndPaint(hWnd,(LPPAINTSTRUCT)&ps); + return TRUE; + break; + case WM_COMMAND: + if (LOWORD(wParam)) + buttons[LOWORD(wParam)-1].washit = 1; + break; + default: + return DefWindowProc(hWnd,message,wParam,lParam); + } + return 0; +} + +void GUIPrint(HWND wnd, char *msg) +{ + MSG wmsg; + int len; + static int writing; + + if (writing) + return; + if (!mainwindow) + { + printf("%s", msg); + return; + } + writing=true; + len=Edit_GetTextLength(wnd); +/* if ((unsigned)len>(32767-strlen(msg))) + Edit_SetSel(wnd,0,len); + else*/ + Edit_SetSel(wnd,len,len); + Edit_ReplaceSel(wnd,msg); + + while (PeekMessage (&wmsg, NULL, 0, 0, PM_NOREMOVE)) + { + if (!GetMessage (&wmsg, NULL, 0, 0)) + break; + TranslateMessage (&wmsg); + DispatchMessage (&wmsg); + } + writing=false; +} +int GUIEmitOutputText(HWND wnd, int start, char *text, int len, DWORD colour) +{ + int c, cr; + CHARFORMAT cf; + + if (!len) + return start; + + c = text[len]; + text[len] = '\0'; + Edit_SetSel(wnd,start,start); + Edit_ReplaceSel(wnd,text); + + text[len] = c; + + cr = 0; + for (c = 0; c < len; c++) + if (text[c] == '\r') + cr++; + if (cr) + len-=cr; + + Edit_SetSel(wnd,start,start+len); + memset(&cf, 0, sizeof(cf)); + cf.cbSize = sizeof(cf); + cf.dwMask = CFM_COLOR; + cf.crTextColor = colour; + SendMessage(wnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf); + Edit_SetSel(wnd,start+len,start+len); + + return start + len; +} +int outlen; +int GUIprintf(const char *msg, ...) +{ + va_list argptr; + char buf[1024]; + char rn[3] = "\n"; + char *st, *s; + int args; + MSG wmsg; + + DWORD col; + + va_start (argptr,msg); + args = QC_vsnprintf (buf,sizeof(buf)-1, msg,argptr); + va_end (argptr); + + if (!*buf) + { + SetWindowText(outputbox,""); + outlen = 0; + return 0; + } + + if (strstr(buf, "warning: ")) + col = RGB(128, 128, 0); + else if (strstr(buf, "error: ")) + col = RGB(255, 0, 0); + else + col = RGB(0, 0, 0); + + s = st = buf; + while(*s) + { + if (*s == '\n') + { + *s = '\0'; + if (*st) + outlen = GUIEmitOutputText(outputbox, outlen, st, strlen(st), col); + outlen = GUIEmitOutputText(outputbox, outlen, rn, 1, col); + st = s+1; + } + + s++; + } + if (*st) + outlen = GUIEmitOutputText(outputbox, outlen, st, strlen(st), col); + + while (PeekMessage (&wmsg, NULL, 0, 0, PM_NOREMOVE)) + { + if (!GetMessage (&wmsg, NULL, 0, 0)) + break; + TranslateMessage (&wmsg); + DispatchMessage (&wmsg); + } +/* + s = st = buf; + while(*s) + { + if (*s == '\n') + { + *s = '\0'; + if (*st) + GUIPrint(outputbox, st); + GUIPrint(outputbox, "\r\n"); + st = s+1; + } + + s++; + } + if (*st) + GUIPrint(outputbox, st); +*/ + return args; +} + +#undef Sys_Error +void Sys_Error(const char *text, ...); +void RunCompiler(char *args) +{ + int i; + char *argv[64]; + char param[2048]; + char *next; + int paramlen = 0; + int argc; + progexterns_t ext; + progfuncs_t funcs; + memset(&funcs, 0, sizeof(funcs)); + funcs.parms = &ext; + memset(&ext, 0, sizeof(ext)); + funcs.parms->ReadFile = GUIReadFile; + funcs.parms->FileSize = GUIFileSize; + funcs.parms->WriteFile = QCC_WriteFile; + funcs.parms->printf = GUIprintf; + funcs.parms->Sys_Error = Sys_Error; + GUIprintf(""); + + + argc = 1; + argv[0] = "fteqcc"; + + while(*args) + { + while (*args <= ' '&& *args) + args++; + + for (next = args; *next>' '; next++) + ; + strncpy(param+paramlen, args, next-args); + param[paramlen+next-args] = '\0'; + argv[argc++] = param+paramlen; + paramlen += strlen(param+paramlen)+1; + + args=next; + } + + if (fl_hexen2) + { + strcpy(param+paramlen, "-Th2"); + argv[argc++] = param+paramlen; + paramlen += strlen(param+paramlen)+1; + } + if (fl_nokeywords_coexist) + { + strcpy(param+paramlen, "-Fno-kce"); + argv[argc++] = param+paramlen; + paramlen += strlen(param+paramlen)+1; + } + if (fl_autoprototype) + { + strcpy(param+paramlen, "-Fautoproto"); + argv[argc++] = param+paramlen; + paramlen += strlen(param+paramlen)+1; + } + + + for (i = 0; optimisations[i].enabled; i++) //enabled is a pointer + { + if (optimisations[i].flags & 8) + sprintf(param+paramlen, "-O%s", optimisations[i].abbrev); + else + sprintf(param+paramlen, "-Ono-%s", optimisations[i].abbrev); + argv[argc++] = param+paramlen; + paramlen += strlen(param+paramlen)+1; + } + + +/* while(*args) + { + while (*args <= ' '&& *args) + args++; + + for (next = args; *next>' '; next++) + ; + strncpy(param+paramlen, args, next-args); + param[paramlen+next-args] = '\0'; + argv[argc++] = param+paramlen; + paramlen += strlen(param+paramlen)+1; + args=next; + }*/ + + if (*progssrcname) + { + argv[argc++] = "-srcfile"; + argv[argc++] = progssrcname; + } + if (*progssrcdir) + { + argv[argc++] = "-src"; + argv[argc++] = progssrcdir; + } + + CompileParams(&funcs, true, argc, argv); +} + + +//this function takes the windows specified commandline and strips out all the options menu items. +void GuiParseCommandLine(char *args) +{ + int paramlen=0; + int l, p; + char *next; + while(*args) + { + while (*args <= ' ' && *args) + args++; + + for (next = args; *next>' '; next++) + ; + + strncpy(parameters+paramlen, args, next-args); + parameters[paramlen+next-args] = '\0'; + l = strlen(parameters+paramlen)+1; + + if (!strnicmp(parameters+paramlen, "-O", 2) || !strnicmp(parameters+paramlen, "/O", 2)) + { //strip out all -O + if (parameters[paramlen+2] >= '0' && parameters[paramlen+2] <= '3') + { + p = parameters[paramlen+2]-'0'; + for (l = 0; optimisations[l].enabled; l++) + { + if (optimisations[l].optimisationlevel<=p) + optimisations[l].flags |= 8; + else + optimisations[l].flags &= ~8; + } + p=0; + } + else if (!strncmp(parameters+paramlen+2, "no-", 3)) + { + if (parameters[paramlen+5]) + for (p = 0; optimisations[p].enabled; p++) + if ((*optimisations[p].abbrev && !strcmp(parameters+paramlen+5, optimisations[p].abbrev)) || !strcmp(parameters+paramlen+5, optimisations[p].fullname)) + { + optimisations[p].flags &= ~8; + break; + } + } + else + { + if (parameters[paramlen+2]) + for (p = 0; optimisations[p].enabled; p++) + if ((*optimisations[p].abbrev && !strcmp(parameters+paramlen+2, optimisations[p].abbrev)) || !strcmp(parameters+paramlen+2, optimisations[p].fullname)) + { + optimisations[p].flags |= 8; + break; + } + } + + if (!optimisations[p].enabled) + { + parameters[paramlen+next-args] = ' '; + paramlen += l; + } + } + else if (!strnicmp(parameters+paramlen, "-Fno-kce", 8) || !strnicmp(parameters+paramlen, "/Fno-kce", 8)) //keywords stuph + { + fl_nokeywords_coexist = true; + } + else if (!strnicmp(parameters+paramlen, "-Fkce", 5) || !strnicmp(parameters+paramlen, "/Fkce", 5)) + { + fl_nokeywords_coexist = false; + } + else if (!strnicmp(parameters+paramlen, "-sh", 3) || !strnicmp(parameters+paramlen, "/sh", 3)) + { + fl_autohighlight = true; + } + else if (!strnicmp(parameters+paramlen, "-autoproto", 10) || !strnicmp(parameters+paramlen, "/autoproto", 10)) + { + fl_autoprototype = true; + } + else if (!strnicmp(parameters+paramlen, "-ac", 3) || !strnicmp(parameters+paramlen, "/ac", 3)) + { + fl_compileonstart = true; + } + else if (!strnicmp(parameters+paramlen, "-T", 2) || !strnicmp(parameters+paramlen, "/T", 2)) //the target + { + if (!strnicmp(parameters+paramlen+2, "h2", 2)) + { + fl_hexen2 = true; + } + else + { + fl_hexen2 = false; + parameters[paramlen+next-args] = ' '; + paramlen += l; + } + } + else + { + parameters[paramlen+next-args] = ' '; + paramlen += l; + } + + args=next; + } + if (paramlen) + parameters[paramlen-1] = '\0'; + else + *parameters = '\0'; +} + +void SetDefaultOpts(void) +{ + int i; + for (i = 0; optimisations[i].enabled; i++) //enabled is a pointer + { + if (optimisations[i].flags & 2) + optimisations[i].flags |= 8; + else + optimisations[i].flags &= ~8; + } +} + +int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +{ + unsigned int i; + WNDCLASS wndclass; + ghInstance= hInstance; + + SetDefaultOpts(); + + if(strstr(lpCmdLine, "-stdout")) + { + RunCompiler(lpCmdLine); + return 0; + } + + GuiParseCommandLine(lpCmdLine); + + if (!*progssrcname) + { + strcpy(progssrcname, "preprogs.src"); + if (QCC_FileSize(progssrcname)==-1) + strcpy(progssrcname, "progs.src"); + if (QCC_FileSize(progssrcname)==-1) + { + char *s, *s2; + char filename[MAX_PATH]; + char oldpath[MAX_PATH+10]; + OPENFILENAME ofn; + memset(&ofn, 0, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hInstance = ghInstance; + ofn.lpstrFile = filename; + ofn.lpstrTitle = "Please find progs.src"; + ofn.nMaxFile = sizeof(filename)-1; + ofn.lpstrFilter = "QuakeC source\0*.src\0All files\0*.*\0"; + memset(filename, 0, sizeof(filename)); + GetCurrentDirectory(sizeof(oldpath)-1, oldpath); + ofn.lpstrInitialDir = oldpath; + if (GetOpenFileName(&ofn)) + { + strcpy(progssrcdir, filename); + for(s = progssrcdir; s; s = s2) + { + s2 = strchr(s+1, '\\'); + if (!s2) + break; + s = s2; + } + if (s) + { + *s = '\0'; + strcpy(progssrcname, s+1); + } + else + strcpy(progssrcname, filename); + } + else + { + MessageBox(NULL, "You didn't select a file", "Error", 0); + return 0; + } + SetCurrentDirectory(progssrcdir); + *progssrcdir = '\0'; + } + } + + wndclass.style = 0; + wndclass.lpfnWndProc = (WNDPROC)MainWndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = ghInstance; + wndclass.hIcon = 0; + wndclass.hCursor = LoadCursor (NULL,IDC_ARROW); + wndclass.hbrBackground = (void *)COLOR_WINDOW; + wndclass.lpszMenuName = 0; + wndclass.lpszClassName = MAIN_WINDOW_CLASS_NAME; + RegisterClass(&wndclass); + + mainwindow=CreateWindow(MAIN_WINDOW_CLASS_NAME, "FTE QuakeC compiler", WS_OVERLAPPEDWINDOW, + 0, 0, 640, 480, NULL, NULL, ghInstance, NULL); + + if (!mainwindow) + { + MessageBox(NULL, "Failed to create main window", "Error", 0); + return 0; + } + + InitCommonControls(); +/* + outputbox=CreateWindowEx(WS_EX_CLIENTEDGE, + "EDIT", + "", + WS_CHILD | ES_READONLY | WS_VISIBLE | + WS_VSCROLL | ES_LEFT | ES_WANTRETURN | + ES_MULTILINE | ES_AUTOVSCROLL, + 0, 0, 0, 0, + mainwindow, + NULL, + ghInstance, + NULL); +*/ + richedit = LoadLibrary("RICHED32.DLL"); + outputbox=CreateWindowEx(WS_EX_CLIENTEDGE, + richedit?RICHEDIT_CLASS:"EDIT", + "", + WS_CHILD /*| ES_READONLY*/ | WS_VISIBLE | + WS_HSCROLL | WS_VSCROLL | ES_LEFT | ES_WANTRETURN | + ES_MULTILINE | ES_AUTOVSCROLL, + 0, 0, 0, 0, + mainwindow, + NULL, + ghInstance, + NULL); + + if (richedit) + { + SendMessage(outputbox, EM_EXLIMITTEXT, 0, 1<<20); + } + + + for (i = 0; i < NUMBUTTONS; i++) + { + buttons[i].hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, + "BUTTON", + buttons[i].text, + WS_CHILD | WS_VISIBLE, + 0, 0, 5, 5, + mainwindow, + (HMENU)(i+1), + ghInstance, + NULL); + } + + ShowWindow(mainwindow, SW_SHOWDEFAULT); + + if (fl_compileonstart) + { + RunCompiler(lpCmdLine); + } + else + { + GUIprintf("Welcome to FTE QCC\n"); + GUIprintf("Source file: "); + GUIprintf(progssrcname); + GUIprintf("\n"); + + RunCompiler("-?"); + } + + while(mainwindow || editors) + { + MSG msg; + + EditorsRun(); + + while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)) + { + if (!GetMessage (&msg, NULL, 0, 0)) + break; + TranslateMessage (&msg); + DispatchMessage (&msg); + } + + if (mainwindow) + { + i = Edit_GetSel(outputbox); + if ((i>>16) != (i&0xffff) && i != -1) //some text is selected. + { + int bytes; + char line[1024]; + char *colon1, *colon2 = NULL; + + int l1; + int l2; + + l1 = Edit_LineFromChar(outputbox, i&0xffff); + l2 = Edit_LineFromChar(outputbox, (i>>16)&0xffff); + if (l1 == l2) + { + bytes = Edit_GetLine(outputbox, Edit_LineFromChar(outputbox, i&0xffff), line, sizeof(line)-1); + line[bytes] = 0; + + for (colon1 = line+strlen(line)-1; *colon1 <= ' ' && colon1>=line; colon1--) + *colon1 = '\0'; + if (!strncmp(line, "warning: ", 9)) + memmove(line, line+9, sizeof(line)); + colon1=line; + do + { + colon1 = strchr(colon1+1, ':'); + } while (colon1 && colon1[1] == '\\'); + + if (colon1) + { + colon2 = strchr(colon1+1, ':'); + while (colon2 && colon2[1] == '\\') + { + colon2 = strchr(colon2+1, ':'); + } + if (colon2) + { + *colon1 = '\0'; + *colon2 = '\0'; + EditFile(line, atoi(colon1+1)-1); + } + else if (!strncmp(line, "Source file: ", 13)) + EditFile(line+13, -1); + else if (!strncmp(line, "Including: ", 11)) + EditFile(line+11, -1); + } + else if (!strncmp(line, "compiling ", 10)) + EditFile(line+10, -1); + Edit_SetSel(outputbox, i&0xffff, i&0xffff); //deselect it. + } + } + + if (buttons[ID_COMPILE].washit) + { + RunCompiler(parameters); + + buttons[ID_COMPILE].washit = false; + } + if (buttons[ID_EDIT].washit) + { + buttons[ID_EDIT].washit = false; + EditFile(progssrcname, -1); + } + if (buttons[ID_OPTIONS].washit) + { + buttons[ID_OPTIONS].washit = false; + OptionsDialog(); + } + if (buttons[ID_QUIT].washit) + { + buttons[ID_QUIT].washit = false; + DestroyWindow(mainwindow); + } + } + + Sleep(10); + } + + return 0; +} diff --git a/engine/qclib/qccguistuff.c b/engine/qclib/qccguistuff.c new file mode 100644 index 000000000..87f714d27 --- /dev/null +++ b/engine/qclib/qccguistuff.c @@ -0,0 +1,44 @@ +#include "qcc.h" +#include "gui.h" + +void GoToDefinition(char *name) +{ + QCC_def_t *def; + QCC_dfunction_t *fnc; + + char *strip; //trim whitespace (for convieniance). + while (*name <= ' ' && *name) + name++; + for (strip = name + strlen(name)-1; *strip; strip++) + { + if (*strip <= ' ') + *strip = '\0'; + else //got some part of a word + break; + } + + if (!globalstable.numbuckets) + { + MessageBox(NULL, "You need to compile first.", "Not found", 0); + return; + } + + + def = QCC_PR_GetDef(NULL, name, NULL, false, 0); + + if (def) + { + if (def->type->type == ev_function && def->constant) + { + fnc = &functions[((int *)qcc_pr_globals)[def->ofs]]; + if (fnc->first_statement>=0) + { + EditFile(fnc->s_file+strings, statement_linenums[fnc->first_statement]); + return; + } + } + EditFile(def->s_file+strings, def->s_line-1); + } + else + MessageBox(NULL, "Global instance of var was not found", "Not found", 0); +}