19 unsigned char *QCC_ReadFile (char *fname, void *buffer, int len)
23 f = fopen(fname, "rb");
26 length = fread(buffer, 1, len, f);
34 int QCC_FileSize (char *fname)
38 f = fopen(fname, "rb");
41 fseek(f, 0, SEEK_END);
48 pbool QCC_WriteFile (char *name, void *data, int len)
52 f = fopen(name, "wb");
55 length = fwrite(data, 1, len, f);
67 void Sys_Error(const char *text, ...)
70 static char msg[2048];
72 va_start (argptr,text);
73 QC_vsnprintf (msg,sizeof(msg)-1, text,argptr);
76 QCC_Error(ERR_INTERNAL, "%s", msg);
81 int logprintf(const char *format, ...)
84 static char string[1024];
86 va_start (argptr, format);
88 _vsnprintf (string,sizeof(string)-1, format,argptr);
90 vsnprintf (string,sizeof(string), format,argptr);
96 fputs(string, logfile);
111 #define Edit_Redo(hwndCtl) ((BOOL)(DWORD)SNDMSG((hwndCtl), EM_REDO, 0L, 0L))
114 #define MAIN_WINDOW_CLASS_NAME "FTEMAINWINDOW"
115 #define MDI_WINDOW_CLASS_NAME "FTEMDIWINDOW"
116 #define EDIT_WINDOW_CLASS_NAME "FTEEDITWINDOW"
117 #define OPTIONS_WINDOW_CLASS_NAME "FTEOPTIONSWINDOW"
119 #define EM_GETSCROLLPOS (WM_USER + 221)
120 #define EM_SETSCROLLPOS (WM_USER + 222)
124 int GUIprintf(const char *msg, ...);
125 void GUIPrint(HWND wnd, char *msg);
129 void RunCompiler(char *args);
131 HINSTANCE ghInstance;
134 pbool resetprogssrc; //progs.src was changed, reload project info.
163 #define NUMBUTTONS sizeof(buttons)/sizeof(buttons[0])
167 void GUI_DialogPrint(char *title, char *text)
169 MessageBox(mainwindow, text, title, 0);
172 HWND CreateAnEditControl(HWND parent)
177 richedit = LoadLibrary("RICHED32.DLL");
179 newc=CreateWindowEx(WS_EX_CLIENTEDGE,
180 richedit?RICHEDIT_CLASS:"EDIT",
182 WS_CHILD /*| ES_READONLY*/ | WS_VISIBLE |
183 WS_HSCROLL | WS_VSCROLL | ES_LEFT | ES_WANTRETURN |
184 ES_MULTILINE | ES_AUTOVSCROLL,
192 newc=CreateWindowEx(WS_EX_CLIENTEDGE,
193 richedit?RICHEDIT_CLASS10A:"EDIT", //fall back to the earlier version
195 WS_CHILD /*| ES_READONLY*/ | WS_VISIBLE |
196 WS_HSCROLL | WS_VSCROLL | ES_LEFT | ES_WANTRETURN |
197 ES_MULTILINE | ES_AUTOVSCROLL,
205 { //you've not got RICHEDIT installed properly, I guess
206 FreeLibrary(richedit);
208 newc=CreateWindowEx(WS_EX_CLIENTEDGE,
211 WS_CHILD /*| ES_READONLY*/ | WS_VISIBLE |
212 WS_HSCROLL | WS_VSCROLL | ES_LEFT | ES_WANTRETURN |
213 ES_MULTILINE | ES_AUTOVSCROLL,
221 //go to lucidia console, 10pt
224 memset(&cf, 0, sizeof(cf));
225 cf.cbSize = sizeof(cf);
226 cf.dwMask = CFM_BOLD | CFM_FACE;// | CFM_SIZE;
227 strcpy(cf.szFaceName, "Lucida Console");
230 SendMessage(newc, EM_SETCHARFORMAT, SCF_ALL, (WPARAM)&cf);
235 SendMessage(newc, EM_EXLIMITTEXT, 0, 1<<20);
238 ShowWindow(newc, SW_SHOW);
267 IDI_O_CHANGE_PROGS_SRC,
268 IDI_O_ADDITIONALPARAMETERS,
274 IDI_O_SYNTAX_HIGHLIGHTING,
280 typedef struct editor_s {
281 char filename[MAX_PATH]; //abs
284 struct editor_s *next;
289 int EditorSave(editor_t *edit);
290 void EditFile(char *name, int line);
291 pbool EditorModified(editor_t *e);
292 int Rehighlight(editor_t *edit);
294 void QueryOpenFile(void)
296 char filename[MAX_PATH];
297 char oldpath[MAX_PATH+10];
299 memset(&ofn, 0, sizeof(ofn));
300 ofn.lStructSize = sizeof(ofn);
301 ofn.hInstance = ghInstance;
302 ofn.lpstrFile = filename;
303 ofn.nMaxFile = sizeof(filename)-1;
304 memset(filename, 0, sizeof(filename));
305 GetCurrentDirectory(sizeof(oldpath)-1, oldpath);
306 if (GetOpenFileName(&ofn))
307 EditFile(filename, -1);
308 SetCurrentDirectory(oldpath);
311 //IDM_ stuff that needs no active menu
312 void GenericMenu(WPARAM wParam)
314 switch(LOWORD(wParam))
321 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);
325 SendMessage(mdibox, WM_MDICASCADE, 0, 0);
328 SendMessage(mdibox, WM_MDITILE, MDITILE_HORIZONTAL, 0);
331 SendMessage(mdibox, WM_MDITILE, MDITILE_VERTICAL, 0);
336 void EditorMenu(editor_t *editor, WPARAM wParam)
338 switch(LOWORD(wParam))
344 total = SendMessage(editor->editpane, EM_GETSELTEXT, (WPARAM)sizeof(buffer)-1, (LPARAM)buffer);
348 MessageBox(NULL, "There is no name currently selected.", "Whoops", 0);
352 EditFile(buffer, -1);
362 total = SendMessage(editor->editpane, EM_GETSELTEXT, (WPARAM)sizeof(buffer)-1, (LPARAM)buffer);
366 MessageBox(NULL, "There is no name currently selected.", "Whoops", 0);
370 GoToDefinition(buffer);
378 Edit_Undo(editor->editpane);
381 Edit_Redo(editor->editpane);
390 static LONG CALLBACK EditorWndProc(HWND hWnd,UINT message,
391 WPARAM wParam,LPARAM lParam)
398 for (editor = editors; editor; editor = editor->next)
400 if (editor->window == hWnd)
402 if (editor->window == NULL)
403 break; //we're actually creating it now.
412 if (EditorModified(editor))
414 switch (MessageBox(hWnd, "Would you like to save?", editor->filename, MB_YESNOCANCEL))
419 if (!EditorSave(editor))
430 if (editor == editors)
432 editors = editor->next;
436 for (e = editors; e; e = e->next)
438 if (e->next == editor)
440 e->next = editor->next;
445 MessageBox(0, "Couldn't destroy file reference", "WARNING", 0);
449 editor->editpane = CreateAnEditControl(hWnd);
451 editor->editpane=CreateWindowEx(WS_EX_CLIENTEDGE,
452 richedit?RICHEDIT_CLASS:"EDIT",
454 WS_CHILD | WS_VISIBLE |
455 WS_HSCROLL | WS_VSCROLL | ES_LEFT | ES_WANTRETURN |
456 ES_MULTILINE | ES_AUTOVSCROLL,
465 SendMessage(editor->editpane, EM_EXLIMITTEXT, 0, 1<<31);
467 SendMessage(editor->editpane, EM_SETUNDOLIMIT, 256, 256);
471 GetClientRect(hWnd, &rect);
472 SetWindowPos(editor->editpane, NULL, 0, 0, rect.right-rect.left, rect.bottom-rect.top, 0);
475 hdc=BeginPaint(hWnd,(LPPAINTSTRUCT)&ps);
477 EndPaint(hWnd,(LPPAINTSTRUCT)&ps);
483 EditorMenu(editor, wParam);
490 nmhdr = (NMHDR *)lParam;
494 sel = (SELCHANGE *)nmhdr;
495 sprintf(message, "%s:%i - FTEQCC Editor", editor->filename, 1+Edit_LineFromChar(editor->editpane, sel->chrg.cpMin));
496 SetWindowText(editor->window, message);
503 return DefMDIChildProc(hWnd,message,wParam,lParam);
505 return DefWindowProc(hWnd,message,wParam,lParam);
511 static DWORD lastcolour;
512 int GUIEmitText(HWND wnd, int start, char *text, int len)
523 Edit_SetSel(wnd,start,start);
524 Edit_ReplaceSel(wnd,text);
526 if (!strcmp(text, "void"))
527 colour = RGB(0, 0, 255);
528 else if (!strcmp(text, "float"))
529 colour = RGB(0, 0, 255);
530 else if (!strcmp(text, "vector"))
531 colour = RGB(0, 0, 255);
532 else if (!strcmp(text, "entity"))
533 colour = RGB(0, 0, 255);
534 else if (!strcmp(text, "local"))
535 colour = RGB(0, 0, 255);
536 else if (!strcmp(text, "string"))
537 colour = RGB(0, 0, 255);
538 else if (!strcmp(text, "struct"))
539 colour = RGB(0, 0, 255);
540 else if (!strcmp(text, "class"))
541 colour = RGB(0, 0, 255);
542 else if (!strcmp(text, "union"))
543 colour = RGB(0, 0, 255);
544 else if (!strcmp(text, "const"))
545 colour = RGB(0, 0, 255);
546 else if (!strcmp(text, "var"))
547 colour = RGB(0, 0, 255);
548 else if (!strcmp(text, "nosave"))
549 colour = RGB(0, 0, 255);
551 else if (!strcmp(text, "goto"))
552 colour = RGB(255, 0, 0);
553 else if (!strcmp(text, "thinktime"))
554 colour = RGB(0, 0, 255);
555 else if (!strcmp(text, "if"))
556 colour = RGB(0, 0, 255);
557 else if (!strcmp(text, "else"))
558 colour = RGB(0, 0, 255);
559 else if (!strcmp(text, "switch"))
560 colour = RGB(0, 0, 255);
561 else if (!strcmp(text, "case"))
562 colour = RGB(0, 0, 255);
563 else if (!strcmp(text, "default"))
564 colour = RGB(0, 0, 255);
565 else if (!strcmp(text, "break"))
566 colour = RGB(0, 0, 255);
567 else if (!strcmp(text, "continue"))
568 colour = RGB(0, 0, 255);
569 else if (!strcmp(text, "do"))
570 colour = RGB(0, 0, 255);
571 else if (!strcmp(text, "while"))
572 colour = RGB(0, 0, 255);
573 else if (!strcmp(text, "for"))
574 colour = RGB(0, 0, 255);
575 else if (!strcmp(text, "return"))
576 colour = RGB(0, 0, 255);
578 else if (!strcmp(text, "self"))
579 colour = RGB(0, 0, 127);
580 else if (!strcmp(text, "this"))
581 colour = RGB(0, 0, 127);
582 else if (!strcmp(text, "other"))
583 colour = RGB(0, 0, 127);
584 else if (!strcmp(text, "world"))
585 colour = RGB(0, 0, 127);
586 else if (!strcmp(text, "time"))
587 colour = RGB(0, 0, 127);
590 else if (!strcmp(text, "#define"))
591 colour = RGB(0, 128, 255);
592 else if (!strcmp(text, "#ifdef"))
593 colour = RGB(0, 128, 255);
594 else if (!strcmp(text, "#ifndef"))
595 colour = RGB(0, 128, 255);
596 else if (!strcmp(text, "#else"))
597 colour = RGB(0, 128, 255);
598 else if (!strcmp(text, "#endif"))
599 colour = RGB(0, 128, 255);
600 else if (!strcmp(text, "#undef"))
601 colour = RGB(0, 128, 255);
602 else if (!strcmp(text, "#pragma"))
603 colour = RGB(0, 128, 255);
604 else if (!strcmp(text, "#includelist"))
605 colour = RGB(0, 128, 255);
606 else if (!strcmp(text, "#endlist"))
607 colour = RGB(0, 128, 255);
610 else if (*text == '\"')
611 colour = RGB(128, 0, 0);
613 else if (!strncmp(text, "//", 2))
614 colour = RGB(0, 127, 0);
615 else if (!strncmp(text, "/*", 2))
616 colour = RGB(0, 127, 0);
618 colour = RGB(0, 0, 0);
623 for (c = 0; c < len; c++)
629 if (colour == lastcolour)
634 Edit_SetSel(wnd,start,start+len);
635 memset(&cf, 0, sizeof(cf));
636 cf.cbSize = sizeof(cf);
637 cf.dwMask = CFM_COLOR;
638 cf.crTextColor = colour;
639 SendMessage(wnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
640 Edit_SetSel(wnd,start+len,start+len);
644 void GUIFormattingPrint(HWND wnd, char *msg)
646 int len=Edit_GetTextLength(wnd);
649 lastcolour = RGB(0,0,0);
650 SendMessage(wnd, WM_SETREDRAW, false, 0);
651 chrg.cpMin = chrg.cpMax = 0;
652 SendMessage(wnd, EM_EXSETSEL, 0, (LPARAM) &chrg);
658 else if (*msg == '/' && msg[1] == '/')
660 len = GUIEmitText(wnd, len, start, msg - start);
664 while(*msg && *msg != '\n' && *msg != '\r')
667 else if (*msg == '/' && msg[1] == '*')
669 len = GUIEmitText(wnd, len, start, msg - start);
674 if (msg[0] == '*' && msg[1] == '/')
682 else if (*msg == '#' || *msg == '_' || (*msg >= 'A' && *msg <= 'Z') || (*msg >= 'a' && *msg <= 'z'))
684 len = GUIEmitText(wnd, len, start, msg - start);
687 while (*msg == '_' || (*msg >= 'A' && *msg <= 'Z') || (*msg >= 'a' && *msg <= 'z' || *msg >= '0' && *msg <= '9'))
690 else if (*msg == '\"')
692 len = GUIEmitText(wnd, len, start, msg - start);
699 else if (*msg == '\"')
708 /* else if (*msg <= ' ')
710 while (*msg <= ' ' && *msg)
719 len = GUIEmitText(wnd, len, start, msg - start);
722 len = GUIEmitText(wnd, len, start, msg - start);
724 SendMessage(wnd, WM_SETREDRAW, true, 0);
727 int Rehighlight(editor_t *edit)
735 SendMessage(edit->editpane, EM_SETEVENTMASK, 0, 0);
737 SendMessage(edit->editpane, EM_GETSCROLLPOS, 0, (LPARAM)&scrollpos);
738 SendMessage(edit->editpane, EM_EXGETSEL, 0, (LPARAM) &chrg);
740 len = Edit_GetTextLength(edit->editpane);
741 file = malloc(len+1);
744 MessageBox(NULL, "Save failed - not enough mem", "Error", 0);
747 Edit_GetText(edit->editpane, file, len);
750 SetWindowText(edit->editpane,"");
752 // GUIPrint(edit->editpane, file);
753 GUIFormattingPrint(edit->editpane, file);
756 // Edit_SetSel(edit->editpane, Edit_LineIndex(neweditor->editpane, 0), Edit_LineIndex(neweditor->editpane, 0));
758 InvalidateRect(edit->editpane, NULL, true);
759 InvalidateRect(edit->window, NULL, true);
761 SendMessage(edit->editpane, EM_SETEVENTMASK, 0, ENM_SELCHANGE);
763 SendMessage(edit->editpane, EM_SETSCROLLPOS, 0, (LPARAM)&scrollpos);
764 SendMessage(edit->editpane, EM_EXSETSEL, 0, (LPARAM) &chrg);
766 UpdateWindow(edit->editpane);
767 RedrawWindow(edit->window, NULL, NULL, 0);
772 static void chunkcolour(HWND pane, int start, int end, DWORD colour)
775 if (colour == RGB(0,0,0))
776 return; //don't need to
777 Edit_SetSel(pane,start,end);
778 memset(&cf, 0, sizeof(cf));
779 cf.cbSize = sizeof(cf);
780 cf.dwMask = CFM_COLOR;
781 cf.crTextColor = colour;
782 SendMessage(pane, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
784 void GUIFormattingPrint(HWND wnd, char *msg)
787 int Rehighlight(editor_t *edit)
796 SendMessage(edit->editpane, WM_SETREDRAW, false, 0);
798 //Don't notify us for a bit..
799 SendMessage(edit->editpane, EM_SETEVENTMASK, 0, 0);
801 //get state so we can restore scroll positions and things.
802 SendMessage(edit->editpane, EM_GETSCROLLPOS, 0, (LPARAM)&scrollpos);
803 SendMessage(edit->editpane, EM_EXGETSEL, 0, (LPARAM) &chrg);
806 len = Edit_GetTextLength(edit->editpane);
807 file = malloc(len+1);
810 MessageBox(NULL, "Highlight failed - not enough mem", "Error", 0);
813 Edit_GetText(edit->editpane, file, len);
815 SetWindowText(edit->editpane,file); //this is so that we guarentee that the \rs or whatever that windows insists on inserting don't get in the way
818 for (last = 0, c = 0; c < len; c++)
820 if (file[c] == '/' && file[c+1] == '/') //do special syntax
822 chunkcolour(edit->editpane, last, c, color);
825 while(file[c] != '\n')
827 color = RGB(0, 127, 0);
831 chunkcolour(edit->editpane, last, c, color);
834 while(file[c] >= 'a' && file[c] <= 'z' || file[c] >= 'A' && file[c] <= 'Z' || file[c] == '_')
837 color = RGB(rand(), rand(), rand());
844 SendMessage(edit->editpane, WM_SETREDRAW, true, 0);
848 void EditFile(char *name, int line)
855 HMENU menu, menufile, menuhelp, menunavig;
857 for (neweditor = editors; neweditor; neweditor = neweditor->next)
859 if (neweditor->window && !strcmp(neweditor->filename, name))
863 Edit_SetSel(neweditor->editpane, Edit_LineIndex(neweditor->editpane, line), Edit_LineIndex(neweditor->editpane, line+1));
864 Edit_ScrollCaret(neweditor->editpane);
867 SendMessage(mdibox, WM_MDIACTIVATE, (WPARAM)neweditor->window, 0);
868 SetFocus(neweditor->window);
869 SetFocus(neweditor->editpane);
874 flen = QCC_FileSize(name);
877 MessageBox(NULL, "File not found.", "Error", 0);
881 neweditor = malloc(sizeof(editor_t));
884 MessageBox(NULL, "Low memory", "Error", 0);
888 neweditor->next = editors;
891 strncpy(neweditor->filename, name, sizeof(neweditor->filename)-1);
896 menufile = CreateMenu();
897 menuhelp = CreateMenu();
898 menunavig = CreateMenu();
899 AppendMenu(menu, MF_POPUP, (UINT)menufile, "&File");
900 AppendMenu(menu, MF_POPUP, (UINT)menunavig, "&Navigation");
901 AppendMenu(menu, MF_POPUP, (UINT)menuhelp, "&Help");
902 AppendMenu(menufile, 0, IDM_OPENNEW, "Open &new file ");
903 AppendMenu(menufile, 0, IDM_SAVE, "&Save ");
904 // AppendMenu(menufile, 0, IDM_FIND, "&Find");
905 AppendMenu(menufile, 0, IDM_UNDO, "&Undo Ctrl+Z");
906 AppendMenu(menufile, 0, IDM_REDO, "&Redo Ctrl+Y");
907 AppendMenu(menunavig, 0, IDM_GOTODEF, "Go to definition");
908 AppendMenu(menunavig, 0, IDM_OPENDOCU, "Open selected file");
909 AppendMenu(menuhelp, 0, IDM_ABOUT, "About");
910 AppendMenu(menu, 0, IDM_HIGHTLIGHT, "H&ighlight");
916 wndclass.lpfnWndProc = (WNDPROC)EditorWndProc;
917 wndclass.cbClsExtra = 0;
918 wndclass.cbWndExtra = 0;
919 wndclass.hInstance = ghInstance;
921 wndclass.hCursor = LoadCursor (NULL,IDC_ARROW);
922 wndclass.hbrBackground = (void *)COLOR_WINDOW;
923 wndclass.lpszMenuName = 0;
924 wndclass.lpszClassName = EDIT_WINDOW_CLASS_NAME;
925 RegisterClass(&wndclass);
927 neweditor->window = NULL;
932 sprintf(title, "%s", name);
934 mcs.szClass = EDIT_WINDOW_CLASS_NAME;
936 mcs.hOwner = ghInstance;
937 mcs.x = mcs.cx = CW_USEDEFAULT;
938 mcs.y = mcs.cy = CW_USEDEFAULT;
939 mcs.style = WS_OVERLAPPEDWINDOW;
942 neweditor->window = (HWND) SendMessage (mdibox, WM_MDICREATE, 0,
943 (LONG) (LPMDICREATESTRUCT) &mcs);
947 sprintf(title, "%s - FTEEditor", name);
949 neweditor->window=CreateWindow(EDIT_WINDOW_CLASS_NAME, title, WS_OVERLAPPEDWINDOW,
950 0, 0, 640, 480, NULL, NULL, ghInstance, NULL);
954 SetMenu(neweditor->window, menu);
956 if (!neweditor->window)
958 MessageBox(NULL, "Failed to create editor window", "Error", 0);
962 flen = QCC_FileSize(name);
963 file = malloc(flen+1);
964 QCC_ReadFile(name, file, flen);
967 SendMessage(neweditor->editpane, EM_SETEVENTMASK, 0, 0);
969 if (!fl_autohighlight)
971 GUIPrint(neweditor->editpane, file);
975 GUIFormattingPrint(neweditor->editpane, file);
978 SendMessage(neweditor->editpane, EM_SETEVENTMASK, 0, ENM_SELCHANGE);
981 Edit_SetSel(neweditor->editpane, Edit_LineIndex(neweditor->editpane, line), Edit_LineIndex(neweditor->editpane, line+1));
983 Edit_SetSel(neweditor->editpane, Edit_LineIndex(neweditor->editpane, 0), Edit_LineIndex(neweditor->editpane, 0));
985 Edit_ScrollCaret(neweditor->editpane);
987 ShowWindow(neweditor->window, SW_SHOW);
988 SetFocus(mainwindow);
989 SetFocus(neweditor->window);
990 SetFocus(neweditor->editpane);
993 int EditorSave(editor_t *edit)
997 len = Edit_GetTextLength(edit->editpane);
998 file = malloc(len+1);
1001 MessageBox(NULL, "Save failed - not enough mem", "Error", 0);
1004 Edit_GetText(edit->editpane, file, len);
1005 if (!QCC_WriteFile(edit->filename, file, len))
1007 MessageBox(NULL, "Save failed\nCheck path and ReadOnly flags", "Failure", 0);
1014 void EditorsRun(void)
1019 char *GUIReadFile(char *fname, void *buffer, int blen)
1022 for (e = editors; e; e = e->next)
1024 if (e->window && !strcmp(e->filename, fname))
1026 int elen = Edit_GetTextLength(e->editpane);
1027 Edit_GetText(e->editpane, buffer, blen);
1032 return QCC_ReadFile(fname, buffer, blen);
1035 int GUIFileSize(char *fname)
1038 for (e = editors; e; e = e->next)
1040 if (e->window && !strcmp(e->filename, fname))
1042 int len = Edit_GetTextLength(e->editpane);
1046 return QCC_FileSize(fname);
1049 pbool EditorModified(editor_t *e)
1053 elen = Edit_GetTextLength(e->editpane);
1054 flen = QCC_FileSize(e->filename);
1059 buffer = malloc(elen+flen);
1060 Edit_GetText(e->editpane, buffer, elen);
1061 QCC_ReadFile(e->filename, buffer+elen, flen);
1062 if (memcmp(buffer, buffer+elen, elen))
1086 HWND nokeywords_coexistitem;
1087 HWND autoprototype_item;
1088 HWND autohighlight_item;
1089 HWND extraparmsitem;
1090 static LONG CALLBACK OptionsWndProc(HWND hWnd,UINT message,
1091 WPARAM wParam,LPARAM lParam)
1105 for (i = 0; optimisations[i].enabled; i++)
1107 if (optimisations[i].flags & FLAG_HIDDENINGUI)
1110 if (Button_GetCheck(optimisations[i].guiinfo))
1111 optimisations[i].flags |= FLAG_SETINGUI;
1113 optimisations[i].flags &= ~FLAG_SETINGUI;
1115 fl_hexen2 = Button_GetCheck(hexen2item);
1116 for (i = 0; compiler_flag[i].enabled; i++)
1118 if (compiler_flag[i].flags & FLAG_HIDDENINGUI)
1120 if (Button_GetCheck(compiler_flag[i].guiinfo))
1121 compiler_flag[i].flags |= FLAG_SETINGUI;
1123 compiler_flag[i].flags &= ~FLAG_SETINGUI;
1125 fl_autohighlight = Button_GetCheck(autohighlight_item);
1126 Edit_GetText(extraparmsitem, parameters, sizeof(parameters)-1);
1128 if (wParam == IDI_O_USE)
1129 buttons[ID_COMPILE].washit = true;
1131 case IDI_O_CHANGE_PROGS_SRC:
1134 char filename[MAX_PATH];
1135 char oldpath[MAX_PATH+10];
1137 memset(&ofn, 0, sizeof(ofn));
1138 ofn.lStructSize = sizeof(ofn);
1139 ofn.hInstance = ghInstance;
1140 ofn.lpstrFile = filename;
1141 ofn.lpstrTitle = "Please find progs.src";
1142 ofn.nMaxFile = sizeof(filename)-1;
1143 ofn.lpstrFilter = "QuakeC source\0*.src\0All files\0*.*\0";
1144 memset(filename, 0, sizeof(filename));
1145 GetCurrentDirectory(sizeof(oldpath)-1, oldpath);
1146 ofn.lpstrInitialDir = oldpath;
1147 if (GetOpenFileName(&ofn))
1149 strcpy(progssrcdir, filename);
1150 for(s = progssrcdir; s; s = s2)
1152 s2 = strchr(s+1, '\\');
1160 strcpy(progssrcname, s+1);
1163 strcpy(progssrcname, filename);
1165 SetCurrentDirectory(progssrcdir);
1166 *progssrcdir = '\0';
1168 resetprogssrc = true;
1175 for (i = 0; optimisations[i].enabled; i++)
1177 if (optimisations[i].flags & FLAG_HIDDENINGUI)
1180 if (optimisations[i].optimisationlevel<=(int)wParam-IDI_O_LEVEL0)
1181 Button_SetCheck(optimisations[i].guiinfo, 1);
1183 Button_SetCheck(optimisations[i].guiinfo, 0);
1187 for (i = 0; optimisations[i].enabled; i++)
1189 if (optimisations[i].flags & FLAG_HIDDENINGUI)
1192 if (optimisations[i].flags&FLAG_KILLSDEBUGGERS)
1193 Button_SetCheck(optimisations[i].guiinfo, 0);
1197 for (i = 0; optimisations[i].enabled; i++)
1199 if (optimisations[i].flags & FLAG_HIDDENINGUI)
1202 if (optimisations[i].flags & FLAG_ASDEFAULT)
1203 Button_SetCheck(optimisations[i].guiinfo, 1);
1205 Button_SetCheck(optimisations[i].guiinfo, 0);
1213 hi = (HELPINFO *)lParam;
1217 MessageBox(hWnd, "Sets the default optimisations", "Help", MB_OK|MB_ICONINFORMATION);
1220 MessageBox(hWnd, "Clears all optimisations which can make your progs harder to debug", "Help", MB_OK|MB_ICONINFORMATION);
1226 MessageBox(hWnd, "Sets a specific optimisation level", "Help", MB_OK|MB_ICONINFORMATION);
1228 case IDI_O_CHANGE_PROGS_SRC:
1229 MessageBox(hWnd, "Use this button to change your root source file.\nNote that fteqcc compiles sourcefiles from editors first, rather than saving. This means that changes are saved ONLY when you save them, but means that switching project mid-compile can result in problems.", "Help", MB_OK|MB_ICONINFORMATION);
1231 case IDI_O_ADDITIONALPARAMETERS:
1232 MessageBox(hWnd, "Type in additional commandline parameters here. Use -Dname to define a named precompiler constant before compiling.", "Help", MB_OK|MB_ICONINFORMATION);
1235 MessageBox(hWnd, "Apply changes shown, but do not recompile yet.", "Help", MB_OK|MB_ICONINFORMATION);
1238 MessageBox(hWnd, "Apply changes shown here and recompile.", "Help", MB_OK|MB_ICONINFORMATION);
1240 case IDI_O_OPTIMISATION:
1241 for (i = 0; optimisations[i].enabled; i++)
1243 if (optimisations[i].guiinfo == hi->hItemHandle)
1245 MessageBox(hWnd, optimisations[i].description, "Help", MB_OK|MB_ICONINFORMATION);
1250 case IDI_O_COMPILER_FLAG:
1251 for (i = 0; compiler_flag[i].enabled; i++)
1253 if (compiler_flag[i].guiinfo == hi->hItemHandle)
1255 MessageBox(hWnd, compiler_flag[i].description, "Help", MB_OK|MB_ICONINFORMATION);
1261 MessageBox(hWnd, "Click here to compile a hexen2 compatible progs. Note that this uses the -Thexen2. There are other targets available.", "Help", MB_OK|MB_ICONINFORMATION);
1263 case IDI_O_SYNTAX_HIGHLIGHTING:
1264 MessageBox(hWnd, "Should syntax be highlighted automatically when a file is opened?", "Help", MB_OK|MB_ICONINFORMATION);
1270 return DefWindowProc(hWnd,message,wParam,lParam);
1274 void OptionsDialog(void)
1292 BringWindowToTop(optionsmenu);
1297 memset(&wndclass, 0, sizeof(wndclass));
1299 wndclass.lpfnWndProc = (WNDPROC)OptionsWndProc;
1300 wndclass.cbClsExtra = 0;
1301 wndclass.cbWndExtra = 0;
1302 wndclass.hInstance = ghInstance;
1304 wndclass.hCursor = LoadCursor (NULL,IDC_ARROW);
1305 wndclass.hbrBackground = (void *)COLOR_WINDOW;
1306 wndclass.lpszMenuName = 0;
1307 wndclass.lpszClassName = OPTIONS_WINDOW_CLASS_NAME;
1308 RegisterClass(&wndclass);
1311 for (i = 0; optimisations[i].enabled; i++)
1313 if (optimisations[i].flags & FLAG_HIDDENINGUI)
1320 for (i = 0; compiler_flag[i].enabled; i++)
1322 if (compiler_flag[i].flags & FLAG_HIDDENINGUI)
1328 height = (height-1)/2;
1330 while (cflagsshown > ((480-(88+40))/16)*(flagcolums))
1333 if (height < (cflagsshown+flagcolums-1)/flagcolums)
1334 height = (cflagsshown+flagcolums-1)/flagcolums;
1336 r.right = 408 + flagcolums*168;
1344 r.left = GetSystemMetrics(SM_CXSCREEN)/2-320;
1345 r.top = GetSystemMetrics(SM_CYSCREEN)/2-240;
1346 r.bottom = r.top + height;
1351 AdjustWindowRectEx (&r, WS_CAPTION|WS_SYSMENU, FALSE, 0);
1353 optionsmenu=CreateWindowEx(WS_EX_CONTEXTHELP, OPTIONS_WINDOW_CLASS_NAME, "Options - FTE QuakeC compiler", WS_CAPTION|WS_SYSMENU,
1354 r.left, r.top, r.right-r.left, r.bottom-r.top, NULL, NULL, ghInstance, NULL);
1356 subsection = CreateWindow("BUTTON", "Optimisations", WS_CHILD|WS_VISIBLE|BS_GROUPBOX,
1357 0, 0, 400, height-48, optionsmenu, NULL, ghInstance, NULL);
1360 for (i = 0; optimisations[i].enabled; i++)
1362 if (optimisations[i].flags & FLAG_HIDDENINGUI)
1364 optimisations[i].guiinfo = NULL;
1368 optimisations[i].guiinfo = wnd = CreateWindow("BUTTON",optimisations[i].fullname,
1369 WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
1370 8+200*(num&1),16+16*(num/2),200-16,16,
1372 (HMENU)IDI_O_OPTIMISATION,
1376 if (optimisations[i].flags&FLAG_SETINGUI)
1377 Button_SetCheck(wnd, 1);
1379 Button_SetCheck(wnd, 0);
1384 CreateWindow("BUTTON","O0",
1385 WS_CHILD | WS_VISIBLE,
1388 (HMENU)IDI_O_LEVEL0,
1391 CreateWindow("BUTTON","O1",
1392 WS_CHILD | WS_VISIBLE,
1393 8+64,height-88,64,32,
1395 (HMENU)IDI_O_LEVEL1,
1398 CreateWindow("BUTTON","O2",
1399 WS_CHILD | WS_VISIBLE,
1400 8+64*2,height-88,64,32,
1402 (HMENU)IDI_O_LEVEL2,
1405 CreateWindow("BUTTON","O3",
1406 WS_CHILD | WS_VISIBLE,
1407 8+64*3,height-88,64,32,
1409 (HMENU)IDI_O_LEVEL3,
1412 CreateWindow("BUTTON","Debug",
1413 WS_CHILD | WS_VISIBLE,
1414 8+64*4,height-88,64,32,
1419 CreateWindow("BUTTON","Default",
1420 WS_CHILD | WS_VISIBLE,
1421 8+64*5,height-88,64,32,
1423 (HMENU)IDI_O_DEFAULT,
1426 CreateWindow("BUTTON","Apply",
1427 WS_CHILD | WS_VISIBLE,
1433 CreateWindow("BUTTON","Use",
1434 WS_CHILD | WS_VISIBLE,
1435 8+64,height-40,64,32,
1440 CreateWindow("BUTTON","progs.src",
1441 WS_CHILD | WS_VISIBLE,
1442 8+64*2,height-40,64,32,
1444 (HMENU)IDI_O_CHANGE_PROGS_SRC,
1451 hexen2item = wnd = CreateWindow("BUTTON","HexenC",
1452 WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
1455 (HMENU)IDI_O_TARGET,
1460 Button_SetCheck(wnd, 1);
1462 Button_SetCheck(wnd, 0);
1464 autohighlight_item = wnd = CreateWindow("BUTTON","Syntax Highlighting",
1465 WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
1468 (HMENU)IDI_O_SYNTAX_HIGHLIGHTING,
1472 if (fl_autohighlight)
1473 Button_SetCheck(wnd, 1);
1475 Button_SetCheck(wnd, 0);
1479 for (i = 0; compiler_flag[i].enabled; i++)
1481 if (compiler_flag[i].flags & FLAG_HIDDENINGUI)
1483 compiler_flag[i].guiinfo = NULL;
1487 if (y > height-(88+40))
1493 compiler_flag[i].guiinfo = wnd = CreateWindow("BUTTON",compiler_flag[i].fullname,
1494 WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
1497 (HMENU)IDI_O_COMPILER_FLAG,
1505 if (compiler_flag[i].flags & FLAG_SETINGUI)
1506 Button_SetCheck(wnd, 1);
1508 Button_SetCheck(wnd, 0);
1511 CreateWindow("STATIC","Extra Parameters:",
1512 WS_CHILD | WS_VISIBLE,
1519 extraparmsitem = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT",parameters,
1520 WS_CHILD | WS_VISIBLE|ES_LEFT | ES_WANTRETURN |
1521 ES_MULTILINE | ES_AUTOVSCROLL,
1522 408,my,r.right-r.left - 408 - 8,height-my-4,
1524 (HMENU)IDI_O_ADDITIONALPARAMETERS,
1528 ShowWindow(optionsmenu, SW_SHOWDEFAULT);
1545 static LONG CALLBACK MainWndProc(HWND hWnd,UINT message,
1546 WPARAM wParam,LPARAM lParam)
1557 CLIENTCREATESTRUCT ccs;
1559 HMENU rootmenu, windowmenu, m;
1560 rootmenu = CreateMenu();
1562 AppendMenu(rootmenu, MF_POPUP, (UINT)(m = CreateMenu()), "&File");
1563 AppendMenu(m, 0, IDM_OPENNEW, "Open &new file ");
1564 AppendMenu(m, 0, IDM_SAVE, "&Save ");
1565 // AppendMenu(m, 0, IDM_FIND, "&Find");
1566 AppendMenu(m, 0, IDM_UNDO, "&Undo Ctrl+Z");
1567 AppendMenu(m, 0, IDM_REDO, "&Redo Ctrl+Y");
1568 AppendMenu(rootmenu, MF_POPUP, (UINT)(m = CreateMenu()), "&Navigation");
1569 AppendMenu(m, 0, IDM_GOTODEF, "Go to definition");
1570 AppendMenu(m, 0, IDM_OPENDOCU, "Open selected file");
1571 AppendMenu(rootmenu, MF_POPUP, (UINT)(m = windowmenu = CreateMenu()), "&Window");
1572 AppendMenu(m, 0, IDM_CASCADE, "&Cascade");
1573 AppendMenu(m, 0, IDM_TILE_HORIZ, "Tile &Horizontally");
1574 AppendMenu(m, 0, IDM_TILE_VERT, "Tile &Vertically");
1575 AppendMenu(rootmenu, MF_POPUP, (UINT)(m = CreateMenu()), "&Help");
1576 AppendMenu(m, 0, IDM_ABOUT, "About");
1578 SetMenu(hWnd, rootmenu);
1580 // Retrieve the handle to the window menu and assign the
1581 // first child window identifier.
1583 memset(&ccs, 0, sizeof(ccs));
1584 ccs.hWindowMenu = windowmenu;
1585 ccs.idFirstChild = IDM_FIRSTCHILD;
1587 // Create the MDI client window.
1589 mdibox = CreateWindow( "MDICLIENT", (LPCTSTR) NULL,
1590 WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL,
1591 0, 0, 320, 200, hWnd, (HMENU) 0xCAC, ghInstance, (LPSTR) &ccs);
1592 ShowWindow(mdibox, SW_SHOW);
1594 projecttree = CreateWindow(WC_TREEVIEW, (LPCTSTR) NULL,
1595 WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL
1596 | TVS_HASBUTTONS |TVS_LINESATROOT|TVS_HASLINES,
1597 0, 0, 320, 200, hWnd, (HMENU) 0xCAC, ghInstance, (LPSTR) &ccs);
1598 ShowWindow(projecttree, SW_SHOW);
1602 gotodefbox = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", (LPCTSTR) NULL,
1603 WS_CHILD | WS_CLIPCHILDREN,
1604 0, 0, 320, 200, hWnd, (HMENU) 0xCAC, ghInstance, (LPSTR) NULL);
1605 ShowWindow(gotodefbox, SW_SHOW);
1607 gotodefaccept = CreateWindowEx(WS_EX_CLIENTEDGE, "BUTTON", "GO",
1608 WS_CHILD | WS_CLIPCHILDREN | BS_DEFPUSHBUTTON,
1609 0, 0, 320, 200, hWnd, (HMENU) 0x4404, ghInstance, (LPSTR) NULL);
1610 ShowWindow(gotodefaccept, SW_SHOW);
1620 GetClientRect(mainwindow, &rect);
1623 SetWindowPos(projecttree, NULL, 0, 0, 192, rect.bottom-rect.top - 34 - 24, 0);
1625 SetWindowPos(gotodefbox, NULL, 0, rect.bottom-rect.top - 33 - 24, 160, 24, 0);
1626 SetWindowPos(gotodefaccept, NULL, 160, rect.bottom-rect.top - 33 - 24, 32, 24, 0);
1627 SetWindowPos(mdibox?mdibox:outputbox, NULL, 192, 0, rect.right-rect.left-192, rect.bottom-rect.top - 32, 0);
1630 SetWindowPos(mdibox?mdibox:outputbox, NULL, 0, 0, rect.right-rect.left, rect.bottom-rect.top - 32, 0);
1631 width = (rect.right-rect.left);
1633 for (i = 0; i < NUMBUTTONS; i++)
1635 SetWindowPos(buttons[i].hwnd, NULL, width*i, rect.bottom-rect.top - 32, width, 32, 0);
1639 hdc=BeginPaint(hWnd,(LPPAINTSTRUCT)&ps);
1641 EndPaint(hWnd,(LPPAINTSTRUCT)&ps);
1645 if (wParam == 0x4404)
1647 GetWindowText(gotodefbox, finddef, sizeof(finddef)-1);
1650 if (LOWORD(wParam)>0 && LOWORD(wParam) <= NUMBUTTONS)
1653 buttons[LOWORD(wParam)-1].washit = 1;
1656 if (LOWORD(wParam) < IDM_FIRSTCHILD)
1661 ew = (HWND)SendMessage(mdibox, WM_MDIGETACTIVE, 0, 0);
1663 for (editor = editors; editor; editor = editor->next)
1665 if (editor->window == ew)
1669 EditorMenu(editor, wParam);
1671 GenericMenu(wParam);
1685 nm = (NMHDR*)lParam;
1686 if (nm->hwndFrom == projecttree)
1691 item = TreeView_GetSelection(projecttree);
1694 i.pszText = itemtext;
1695 i.cchTextMax = sizeof(itemtext)-1;
1696 if (!TreeView_GetItem(projecttree, &i))
1698 strcpy(filename, i.pszText);
1701 item = TreeView_GetParent(projecttree, item);
1703 if (!TreeView_GetItem(projecttree, &i))
1705 if (!TreeView_GetParent(projecttree, item))
1708 oldlen = strlen(filename);
1709 newlen = strlen(i.pszText);
1710 memmove(filename+newlen+1, filename, oldlen+1);
1711 filename[newlen] = '/';
1712 strncpy(filename, i.pszText, newlen);
1714 EditFile(filename, -1);
1721 return DefFrameProc(hWnd,mdibox,message,wParam,lParam);
1723 return DefWindowProc(hWnd,message,wParam,lParam);
1728 static LONG CALLBACK OutputWindowProc(HWND hWnd,UINT message,
1729 WPARAM wParam,LPARAM lParam)
1735 outputwindow = NULL;
1739 outputbox = CreateAnEditControl(hWnd);
1741 GetClientRect(hWnd, &rect);
1742 SetWindowPos(outputbox, NULL, 0, 0, rect.right-rect.left, rect.bottom-rect.top, 0);
1745 return DefMDIChildProc(hWnd,message,wParam,lParam);
1750 void GUIPrint(HWND wnd, char *msg)
1764 len=Edit_GetTextLength(wnd);
1765 /* if ((unsigned)len>(32767-strlen(msg)))
1766 Edit_SetSel(wnd,0,len);
1768 Edit_SetSel(wnd,len,len);
1769 Edit_ReplaceSel(wnd,msg);
1771 while (PeekMessage (&wmsg, NULL, 0, 0, PM_NOREMOVE))
1773 if (!GetMessage (&wmsg, NULL, 0, 0))
1775 TranslateMessage (&wmsg);
1776 DispatchMessage (&wmsg);
1780 int GUIEmitOutputText(HWND wnd, int start, char *text, int len, DWORD colour)
1790 Edit_SetSel(wnd,start,start);
1791 Edit_ReplaceSel(wnd,text);
1796 for (c = 0; c < len; c++)
1797 if (text[c] == '\r')
1802 Edit_SetSel(wnd,start,start+len);
1803 memset(&cf, 0, sizeof(cf));
1804 cf.cbSize = sizeof(cf);
1805 cf.dwMask = CFM_COLOR;
1806 cf.crTextColor = colour;
1807 SendMessage(wnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
1808 Edit_SetSel(wnd,start+len,start+len);
1813 int GUIprintf(const char *msg, ...)
1824 va_start (argptr,msg);
1825 args = QC_vsnprintf (buf,sizeof(buf)-1, msg,argptr);
1830 fprintf(logfile, "%s", buf);
1834 SetWindowText(outputbox,"");
1839 if (strstr(buf, "warning: "))
1840 col = RGB(128, 128, 0);
1841 else if (strstr(buf, "error: "))
1842 col = RGB(255, 0, 0);
1853 outlen = GUIEmitOutputText(outputbox, outlen, st, strlen(st), col);
1854 outlen = GUIEmitOutputText(outputbox, outlen, rn, 1, col);
1861 outlen = GUIEmitOutputText(outputbox, outlen, st, strlen(st), col);
1863 while (PeekMessage (&wmsg, NULL, 0, 0, PM_NOREMOVE))
1865 if (!GetMessage (&wmsg, NULL, 0, 0))
1867 TranslateMessage (&wmsg);
1868 DispatchMessage (&wmsg);
1878 GUIPrint(outputbox, st);
1879 GUIPrint(outputbox, "\r\n");
1886 GUIPrint(outputbox, st);
1893 void Sys_Error(const char *text, ...);
1894 void RunCompiler(char *args)
1901 memset(&funcs, 0, sizeof(funcs));
1903 memset(&ext, 0, sizeof(ext));
1904 funcs.parms->ReadFile = GUIReadFile;
1905 funcs.parms->FileSize = GUIFileSize;
1906 funcs.parms->WriteFile = QCC_WriteFile;
1907 funcs.parms->printf = GUIprintf;
1908 funcs.parms->Sys_Error = Sys_Error;
1914 logfile = fopen("fteqcc.log", "wb");
1918 argc = GUI_BuildParms(args, argv);
1920 CompileParams(&funcs, true, argc, argv);
1927 void CreateOutputWindow(void)
1930 MDICREATESTRUCT mcs;
1932 if (!mdibox) //should already be created
1938 wndclass.lpfnWndProc = (WNDPROC)OutputWindowProc;
1939 wndclass.cbClsExtra = 0;
1940 wndclass.cbWndExtra = 0;
1941 wndclass.hInstance = ghInstance;
1943 wndclass.hCursor = LoadCursor (NULL,IDC_ARROW);
1944 wndclass.hbrBackground = (void *)COLOR_WINDOW;
1945 wndclass.lpszMenuName = 0;
1946 wndclass.lpszClassName = MAIN_WINDOW_CLASS_NAME;
1947 RegisterClass(&wndclass);
1951 mcs.szClass = MAIN_WINDOW_CLASS_NAME;
1952 mcs.szTitle = "Compiler output";
1953 mcs.hOwner = ghInstance;
1954 mcs.x = mcs.cx = CW_USEDEFAULT;
1955 mcs.y = mcs.cy = CW_USEDEFAULT;
1956 mcs.style = WS_OVERLAPPEDWINDOW;
1959 outputwindow = (HWND) SendMessage (mdibox, WM_MDICREATE, 0,
1960 (LONG) (LPMDICREATESTRUCT) &mcs);
1962 ShowWindow(outputwindow, SW_SHOW);
1965 //bring it to the front.
1966 SendMessage(mdibox, WM_MDIACTIVATE, (WPARAM)outputwindow, 0);
1969 //progssrcname should already have been set.
1970 void SetProgsSrc(void)
1974 HANDLE rootitem, pi;
1975 TVINSERTSTRUCT item;
1977 char parentstring[256];
1978 memset(&item, 0, sizeof(item));
1979 memset(&parent, 0, sizeof(parent));
1987 f = fopen (progssrcname, "rb");
1990 fseek(f, 0, SEEK_END);
1992 fseek(f, 0, SEEK_SET);
1993 buffer = malloc(size+1);
1999 buffer[size] = '\0';
2000 fread(buffer, 1, size, f);
2003 pr_file_p = QCC_COM_Parse(buffer);
2004 if (*qcc_token == '#')
2006 free(buffer); //aaaahhh! newstyle!
2010 pr_file_p = QCC_COM_Parse(pr_file_p); //we dont care about the produced progs.dat
2013 item.hParent = TVI_ROOT;
2014 item.hInsertAfter = TVI_SORT;
2015 item.item.pszText = progssrcname;
2016 item.item.mask = TVIF_TEXT;
2017 rootitem = (HANDLE)SendMessage(projecttree,TVM_INSERTITEM,0,(LPARAM)&item);
2020 pi = item.hParent = rootitem;
2021 item.item.pszText = qcc_token;
2022 while(slash = strchr(item.item.pszText, '/'))
2025 item.hParent = TreeView_GetChild(projecttree, item.hParent);
2028 parent.hItem = item.hParent;
2029 parent.mask = TVIF_TEXT;
2030 parent.pszText = parentstring;
2031 parent.cchTextMax = sizeof(parentstring)-1;
2032 if (TreeView_GetItem(projecttree, &parent))
2034 if (!stricmp(parent.pszText, item.item.pszText))
2037 } while(item.hParent=TreeView_GetNextSibling(projecttree, item.hParent));
2039 { //add a directory.
2041 pi = (HANDLE)SendMessage(projecttree,TVM_INSERTITEM,0,(LPARAM)&item);
2044 else pi = item.hParent;
2046 item.item.pszText = slash+1;
2048 SendMessage(projecttree,TVM_INSERTITEM,0,(LPARAM)&item);
2049 pr_file_p = QCC_COM_Parse(pr_file_p);
2056 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
2060 ghInstance= hInstance;
2062 GUI_SetDefaultOpts();
2064 if(strstr(lpCmdLine, "-stdout"))
2066 GUI_ParseCommandLine(lpCmdLine);
2067 RunCompiler(lpCmdLine);
2077 f = fopen("fteqcc.cfg", "rb");
2080 fseek(f, 0, SEEK_END);
2082 fseek(f, 0, SEEK_SET);
2083 lpCmdLine = malloc(len+1);
2084 fread(lpCmdLine, 1, len, f);
2085 lpCmdLine[len] = '\0';
2088 while(s = strchr(lpCmdLine, '\r'))
2090 while(s = strchr(lpCmdLine, '\n'))
2095 GUI_ParseCommandLine(lpCmdLine);
2097 GUI_RevealOptions();
2099 if (/*!fl_acc &&*/ !*progssrcname)
2101 strcpy(progssrcname, "preprogs.src");
2102 if (QCC_FileSize(progssrcname)==-1)
2103 strcpy(progssrcname, "progs.src");
2104 if (QCC_FileSize(progssrcname)==-1)
2107 char filename[MAX_PATH];
2108 char oldpath[MAX_PATH+10];
2110 memset(&ofn, 0, sizeof(ofn));
2111 ofn.lStructSize = sizeof(ofn);
2112 ofn.hInstance = ghInstance;
2113 ofn.lpstrFile = filename;
2114 ofn.lpstrTitle = "Please find progs.src";
2115 ofn.nMaxFile = sizeof(filename)-1;
2116 ofn.lpstrFilter = "QuakeC source\0*.src\0All files\0*.*\0";
2117 memset(filename, 0, sizeof(filename));
2118 GetCurrentDirectory(sizeof(oldpath)-1, oldpath);
2119 ofn.lpstrInitialDir = oldpath;
2120 if (GetOpenFileName(&ofn))
2122 strcpy(progssrcdir, filename);
2123 for(s = progssrcdir; s; s = s2)
2125 s2 = strchr(s+1, '\\');
2133 strcpy(progssrcname, s+1);
2136 strcpy(progssrcname, filename);
2140 MessageBox(NULL, "You didn't select a file", "Error", 0);
2143 SetCurrentDirectory(progssrcdir);
2144 *progssrcdir = '\0';
2148 resetprogssrc = true;
2151 wndclass.lpfnWndProc = (WNDPROC)MainWndProc;
2152 wndclass.cbClsExtra = 0;
2153 wndclass.cbWndExtra = 0;
2154 wndclass.hInstance = ghInstance;
2156 wndclass.hCursor = LoadCursor (NULL,IDC_ARROW);
2157 wndclass.hbrBackground = (void *)COLOR_WINDOW;
2158 wndclass.lpszMenuName = 0;
2159 wndclass.lpszClassName = MDI_WINDOW_CLASS_NAME;
2160 RegisterClass(&wndclass);
2162 mainwindow=CreateWindow(MDI_WINDOW_CLASS_NAME, "FTE QuakeC compiler", WS_OVERLAPPEDWINDOW,
2163 0, 0, 640, 480, NULL, NULL, ghInstance, NULL);
2167 SetWindowText(mainwindow, "FTE QuakeC Development Suite");
2172 MessageBox(NULL, "Failed to create main window", "Error", 0);
2176 InitCommonControls();
2178 outputbox=CreateWindowEx(WS_EX_CLIENTEDGE,
2181 WS_CHILD | ES_READONLY | WS_VISIBLE |
2182 WS_VSCROLL | ES_LEFT | ES_WANTRETURN |
2183 ES_MULTILINE | ES_AUTOVSCROLL,
2192 outputbox = CreateAnEditControl(mainwindow);
2194 for (i = 0; i < NUMBUTTONS; i++)
2196 buttons[i].hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,
2199 WS_CHILD | WS_VISIBLE,
2207 ShowWindow(mainwindow, SW_SHOWDEFAULT);
2209 if (fl_compileonstart)
2211 CreateOutputWindow();
2212 RunCompiler(lpCmdLine);
2218 buttons[ID_EDIT].washit = true;
2222 GUIprintf("Welcome to FTE QCC\n");
2223 GUIprintf("Source file: ");
2224 GUIprintf(progssrcname);
2231 while(mainwindow || editors)
2236 { //this here, with the compiler below, means that we don't run recursivly.
2237 resetprogssrc = false;
2243 while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
2245 if (!GetMessage (&msg, NULL, 0, 0))
2247 if (!mdibox || !TranslateMDISysAccel(mdibox, &msg))
2249 TranslateMessage (&msg);
2250 DispatchMessage (&msg);
2256 i = Edit_GetSel(outputbox);
2257 if ((i>>16) != (i&0xffff) && i != -1) //some text is selected.
2261 char *colon1, *colon2 = NULL;
2266 l1 = Edit_LineFromChar(outputbox, i&0xffff);
2267 l2 = Edit_LineFromChar(outputbox, (i>>16)&0xffff);
2270 bytes = Edit_GetLine(outputbox, Edit_LineFromChar(outputbox, i&0xffff), line, sizeof(line)-1);
2273 for (colon1 = line+strlen(line)-1; *colon1 <= ' ' && colon1>=line; colon1--)
2275 if (!strncmp(line, "warning: ", 9))
2276 memmove(line, line+9, sizeof(line));
2280 colon1 = strchr(colon1+1, ':');
2281 } while (colon1 && colon1[1] == '\\');
2285 colon2 = strchr(colon1+1, ':');
2286 while (colon2 && colon2[1] == '\\')
2288 colon2 = strchr(colon2+1, ':');
2294 EditFile(line, atoi(colon1+1)-1);
2296 else if (!strncmp(line, "Source file: ", 13))
2297 EditFile(line+13, -1);
2298 else if (!strncmp(line, "Including: ", 11))
2299 EditFile(line+11, -1);
2301 else if (!strncmp(line, "compiling ", 10))
2302 EditFile(line+10, -1);
2303 else if (!strncmp(line, "prototyping ", 12))
2304 EditFile(line+12, -1);
2305 Edit_SetSel(outputbox, i&0xffff, i&0xffff); //deselect it.
2309 if (buttons[ID_COMPILE].washit)
2311 CreateOutputWindow();
2312 RunCompiler(parameters);
2314 buttons[ID_COMPILE].washit = false;
2316 if (buttons[ID_EDIT].washit)
2318 buttons[ID_EDIT].washit = false;
2319 EditFile(progssrcname, -1);
2321 if (buttons[ID_OPTIONS].washit)
2323 buttons[ID_OPTIONS].washit = false;
2326 if (buttons[ID_QUIT].washit)
2328 buttons[ID_QUIT].washit = false;
2329 DestroyWindow(mainwindow);
2335 GoToDefinition(finddef);