├── LICENSE.txt ├── README.md ├── dispcalc.c ├── dispcalc.def ├── dispcalc.mak ├── dispcalc.rc ├── dpmath.c ├── dpmath.h └── resource.h /LICENSE.txt: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2004 Sam Hocevar 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | I [wrote an article](https://cmpct.info/~calvin/Articles/Win16.htm) about this, which explains. 2 | 3 | ## Building 4 | 5 | Open the makefile in Visual C++, or run (in an MS-DOS prompt with environment variables set up) 6 | 7 | ``` 8 | nmake /f dispcalc.mak dispcalc.exe 9 | ``` 10 | -------------------------------------------------------------------------------- /dispcalc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "dpmath.h" 5 | #include "resource.h" 6 | 7 | int calcMode = DP_MODE_DIST; 8 | BOOL metric = FALSE; 9 | 10 | char appName[] = "DispCalc"; 11 | char winTitle[] = "Display Calculator"; 12 | /* These are loaded in by LoadString on demand */ 13 | char *dynWinTitle, *aboutText, *errorText; 14 | 15 | /* Make these globals because we'd otherwise use Get* a lot */ 16 | HMENU hmenu; 17 | HWND pxxi, pxyi, ri, si, ai, di, ci, 18 | pxxo, pxyo, ro, so, ppio, dio, ixo, iyo; 19 | HANDLE hinst; 20 | 21 | void PASCAL ChangeSolveMode (hwnd, type) 22 | HWND hwnd; 23 | int type; 24 | { 25 | if (dynWinTitle == NULL) { 26 | dynWinTitle = LocalAlloc (LMEM_FIXED, 255); 27 | LoadString (hinst, IDS_ENTRYERR, dynWinTitle, 255); 28 | } 29 | switch (type) 30 | { 31 | case DP_MODE_DIST: 32 | LoadString (hinst, IDS_TITLE_DIST, dynWinTitle, 255); 33 | calcMode = DP_MODE_DIST; 34 | CheckMenuItem (hmenu, ID_MODE_DISTANCE, MF_CHECKED); 35 | CheckMenuItem (hmenu, ID_MODE_SIZE, MF_UNCHECKED); 36 | CheckMenuItem (hmenu, ID_MODE_RESOLUTION, MF_UNCHECKED); 37 | EnableWindow (pxxi, TRUE); 38 | EnableWindow (pxyi, TRUE); 39 | EnableWindow (ri , FALSE); 40 | EnableWindow (si, TRUE); 41 | EnableWindow (ai, TRUE); 42 | EnableWindow (di, FALSE); 43 | EnableWindow (ci, TRUE); 44 | break; 45 | case DP_MODE_SIZE: 46 | LoadString (hinst, IDS_TITLE_SIZE, dynWinTitle, 255); 47 | calcMode = DP_MODE_SIZE; 48 | CheckMenuItem (hmenu, ID_MODE_DISTANCE, MF_UNCHECKED); 49 | CheckMenuItem (hmenu, ID_MODE_SIZE, MF_CHECKED); 50 | CheckMenuItem (hmenu, ID_MODE_RESOLUTION, MF_UNCHECKED); 51 | EnableWindow (pxxi, TRUE); 52 | EnableWindow (pxyi, TRUE); 53 | EnableWindow (ri , FALSE); 54 | EnableWindow (si, FALSE); 55 | EnableWindow (ai, TRUE); 56 | EnableWindow (di, TRUE); 57 | EnableWindow (ci, TRUE); 58 | break; 59 | case DP_MODE_RES: 60 | LoadString (hinst, IDS_TITLE_RES, dynWinTitle, 255); 61 | calcMode = DP_MODE_RES; 62 | CheckMenuItem (hmenu, ID_MODE_DISTANCE, MF_UNCHECKED); 63 | CheckMenuItem (hmenu, ID_MODE_SIZE, MF_UNCHECKED); 64 | CheckMenuItem (hmenu, ID_MODE_RESOLUTION, MF_CHECKED); 65 | EnableWindow (pxxi, FALSE); 66 | EnableWindow (pxyi, FALSE); 67 | EnableWindow (ri , TRUE); 68 | EnableWindow (si, TRUE); 69 | EnableWindow (ai, TRUE); 70 | EnableWindow (di, TRUE); 71 | EnableWindow (ci, TRUE); 72 | break; 73 | } 74 | SetWindowText (hwnd, dynWinTitle); 75 | } 76 | 77 | BOOL PASCAL GetWindowDouble (hwnd, res) 78 | HWND hwnd; 79 | long double *res; 80 | { 81 | char buf [255]; 82 | buf [0] = '\0'; 83 | GetWindowText (hwnd, buf, 254); 84 | if (buf [0] == '\0') { 85 | return FALSE; 86 | } 87 | /* XXX: strold is more tolerant than it should be; better error checking */ 88 | *res = _strtold (buf, NULL); 89 | return TRUE; 90 | } 91 | 92 | void PASCAL SetWindowDouble (hwnd, d) 93 | HWND hwnd; 94 | long double d; 95 | { 96 | char buf [255]; 97 | _snprintf (buf, 255, "%Lf", d); 98 | SetWindowText (hwnd, buf); 99 | } 100 | 101 | void HandleEntryError (hwnd) 102 | HWND hwnd; 103 | { 104 | if (errorText == NULL) { 105 | errorText = LocalAlloc (LMEM_FIXED, 255); 106 | LoadString (hinst, IDS_ENTRYERR, errorText, 255); 107 | } 108 | MessageBox (hwnd, errorText, winTitle, MB_ICONSTOP); 109 | SetFocus (hwnd); 110 | } 111 | 112 | void PASCAL RunCalculate (hwnd) 113 | HWND hwnd; 114 | { 115 | long double pxx, pxy, pxd, r, s, a, d, c, ppi, inx, iny; 116 | switch (calcMode) 117 | { 118 | case DP_MODE_DIST: 119 | if (!GetWindowDouble (pxxi, &pxx) || pxx <= 0) { 120 | HandleEntryError (pxxi); 121 | return; 122 | } 123 | if (!GetWindowDouble (pxyi, &pxy) || pxy <= 0) { 124 | HandleEntryError (pxyi); 125 | return; 126 | } 127 | if (!GetWindowDouble (si, &s) || s <= 0) { 128 | HandleEntryError (si); 129 | return; 130 | } 131 | if (!GetWindowDouble (ai, &a) || a <= 0) { 132 | HandleEntryError (ai); 133 | return; 134 | } 135 | if (!GetWindowDouble (ci, &c) || c <= 0) { 136 | HandleEntryError (ci); 137 | return; 138 | } 139 | a = AdjustedAcuity (a, c); 140 | r = AspectRatio (pxx, pxy); 141 | ppi = PPI (pxx, pxy, s); //sqrtl (powl (pxx, 2) + powl (pxy, 2)) / s; 142 | d = OneInchDistance (a) * (1 / ppi); 143 | SetWindowDouble (ro, r); 144 | SetWindowDouble (dio, d); 145 | SetWindowDouble (ppio, ppi); 146 | break; 147 | case DP_MODE_SIZE: 148 | if (!GetWindowDouble (pxxi, &pxx) || pxx <= 0) { 149 | HandleEntryError (pxxi); 150 | return; 151 | } 152 | if (!GetWindowDouble (pxyi, &pxy) || pxy <= 0) { 153 | HandleEntryError (pxyi); 154 | return; 155 | } 156 | if (!GetWindowDouble (di, &d) || d <= 0) { 157 | HandleEntryError (di); 158 | return; 159 | } 160 | if (!GetWindowDouble (ai, &a) || a <= 0) { 161 | HandleEntryError (ai); 162 | return; 163 | } 164 | if (!GetWindowDouble (ci, &c) || c <= 0) { 165 | HandleEntryError (ci); 166 | return; 167 | } 168 | a = AdjustedAcuity (a, c); 169 | r = AspectRatio (pxx, pxy); 170 | ppi = OptimalPPI (d, a); 171 | s = DisplaySize (pxx, pxy, ppi); 172 | SetWindowDouble (ro, r); 173 | SetWindowDouble (ppio, ppi); 174 | SetWindowDouble (so, s); 175 | break; 176 | case DP_MODE_RES: 177 | if (!GetWindowDouble (si, &s) || s <= 0) { 178 | HandleEntryError (si); 179 | return; 180 | } 181 | if (!GetWindowDouble (ri, &r) || s <= 0) { 182 | HandleEntryError (ri); 183 | return; 184 | } 185 | if (!GetWindowDouble (di, &d) || d <= 0) { 186 | HandleEntryError (di); 187 | return; 188 | } 189 | if (!GetWindowDouble (ai, &a) || a <= 0) { 190 | HandleEntryError (ai); 191 | return; 192 | } 193 | if (!GetWindowDouble (ci, &c) || c <= 0) { 194 | HandleEntryError (ci); 195 | return; 196 | } 197 | a = AdjustedAcuity (a, c); 198 | ppi = OptimalPPI (d, a); 199 | pxd = DiagResolution(s, ppi);; 200 | pxy = VResFromDiag (pxd, r); 201 | pxx = r * pxy; 202 | SetWindowDouble (pxxo, pxx); 203 | SetWindowDouble (pxyo, pxy); 204 | SetWindowDouble (ppio, ppi); 205 | break; 206 | } 207 | iny = PhysVRes (s, r); 208 | inx = r * iny; 209 | if (metric) { 210 | inx *= 25.4; 211 | iny *= 25.4; 212 | } 213 | SetWindowDouble (ixo, inx); 214 | SetWindowDouble (iyo, iny); 215 | } 216 | 217 | BOOL PASCAL ProcessDialogCommand (hwnd, cmd) 218 | HWND hwnd; 219 | WORD cmd; 220 | { 221 | UINT metricState; 222 | 223 | switch (cmd) 224 | { 225 | case IDOK: 226 | RunCalculate (hwnd); 227 | return TRUE; 228 | case ID_HELP_ABOUT: 229 | if (aboutText == NULL) { 230 | aboutText = LocalAlloc (LMEM_FIXED, 255); 231 | LoadString (hinst, IDS_ABOUTTEXT, aboutText, 255); 232 | } 233 | MessageBox (hwnd, aboutText, winTitle, 0); 234 | return TRUE; 235 | case ID_MODE_DISTANCE: 236 | ChangeSolveMode (hwnd, DP_MODE_DIST); 237 | return TRUE; 238 | case ID_MODE_SIZE: 239 | ChangeSolveMode (hwnd, DP_MODE_SIZE); 240 | return TRUE; 241 | case ID_MODE_RESOLUTION: 242 | ChangeSolveMode (hwnd, DP_MODE_RES); 243 | return TRUE; 244 | case ID_MODE_METRICPHYSICALDIMENSION: 245 | metricState = GetMenuState (hmenu, 246 | ID_MODE_METRICPHYSICALDIMENSION, MF_BYCOMMAND); 247 | /* toggle it */ 248 | metric = !(metricState & MF_CHECKED); 249 | CheckMenuItem (hmenu, ID_MODE_METRICPHYSICALDIMENSION, 250 | metric ? MF_CHECKED : MF_UNCHECKED); 251 | return TRUE; 252 | default: 253 | return FALSE; 254 | } 255 | } 256 | 257 | void PASCAL InitializeChildHandles (hwnd) 258 | HWND hwnd; 259 | { 260 | hmenu = GetMenu (hwnd); 261 | pxxi = GetDlgItem (hwnd, IDC_PIXDEM_X_IN); 262 | pxyi = GetDlgItem (hwnd, IDC_PIXDEM_Y_IN); 263 | ri = GetDlgItem (hwnd, IDC_RATIO_IN); 264 | si = GetDlgItem (hwnd, IDC_SIZE_IN); 265 | ai = GetDlgItem (hwnd, IDC_ACUITY_IN); 266 | di = GetDlgItem (hwnd, IDC_DISTANCE_IN); 267 | ci = GetDlgItem (hwnd, IDC_CYCLES_IN); 268 | pxxo = GetDlgItem (hwnd, IDC_PIXDEM_X_OUT); 269 | pxyo = GetDlgItem (hwnd, IDC_PIXDEM_Y_OUT); 270 | ro = GetDlgItem (hwnd, IDC_RATIO_OUT); 271 | so = GetDlgItem (hwnd, IDC_SIZE_OUT); 272 | ppio = GetDlgItem (hwnd, IDC_PPI_OUT); 273 | dio = GetDlgItem (hwnd, IDC_DISTANCE_OUT); 274 | ixo = GetDlgItem (hwnd, IDC_PHYSDEM_X_OUT); 275 | iyo = GetDlgItem (hwnd, IDC_PHYSDEM_Y_OUT); 276 | } 277 | 278 | BOOL FAR PASCAL DialogProc (hwnd, iMsg, wParam, lParam) 279 | HWND hwnd; 280 | unsigned int iMsg; 281 | WORD wParam; 282 | LONG lParam; 283 | { 284 | switch (iMsg) 285 | { 286 | case WM_INITDIALOG: 287 | InitializeChildHandles (hwnd); 288 | ChangeSolveMode (hwnd, DP_MODE_DIST); 289 | SetDlgItemText (hwnd, IDC_ACUITY_IN, "20"); 290 | SetDlgItemText (hwnd, IDC_CYCLES_IN, "30"); 291 | return TRUE; 292 | /* TODO: Process Key events for auto-updating. */ 293 | case WM_COMMAND: 294 | return ProcessDialogCommand (hwnd, wParam); 295 | case WM_CLOSE: 296 | DestroyWindow (hwnd); 297 | return TRUE; 298 | case WM_DESTROY: 299 | PostQuitMessage (NULL); 300 | return TRUE; 301 | default: 302 | return FALSE; 303 | } 304 | } 305 | 306 | int PASCAL WinMain (hInstance, hPrevInst, lpszCmdLine, nCmdShow) 307 | HANDLE hInstance, hPrevInst; 308 | LPSTR lpszCmdLine; 309 | int nCmdShow; 310 | { 311 | int ret; 312 | HWND hwnd; 313 | FARPROC dlgProc; 314 | MSG msg; 315 | 316 | hinst = hInstance; 317 | 318 | if ((dlgProc = MakeProcInstance (DialogProc, hInstance)) == NULL) { 319 | MessageBox (NULL, "There was an error creating the dialog procedure.", winTitle, MB_ICONSTOP); 320 | return 1; 321 | } 322 | /* The API is a filthy liar for Win16. The template name is an ID, NOT a string. */ 323 | if ((hwnd = CreateDialogParam (hInstance, MainDialog, NULL, dlgProc, 0)) == NULL) { 324 | MessageBox (NULL, "There was an error creating the dialog window.", winTitle, MB_ICONSTOP); 325 | return 2; 326 | } 327 | EnableWindow (hwnd, TRUE); 328 | ShowWindow (hwnd, nCmdShow); 329 | 330 | while (GetMessage (&msg, NULL, 0, 0)) { 331 | if (!IsDialogMessage (hwnd, &msg)) { 332 | TranslateMessage (&msg); 333 | DispatchMessage (&msg); 334 | } 335 | } 336 | FreeProcInstance (dlgProc); 337 | 338 | return ret; 339 | } -------------------------------------------------------------------------------- /dispcalc.def: -------------------------------------------------------------------------------- 1 | NAME DISPCALC 2 | EXETYPE WINDOWS 3 | CODE PRELOAD MOVEABLE DISCARDABLE 4 | DATA PRELOAD MOVEABLE MULTIPLE 5 | HEAPSIZE 1024 6 | 7 | EXPORTS 8 | ; ===List your explicitly exported functions here=== 9 | -------------------------------------------------------------------------------- /dispcalc.mak: -------------------------------------------------------------------------------- 1 | # Microsoft Visual C++ generated build script - Do not modify 2 | 3 | PROJ = DISPCALC 4 | DEBUG = 1 5 | PROGTYPE = 0 6 | CALLER = 7 | ARGS = 8 | DLLS = 9 | D_RCDEFINES = -d_DEBUG 10 | R_RCDEFINES = -dNDEBUG 11 | ORIGIN = MSVC 12 | ORIGIN_VER = 1.00 13 | PROJPATH = C:\MYDOCU~1\DISPCALC\ 14 | USEMFC = 1 15 | CC = cl 16 | CPP = cl 17 | CXX = cl 18 | CCREATEPCHFLAG = 19 | CPPCREATEPCHFLAG = 20 | CUSEPCHFLAG = 21 | CPPUSEPCHFLAG = 22 | FIRSTC = 23 | FIRSTCPP = 24 | RC = rc 25 | CFLAGS_D_WEXE = /nologo /W3 /FR /G2 /Zi /D_DEBUG /Od /AM /GA /Fd"DISPCALC.PDB" 26 | CFLAGS_R_WEXE = /nologo /W3 /FR /O1 /DNDEBUG /AM /GA 27 | LFLAGS_D_WEXE = /NOLOGO /ONERROR:NOEXE /NOD /PACKC:61440 /CO /ALIGN:16 /STACK:10240 28 | LFLAGS_R_WEXE = /NOLOGO /ONERROR:NOEXE /NOD /PACKC:61440 /ALIGN:16 /STACK:10240 29 | LIBS_D_WEXE = mafxcwd oldnames libw commdlg shell olecli olesvr mlibcew 30 | LIBS_R_WEXE = mafxcw oldnames libw commdlg shell olecli olesvr mlibcew 31 | RCFLAGS = /nologo 32 | RESFLAGS = /nologo 33 | RUNFLAGS = 34 | DEFFILE = DISPCALC.DEF 35 | OBJS_EXT = 36 | LIBS_EXT = 37 | !if "$(DEBUG)" == "1" 38 | CFLAGS = $(CFLAGS_D_WEXE) 39 | LFLAGS = $(LFLAGS_D_WEXE) 40 | LIBS = $(LIBS_D_WEXE) 41 | MAPFILE = nul 42 | RCDEFINES = $(D_RCDEFINES) 43 | !else 44 | CFLAGS = $(CFLAGS_R_WEXE) 45 | LFLAGS = $(LFLAGS_R_WEXE) 46 | LIBS = $(LIBS_R_WEXE) 47 | MAPFILE = nul 48 | RCDEFINES = $(R_RCDEFINES) 49 | !endif 50 | !if [if exist MSVC.BND del MSVC.BND] 51 | !endif 52 | SBRS = DISPCALC.SBR \ 53 | DPMATH.SBR 54 | 55 | 56 | DISPCALC_DEP = c:\mydocu~1\dispcalc\dpmath.h 57 | 58 | 59 | DPMATH_DEP = 60 | 61 | all: $(PROJ).EXE $(PROJ).BSC 62 | 63 | DISPCALC.OBJ: DISPCALC.C $(DISPCALC_DEP) 64 | $(CC) $(CFLAGS) $(CUSEPCHFLAG) /c DISPCALC.C 65 | 66 | DISPCALC.RES: DISPCALC.RC $(DISPCALC_RCDEP) 67 | $(RC) $(RCFLAGS) $(RCDEFINES) -r DISPCALC.RC 68 | 69 | DPMATH.OBJ: DPMATH.C $(DPMATH_DEP) 70 | $(CC) $(CFLAGS) $(CUSEPCHFLAG) /c DPMATH.C 71 | 72 | 73 | $(PROJ).EXE:: DISPCALC.RES 74 | 75 | $(PROJ).EXE:: DISPCALC.OBJ DPMATH.OBJ $(OBJS_EXT) $(DEFFILE) 76 | echo >NUL @<<$(PROJ).CRF 77 | DISPCALC.OBJ + 78 | DPMATH.OBJ + 79 | $(OBJS_EXT) 80 | $(PROJ).EXE 81 | $(MAPFILE) 82 | c:\msvc\lib\+ 83 | c:\msvc\mfc\lib\+ 84 | $(LIBS) 85 | $(DEFFILE); 86 | << 87 | link $(LFLAGS) @$(PROJ).CRF 88 | $(RC) $(RESFLAGS) DISPCALC.RES $@ 89 | @copy $(PROJ).CRF MSVC.BND 90 | 91 | $(PROJ).EXE:: DISPCALC.RES 92 | if not exist MSVC.BND $(RC) $(RESFLAGS) DISPCALC.RES $@ 93 | 94 | run: $(PROJ).EXE 95 | $(PROJ) $(RUNFLAGS) 96 | 97 | 98 | $(PROJ).BSC: $(SBRS) 99 | bscmake @<< 100 | /o$@ $(SBRS) 101 | << 102 | -------------------------------------------------------------------------------- /dispcalc.rc: -------------------------------------------------------------------------------- 1 | //Microsoft App Studio generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "afxres.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | 16 | ////////////////////////////////////////////////////////////////////////////// 17 | // 18 | // Dialog 19 | // 20 | 21 | MainDialog DIALOG PRELOAD DISCARDABLE 0, 0, 216, 133 22 | STYLE WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU 23 | CAPTION "Display Calculator" 24 | MENU IDR_MENU1 25 | FONT 8, "MS Sans Serif" 26 | BEGIN 27 | DEFPUSHBUTTON "Calculate",IDOK,56,112,50,14 28 | LTEXT "&Pixel Dimensions (W/H)",IDC_STATIC,5,6,51,26 29 | EDITTEXT IDC_PIXDEM_X_IN,57,6,49,12,ES_AUTOHSCROLL 30 | EDITTEXT IDC_PIXDEM_Y_IN,57,20,49,12,ES_AUTOHSCROLL 31 | LTEXT "Aspect &Ratio",IDC_STATIC,5,35,50,11 32 | EDITTEXT IDC_RATIO_IN,57,35,49,12,ES_AUTOHSCROLL 33 | LTEXT "&Size in inches",IDC_STATIC,5,50,50,16 34 | EDITTEXT IDC_SIZE_IN,57,50,49,12,ES_AUTOHSCROLL 35 | LTEXT "Visual &Acuity",IDC_STATIC,5,65,50,16 36 | EDITTEXT IDC_ACUITY_IN,57,65,49,12,ES_AUTOHSCROLL 37 | LTEXT "&Distance in inches",IDC_STATIC,5,80,50,16 38 | EDITTEXT IDC_DISTANCE_IN,57,80,49,12,ES_AUTOHSCROLL 39 | LTEXT "&Cycles per degree",IDC_STATIC,5,96,51,16 40 | EDITTEXT IDC_CYCLES_IN,57,95,49,12,ES_AUTOHSCROLL 41 | LTEXT "Pixel Dimensions (W/H)",IDC_STATIC,111,6,51,26 42 | EDITTEXT IDC_PIXDEM_X_OUT,163,6,49,12,ES_AUTOHSCROLL | 43 | ES_READONLY | NOT WS_TABSTOP 44 | EDITTEXT IDC_PIXDEM_Y_OUT,163,20,49,12,ES_AUTOHSCROLL | 45 | ES_READONLY | NOT WS_TABSTOP 46 | LTEXT "Aspect Ratio",IDC_STATIC,111,35,50,13 47 | EDITTEXT IDC_RATIO_OUT,163,35,49,12,ES_AUTOHSCROLL | ES_READONLY | 48 | NOT WS_TABSTOP 49 | LTEXT "Size in inches",IDC_STATIC,111,49,50,16 50 | EDITTEXT IDC_SIZE_OUT,163,49,49,12,ES_AUTOHSCROLL | ES_READONLY | 51 | NOT WS_TABSTOP 52 | LTEXT "Pixels per inch",IDC_STATIC,111,64,50,16 53 | EDITTEXT IDC_PPI_OUT,163,64,49,12,ES_AUTOHSCROLL | ES_READONLY | 54 | NOT WS_TABSTOP 55 | LTEXT "Distance in inches",IDC_STATIC,111,79,50,16 56 | EDITTEXT IDC_DISTANCE_OUT,163,79,49,12,ES_AUTOHSCROLL | 57 | ES_READONLY | NOT WS_TABSTOP 58 | LTEXT "Physical dimensions ",IDC_STATIC,111,95,51,16 59 | EDITTEXT IDC_PHYSDEM_X_OUT,163,93,49,12,ES_AUTOHSCROLL | 60 | ES_READONLY | NOT WS_TABSTOP 61 | EDITTEXT IDC_PHYSDEM_Y_OUT,163,107,49,12,ES_AUTOHSCROLL | 62 | ES_READONLY | NOT WS_TABSTOP 63 | END 64 | 65 | 66 | ////////////////////////////////////////////////////////////////////////////// 67 | // 68 | // Menu 69 | // 70 | 71 | IDR_MENU1 MENU DISCARDABLE 72 | BEGIN 73 | POPUP "&Mode" 74 | BEGIN 75 | MENUITEM "&Distance", ID_MODE_DISTANCE 76 | MENUITEM "&Size", ID_MODE_SIZE 77 | MENUITEM "&Resolution", ID_MODE_RESOLUTION 78 | MENUITEM SEPARATOR 79 | MENUITEM "Metric Physical Dimension", ID_MODE_METRICPHYSICALDIMENSION 80 | 81 | END 82 | POPUP "&Help", HELP 83 | BEGIN 84 | MENUITEM "&About", ID_HELP_ABOUT 85 | END 86 | END 87 | 88 | #ifdef APSTUDIO_INVOKED 89 | ////////////////////////////////////////////////////////////////////////////// 90 | // 91 | // TEXTINCLUDE 92 | // 93 | 94 | 1 TEXTINCLUDE DISCARDABLE 95 | BEGIN 96 | "resource.h\0" 97 | END 98 | 99 | 2 TEXTINCLUDE DISCARDABLE 100 | BEGIN 101 | "#include ""afxres.h""\r\n" 102 | "\0" 103 | END 104 | 105 | 3 TEXTINCLUDE DISCARDABLE 106 | BEGIN 107 | "\r\n" 108 | "\0" 109 | END 110 | 111 | ///////////////////////////////////////////////////////////////////////////////////// 112 | #endif // APSTUDIO_INVOKED 113 | 114 | 115 | ////////////////////////////////////////////////////////////////////////////// 116 | // 117 | // String Table 118 | // 119 | 120 | STRINGTABLE PRELOAD DISCARDABLE 121 | BEGIN 122 | IDS_ABOUTTEXT "Display Calculator for Windows (Licensed under WTFPL, written in JS by Eric Rucker, translated to Windows/C by Calvin Buckley)" 123 | IDS_ENTRYERR "There was an invalid number entered." 124 | IDS_TITLE_DIST "Display Calculator (Distance)" 125 | IDS_TITLE_SIZE "Display Calculator (Size)" 126 | IDS_TITLE_RES "Display Calculator (Resolution)" 127 | END 128 | 129 | 130 | #ifndef APSTUDIO_INVOKED 131 | //////////////////////////////////////////////////////////////////////////////// 132 | // 133 | // Generated from the TEXTINCLUDE 3 resource. 134 | // 135 | 136 | 137 | ///////////////////////////////////////////////////////////////////////////////////// 138 | #endif // not APSTUDIO_INVOKED 139 | 140 | -------------------------------------------------------------------------------- /dpmath.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | long double AspectRatio (h, v) 4 | long double h, v; 5 | { 6 | return h / v; 7 | } 8 | 9 | long double OneInchDistance (acuity) 10 | long double acuity; 11 | { 12 | return 1 / ((acuity / 20) / 3438); 13 | } 14 | 15 | long double PPI (h, v, size) 16 | long double h, v, size; /* h/v in pixels, size in inches */ 17 | { 18 | return sqrtl (powl (h, 2) + powl (v, 2)) / size; 19 | } 20 | 21 | long double DiagResolution (size, ppi) 22 | long double size, ppi; 23 | { 24 | return powl (size * ppi, 2); 25 | } 26 | 27 | long double VResFromDiag (d, r) 28 | long double d, r; 29 | { 30 | return sqrtl (d / (powl (r, 2) + 1)); 31 | } 32 | 33 | long double PhysVRes (s, r) 34 | long double s, r; 35 | { 36 | return sqrtl (powl (s, 2) / ((powl (r, 2)) + 1)); 37 | } 38 | 39 | long double DisplaySize (h, v, ppi) 40 | long double h, v, ppi; 41 | { 42 | return sqrtl (powl (h, 2) + powl (v, 2)) / ppi; 43 | } 44 | 45 | long double OptimalPPI (distance, acuity) 46 | long double distance, acuity; 47 | { 48 | return (1 / distance) * OneInchDistance (acuity); 49 | } 50 | 51 | long double AdjustedAcuity (acuity, cycles) 52 | long double acuity, cycles; 53 | { 54 | return acuity / (cycles / 30); 55 | } -------------------------------------------------------------------------------- /dpmath.h: -------------------------------------------------------------------------------- 1 | #define DP_MODE_DIST 1 2 | #define DP_MODE_SIZE 2 3 | #define DP_MODE_RES 3 4 | 5 | long double AspectRatio (long double, long double); 6 | long double OneInchDistance (long double); 7 | long double PPI (long double, long double, long double); 8 | long double DisplaySize (long double, long double, long double); 9 | long double DiagResolution (long double, long double); 10 | long double VResFromDiag (long double, long double); 11 | long double PhysVRes (long double, long double); 12 | long double OptimalPPI (long double, long double); 13 | long double AdjustedAcuity (long double, long double); -------------------------------------------------------------------------------- /resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // App Studio generated include file. 3 | // Used by DISPCALC.RC 4 | // 5 | #define IDS_ABOUTTEXT 1 6 | #define IDS_ENTRYERR 2 7 | #define IDS_TITLE_DIST 3 8 | #define IDS_TITLE_SIZE 4 9 | #define IDS_TITLE_RES 5 10 | #define IDD_MAINWIN 101 11 | #define MainDialog 101 12 | #define IDR_MENU1 102 13 | #define IDC_PIXDEM_X_IN 1000 14 | #define IDC_PIXDEM_X_OUT 1001 15 | #define IDC_PIXDEM_Y_IN 1002 16 | #define IDC_RATIO_IN 1003 17 | #define IDC_SIZE_IN 1004 18 | #define IDC_ACUITY_IN 1005 19 | #define IDC_DISTANCE_IN 1006 20 | #define IDC_CYCLES_IN 1007 21 | #define IDC_PIXDEM_Y_OUT 1008 22 | #define IDC_RATIO_OUT 1009 23 | #define IDC_SIZE_OUT 1010 24 | #define IDC_PPI_OUT 1011 25 | #define IDC_DISTANCE_OUT 1012 26 | #define IDC_PHYSDEM_X_OUT 1013 27 | #define IDC_PHYSDEM_Y_OUT 1014 28 | #define ID_MODE_DISTANCE 40001 29 | #define ID_HELP_ABOUT 40002 30 | #define ID_MODE_SIZE 40003 31 | #define ID_MODE_RESOLUTION 40004 32 | #define ID_MODE_METRICPHYSICALDIMENSION 40005 33 | #define IDC_STATIC -1 34 | 35 | // Next default values for new objects 36 | // 37 | #ifdef APSTUDIO_INVOKED 38 | #ifndef APSTUDIO_READONLY_SYMBOLS 39 | 40 | #define _APS_NEXT_RESOURCE_VALUE 103 41 | #define _APS_NEXT_COMMAND_VALUE 40006 42 | #define _APS_NEXT_CONTROL_VALUE 1001 43 | #define _APS_NEXT_SYMED_VALUE 101 44 | #endif 45 | #endif 46 | --------------------------------------------------------------------------------