diff --git a/Makefile b/Makefile index ff99717..132acb1 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -DEFINES = /D_WIN32_WINNT=0x400 /DISOLATION_AWARE_ENABLED /D_WIN32_IE=0x500 /DWIN32_LEAN_AND_MEAN /DWIN32 +DEFINES = /D_WIN32_WINNT=0x500 /DISOLATION_AWARE_ENABLED /D_WIN32_IE=0x500 /DWIN32_LEAN_AND_MEAN /DWIN32 CFLAGS = /W3 /nologo -I..\common\win32 /O2 /D_DEBUG /D_CRT_SECURE_NO_WARNINGS /Zi /I. HEADERS = ..\common\win32\freeze.h ui.h solvespace.h dsc.h sketch.h diff --git a/cmdline.cpp b/cmdline.cpp index 171147c..e432258 100644 --- a/cmdline.cpp +++ b/cmdline.cpp @@ -1,6 +1,16 @@ #include "solvespace.h" #include +const TextWindow::Color TextWindow::colors[] = { + { COLOR_FG_DEFAULT, COLOR_BG_DEFAULT, }, // 0 + { RGB(255, 40, 40), COLOR_BG_DEFAULT, }, // 1 + { RGB(255, 255, 0), COLOR_BG_DEFAULT, }, // 2 + { RGB( 40, 255, 40), COLOR_BG_DEFAULT, }, // 3 + { RGB( 0, 255, 255), COLOR_BG_DEFAULT, }, // 4 + { RGB(140, 140, 255), COLOR_BG_DEFAULT, }, // 5 + { RGB(255, 0, 255), COLOR_BG_DEFAULT, }, // 6 +}; + void TextWindow::Init(void) { ClearScreen(); ClearCommand(); @@ -37,34 +47,77 @@ void TextWindow::Printf(char *fmt, ...) { } int color = COLOR_NORMAL; + int link = NOT_A_LINK; + DWORD data = 0; + LinkFunction *f = NULL; c = 0; while(*fmt) { + char buf[1024]; + if(*fmt == '%') { fmt++; if(*fmt == '\0') goto done; + strcpy(buf, ""); switch(*fmt) { - case 's': { - char *s = va_arg(vl, char *); - memcpy(&(text[r][c]), s, strlen(s)); - c += strlen(s); - break; - } case 'd': { int v = va_arg(vl, int); - sprintf((char *)&(text[r][c]), "%d", v); - c += strlen((char *)&(text[r][c])); - text[r][c] = ' '; + sprintf(buf, "%d", v); break; } + case 'x': { + DWORD v = va_arg(vl, DWORD); + sprintf(buf, "%08x", v); + break; + } + case 's': { + char *s = va_arg(vl, char *); + memcpy(buf, s, min(sizeof(buf), strlen(s)+1)); + break; + } + case 'E': + color = COLOR_NORMAL; + link = NOT_A_LINK; + data = 0; + f = NULL; + break; + + case 'C': + if(fmt[1] == '\0') goto done; + fmt++; + color = *fmt - '0'; + if(color < 0 || color >= arraylen(colors)) color = 0; + break; + + case 'L': + if(fmt[1] == '\0') goto done; + fmt++; + link = *fmt; + break; + + case 'D': + data = va_arg(vl, DWORD); + break; + case '%': - text[r][c++] = '%'; + strcpy(buf, "%"); break; } } else { - if(c >= MAX_COLS) goto done; - text[r][c++] = *fmt; + buf[0] = *fmt; + buf[1]= '\0'; } + + for(unsigned i = 0; i < strlen(buf); i++) { + if(c >= MAX_COLS) goto done; + text[r][c] = buf[i]; + meta[r][c].color = color; + meta[r][c].link = link; + meta[r][c].data = data; + meta[r][c].f = f; + c++; + } + fmt++; } @@ -84,7 +137,7 @@ void TextWindow::ClearCommand(void) { void TextWindow::ProcessCommand(char *cmd) { - Printf("command: '%s'", cmd); + Printf("%C2command:%E '%s' done %C3(green)%E %C5%LaLink%E", cmd); } void TextWindow::KeyPressed(int c) { diff --git a/dsc.h b/dsc.h index 685de7b..2313dd6 100644 --- a/dsc.h +++ b/dsc.h @@ -5,9 +5,8 @@ typedef unsigned long DWORD; typedef unsigned char BYTE; -typedef struct VectorTag Vector; - -typedef struct VectorTag { +class Vector { +public: double x, y, z; Vector Cross(Vector b); @@ -16,26 +15,74 @@ typedef struct VectorTag { double Magnitude(void); Vector ScaledBy(double v); -} Vector; +}; -typedef struct { +class Point2d { +public: double x, y; -} Point2d; +}; -template struct IdList { +template +class IdList { +public: typedef struct { T v; + H h; int tag; } Elem; - Elem elem; + Elem *elem; int elems; int elemsAllocated; - void addAndAssignId(T *v); - void removeTagged(void); + void AddAndAssignId(T *v) { + int i; + int id = 0; + + for(i = 0; i < elems; i++) { + id = max(id, elem[i].h.v); + } + + H h; + h.v = id + 1; + AddById(v, h); + } + + void AddById(T *v, H h) { + if(elems >= elemsAllocated) { + elemsAllocated = (elemsAllocated + 32)*2; + elem = (Elem *)realloc(elem, elemsAllocated*sizeof(elem[0])); + if(!elem) oops(); + } + + elem[elems].v = *v; + elem[elems].h = h; + elem[elems].tag = 0; + elems++; + } + + void RemoveTagged(void) { + int src, dest; + dest = 0; + for(src = 0; src < elems; src++) { + if(elem[src].tag) { + // this item should be deleted + } else { + if(src != dest) { + elem[dest] = elem[src]; + } + dest++; + } + } + elems = dest; + // and elemsAllocated is untouched + } + + void Clear(void) { + elemsAllocated = elems = 0; + if(elem) free(elem); + } - void clear(void); }; #endif diff --git a/graphicswin.cpp b/graphicswin.cpp index d6c5fdc..a22ea65 100644 --- a/graphicswin.cpp +++ b/graphicswin.cpp @@ -127,9 +127,17 @@ void GraphicsWindow::Paint(int w, int h) { glClearDepth(1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - GLUquadricObj *quadObj; - quadObj = gluNewQuadric(); - gluQuadricDrawStyle(quadObj, GLU_LINE); - gluSphere(quadObj, 300, 4, 4); + glBegin(GL_QUADS); + glVertex3f(-200, -200, 0); + glVertex3f(-200, 200, 0); + glVertex3f( 200, 200, 0); + glVertex3f( 200, -200, 0); + glEnd(); + glBegin(GL_QUADS); + glVertex3f(-200, -200, 200); + glVertex3f(-200, 200, 200); + glVertex3f( 200, 200, 200); + glVertex3f( 200, -200, 200); + glEnd(); } diff --git a/sketch.h b/sketch.h index e586dfb..0d62db0 100644 --- a/sketch.h +++ b/sketch.h @@ -2,57 +2,67 @@ #ifndef __SKETCH_H #define __SKETCH_H -typedef struct hRequestTag hRequest; -typedef struct hEntityTag hEntity; -typedef struct hPointTag hPoint; -typedef struct hParamTag hParam; +class hEntity; +class hPoint; +class hRequest; +class hParam; -typedef struct hRequestTag { +class hRequest { +public: int v; hEntity entity(int i); -} hRequest; +}; -typedef struct { +class Request { +public: static const int REQUEST_LINE_SEGMENT = 0; static const int REQUEST_STEP_REPEAT_TRANSLATE = 1; static const int REQUEST_STEP_REPEAT_TRANSLATE_SYM = 2; int type; hRequest h; -} Request; +}; -typedef struct hEntityTag { +class hEntity { +public: int v; hRequest request(int i); hPoint point(int i); -} hEntity; +}; -typedef struct { +class Entity { +public: static const int ENTITY_LINE_SEGMENT = 0; static const int ENTITY_PWL_SEGMENT = 1; int type; hEntity h; -} Entity; +}; -typedef struct hPointTag { -} hPoint; +class hPoint { +public: + int v; +}; -typedef struct { +class Point { +public: hPoint h; -} Point; +}; -typedef struct hParamTag { -} hParam; +class hParam { +public: + int v; +}; -typedef struct { +class Param { +public: double val; hParam h; -} Param; +}; #endif diff --git a/solvespace.cpp b/solvespace.cpp index ad64dec..eb0cd9a 100644 --- a/solvespace.cpp +++ b/solvespace.cpp @@ -1,11 +1,20 @@ #include "solvespace.h" +template IdList; +template IdList; +template IdList; + SolveSpace SS; void SolveSpace::Init(void) { TW.Init(); GW.Init(); + req.Clear(); + entity.Clear(); + point.Clear(); + param.Clear(); + int i; for(i = 0; i < 20; i++) { TW.Printf("this is line number %d", i); diff --git a/solvespace.h b/solvespace.h index b66bd22..318315c 100644 --- a/solvespace.h +++ b/solvespace.h @@ -2,6 +2,17 @@ #ifndef __SOLVESPACE_H #define __SOLVESPACE_H +// Debugging functions +#define oops() do { dbp("oops at line %d, file %s", __LINE__, __FILE__); \ + exit(-1); } while(0) +#ifndef min +#define min(x, y) ((x) < (y) ? (x) : (y)) +#endif +#ifndef max +#define max(x, y) ((x) > (y) ? (x) : (y)) +#endif + +void dbp(char *str, ...); #include #include #include @@ -10,10 +21,6 @@ #include "ui.h" #include "sketch.h" -// Debugging functions -#define oops() do { dbp("oops at line %d, file %s", __LINE__, __FILE__); \ - exit(-1); } while(0) -void dbp(char *str, ...); void Invalidate(void); @@ -26,7 +33,8 @@ void MakeMatrix(double *mat, double a11, double a12, double a13, double a14, double a41, double a42, double a43, double a44); -typedef struct { +class SolveSpace { +public: TextWindow TW; GraphicsWindow GW; @@ -36,7 +44,7 @@ typedef struct { IdList param; void Init(void); -} SolveSpace; +}; extern SolveSpace SS; diff --git a/ui.h b/ui.h index c0d315d..a477a2e 100644 --- a/ui.h +++ b/ui.h @@ -2,9 +2,10 @@ #ifndef __UI_H #define __UI_H -typedef struct { - static const int MAX_COLS = 200; - static const int MAX_ROWS = 500; +class TextWindow { +public: + static const int MAX_COLS = 150; + static const int MAX_ROWS = 300; #ifndef RGB #define RGB(r, g, b) ((r) | ((g) << 8) | ((b) << 16)) @@ -14,6 +15,12 @@ typedef struct { static const int COLOR_BG_CMDLINE = RGB( 0, 20, 80); static const int COLOR_FG_CMDLINE = RGB(255, 255, 255); + typedef struct { + int fg; + int bg; + } Color; + static const Color colors[]; + // The line with the user-typed command, that is currently being edited. char cmd[MAX_COLS]; int cmdInsert; @@ -27,10 +34,12 @@ typedef struct { static const int COLOR_NORMAL = 0; BYTE text[MAX_ROWS][MAX_COLS]; + typedef void LinkFunction(int link, DWORD v); struct { - int color; - int link; - DWORD data; + int color; + int link; + DWORD data; + LinkFunction *f; } meta[MAX_ROWS][MAX_COLS]; int row0, rows; @@ -46,9 +55,10 @@ typedef struct { // These are called by the platform-specific code. void KeyPressed(int c); bool IsHyperlink(int width, int height); -} TextWindow; +}; -typedef struct { +class GraphicsWindow { +public: // This table describes the top-level menus in the graphics winodw. typedef void MenuHandler(int id); typedef struct { @@ -85,7 +95,7 @@ typedef struct { void MouseLeftDoubleClick(double x, double y); void MouseMiddleDown(double x, double y); void MouseScroll(int delta); -} GraphicsWindow; +}; #endif diff --git a/util.cpp b/util.cpp index 3b4806c..547a375 100644 --- a/util.cpp +++ b/util.cpp @@ -24,8 +24,7 @@ void MakeMatrix(double *mat, double a11, double a12, double a13, double a14, } -Vector Vector::Cross(Vector b) -{ +Vector Vector::Cross(Vector b) { Vector r; r.x = -(z*b.y) + (y*b.z); @@ -35,13 +34,11 @@ Vector Vector::Cross(Vector b) return r; } -double Vector::Dot(Vector b) -{ +double Vector::Dot(Vector b) { return (x*b.x + y*b.y + z*b.z); } -Vector Vector::RotatedAbout(Vector axis, double theta) -{ +Vector Vector::RotatedAbout(Vector axis, double theta) { double c = cos(theta); double s = sin(theta); @@ -62,13 +59,11 @@ Vector Vector::RotatedAbout(Vector axis, double theta) return r; } -double Vector::Magnitude(void) -{ +double Vector::Magnitude(void) { return sqrt(x*x + y*y + z*z); } -Vector Vector::ScaledBy(double v) -{ +Vector Vector::ScaledBy(double v) { Vector r; r.x = x * v; @@ -77,4 +72,3 @@ Vector Vector::ScaledBy(double v) return r; } - diff --git a/win32/w32main.cpp b/win32/w32main.cpp index 3fee7a0..9388a1e 100644 --- a/win32/w32main.cpp +++ b/win32/w32main.cpp @@ -25,7 +25,7 @@ HMENU SubMenus[100]; int ClientIsSmallerBy; -HFONT FixedFont; +HFONT FixedFont, LinkFont; void dbp(char *str, ...) { @@ -80,6 +80,15 @@ static void PaintTextWnd(HDC hdc) for(c = 0; c < SS.TW.MAX_COLS; c++) { char v = '0' + (c % 10); + int color = SS.TW.meta[rr][c].color; + SetTextColor(backDc, SS.TW.colors[color].fg); + SetBkColor(backDc, SS.TW.colors[color].bg); + + if(SS.TW.meta[rr][c].link) { + SelectObject(backDc, LinkFont); + } else { + SelectObject(backDc, FixedFont); + } TextOut(backDc, 4 + c*TEXT_WIDTH, (r-TextWndScrollPos)*TEXT_HEIGHT, (char *)&(SS.TW.text[rr][c]), 1); } @@ -107,11 +116,11 @@ void HandleTextWindowScrollBar(WPARAM wParam, LPARAM lParam) { int prevPos = TextWndScrollPos; switch(LOWORD(wParam)) { - case SB_LINEUP: - case SB_PAGEUP: TextWndScrollPos--; break; + case SB_LINEUP: TextWndScrollPos--; break; + case SB_PAGEUP: TextWndScrollPos -= 4; break; - case SB_LINEDOWN: - case SB_PAGEDOWN: TextWndScrollPos++; break; + case SB_LINEDOWN: TextWndScrollPos++; break; + case SB_PAGEDOWN: TextWndScrollPos += 4; break; case SB_TOP: TextWndScrollPos = 0; break; @@ -171,6 +180,30 @@ LRESULT CALLBACK TextWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) break; } + case WM_LBUTTONDOWN: + case WM_MOUSEMOVE: { + int x = LOWORD(lParam); + int y = HIWORD(lParam); + + // Find the corresponding character in the text buffer + int r = (y / TEXT_HEIGHT); + int c = (x / TEXT_WIDTH); + if(msg == WM_MOUSEMOVE && r >= TextWndRows) { + SetCursor(LoadCursor(NULL, IDC_ARROW)); + break; + } + r += TextWndScrollPos; + + if(msg == WM_MOUSEMOVE) { + if(SS.TW.meta[r][c].link) { + SetCursor(LoadCursor(NULL, IDC_HAND)); + } else { + SetCursor(LoadCursor(NULL, IDC_ARROW)); + } + } + break; + } + case WM_CHAR: SS.TW.KeyPressed(wParam); HandleTextWindowScrollBar(SB_BOTTOM, 0); @@ -230,7 +263,6 @@ static HGLRC CreateGlContext(HDC hdc) void Invalidate(void) { InvalidateRect(GraphicsWnd, NULL, FALSE); - InvalidateRect(TextWnd, NULL, FALSE); } LRESULT CALLBACK GraphicsWndProc(HWND hwnd, UINT msg, WPARAM wParam, @@ -375,7 +407,7 @@ static void CreateMainWindows(void) wc.lpfnWndProc = (WNDPROC)TextWndProc; wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wc.lpszClassName = "TextWnd"; - wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hCursor = NULL; if(!RegisterClassEx(&wc)) oops(); // We get the desired Alt+Tab behaviour by specifying that the text @@ -418,8 +450,13 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, FixedFont = CreateFont(TEXT_HEIGHT-1, TEXT_WIDTH, 0, 0, FW_REGULAR, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, "Lucida Console"); + LinkFont = CreateFont(TEXT_HEIGHT-1, TEXT_WIDTH, 0, 0, FW_REGULAR, TRUE, + TRUE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + DEFAULT_QUALITY, FF_DONTCARE, "Lucida Console"); if(!FixedFont) FixedFont = (HFONT)GetStockObject(SYSTEM_FONT); + if(!LinkFont) + LinkFont = (HFONT)GetStockObject(SYSTEM_FONT); // Call in to the platform-independent code, and let them do their init SS.Init();