diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6db035b --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +Debug/ +Release/ diff --git a/BehaviorDialog.cpp b/BehaviorDialog.cpp new file mode 100644 index 0000000..bda6ae6 --- /dev/null +++ b/BehaviorDialog.cpp @@ -0,0 +1,274 @@ +//========================================================================== +// +// File: BehaviorDialog.cpp +// +//========================================================================== + +#include +#include +#include + +#include "SaverSettings.h" +#include "TransparentBitmap.h" +#include "resource.h" +#include "resource.hm" + +extern SaverSettings* ss; +extern HINSTANCE hInstance; + +#define BMPMONITOR_WIDTH 184 +#define BMPMONITOR_HEIGHT 169 + +#define BMPBUTTON_WIDTH 25 +#define BMPBUTTON_HEIGHT 23 + +static const DWORD aHelpIDs[] = +{ + IDC_ABOUT, HIDC_ABOUT, + IDC_SWING, HIDC_SWING, + IDC_USEMOUSE, HIDC_USEMOUSE, + IDC_BACK, HIDC_BACK, + IDC_QUICK, HIDC_QUICK, + IDC_EDIT1, HIDC_SPIN1, + IDC_SPIN1, HIDC_SPIN1, + IDC_MONITOR, HIDC_COLOR1, + IDC_COLOR1, HIDC_COLOR1, + IDC_COLOR2, HIDC_COLOR1, + IDC_COLOR3, HIDC_COLOR1, + IDC_COLOR4, HIDC_COLOR1, + 0, 0 +}; + +/****************************************************************************/ +// +// Process the messages for the 'About' dialog. +// +BOOL FAR PASCAL +AboutDialogProc(HWND win, UINT msg, WPARAM wparam, LONG lparam) +{ + // Check the message + switch (msg) + { + // If we received an InitDialog message, just return true + case WM_INITDIALOG: + return TRUE; + + // If we received an OK button selection, + // close the dialog and return true + case WM_COMMAND: + if (wparam == IDOK) + { + EndDialog(win, TRUE); + return TRUE; + } + break; + } + // Otherwise, return false + return FALSE; +} + +/****************************************************************************/ +// +// Process the messages for the 'Behavior' dialog. +// +BOOL APIENTRY +BehaviorDialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + int i; + int nBtnCoordx[] = { 20, 140, 140, 20 }; + int nBtnCoordy[] = { 21, 21, 103, 103 }; + char chNum[10]; + HWND hspin, hedit; + HWND hstb; + HWND hmonitor; + HBITMAP hbmpmonitor; + HGDIOBJ holdbmp; + RECT rectBmp, rectDlg; + + switch (msg) + { + case WM_INITDIALOG: + hmonitor = GetDlgItem(hwnd, IDC_MONITOR); + GetWindowRect(hwnd, &rectDlg); + GetWindowRect(hmonitor, &rectBmp); + rectBmp.top -= rectDlg.top; + rectBmp.left -= rectDlg.left; + MoveWindow(hmonitor, + rectBmp.left, rectBmp.top, + BMPMONITOR_WIDTH, BMPMONITOR_HEIGHT, TRUE + ); + for (i=0; i < 4; i++) + { + hstb = GetDlgItem(hwnd, IDC_COLOR1+i); + MoveWindow(hstb, + nBtnCoordx[i] + rectBmp.left, + nBtnCoordy[i] + rectBmp.top, + BMPBUTTON_WIDTH, BMPBUTTON_HEIGHT, TRUE + ); + } + return TRUE; + + case WM_DRAWITEM: + { + LPDRAWITEMSTRUCT lpdis; + lpdis = (LPDRAWITEMSTRUCT)lParam; + if (lpdis->CtlType == ODT_BUTTON) + { + HPEN hpen1, hpen2; + HBRUSH hbrush; + HGDIOBJ holdpen, holdbrush; + POINT points[3]; + int nR, nG, nB; + + if (lpdis->CtlID == IDC_MONITOR) + { + hbmpmonitor = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_MONITOR2)); + holdbmp = SelectObject(lpdis->hDC, hbmpmonitor); + DrawTransparentBitmap(lpdis->hDC, hbmpmonitor, 0, 0, RGB(255, 0, 0)); + SelectObject(lpdis->hDC, holdbmp); + DeleteObject(hbmpmonitor); + for (i=0; i < 4; i++) + { + hstb = GetDlgItem(hwnd, IDC_COLOR1+i); + InvalidateRect(hstb, NULL, FALSE); + } + return TRUE; + } + else if ( (lpdis->CtlID >= IDC_COLOR1) && (lpdis->CtlID <= IDC_COLOR4) ) + { + i = lpdis->CtlID - IDC_COLOR1; + nR = (int)(255 * ss->state.fColorR[i]); + nG = (int)(255 * ss->state.fColorG[i]); + nB = (int)(255 * ss->state.fColorB[i]); + + hpen1 = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW)); + hpen2 = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DHILIGHT)); + hbrush = CreateSolidBrush(RGB(nR, nG, nB)); + holdpen = SelectObject(lpdis->hDC, hpen1); + holdbrush = SelectObject(lpdis->hDC, hbrush); + Rectangle(lpdis->hDC, + lpdis->rcItem.left, lpdis->rcItem.top, + lpdis->rcItem.right, lpdis->rcItem.bottom + ); + SelectObject(lpdis->hDC, hpen2); + points[0].x = lpdis->rcItem.left-1; + points[0].y = points[1].y = lpdis->rcItem.bottom - 1; + points[1].x = points[2].x = lpdis->rcItem.right-1; + points[2].y = lpdis->rcItem.top - 1; + Polyline(lpdis->hDC, points, 3); + SelectObject(lpdis->hDC, holdpen); + SelectObject(lpdis->hDC, holdbrush); + DeleteObject(hpen1); + DeleteObject(hpen2); + DeleteObject(hbrush); + + return TRUE; + } + } + } + break; + + case WM_NOTIFY: + switch (((NMHDR FAR *) lParam)->code) + { + case PSN_SETACTIVE: + CheckDlgButton(hwnd, IDC_QUICK, ss->state.bQuick); + CheckDlgButton(hwnd, IDC_SWING, ss->state.bSwing); + CheckDlgButton(hwnd, IDC_USEMOUSE, ss->state.bUseMouse); + CheckDlgButton(hwnd, IDC_BACK, !ss->state.bBlackBackground); + hedit = GetDlgItem(hwnd, IDC_EDIT1); + hspin = GetDlgItem(hwnd, IDC_SPIN1); + sprintf(chNum, "%d", ss->state.nTwists); + SendMessage(hedit, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)chNum); + SendMessage(hspin, UDM_SETRANGE, 0L, MAKELONG(9, 0)); + SendMessage(hspin, UDM_SETPOS, 0L, MAKELONG(ss->state.nTwists, 0)); + break; + + case PSN_KILLACTIVE: + { + DWORD nSpinSel; + hspin = GetDlgItem(hwnd, IDC_SPIN1); + nSpinSel = SendMessage(hspin, UDM_GETPOS, 0, 0L); + ss->state.nTwists = LOWORD(nSpinSel); + ss->state.bQuick = IsDlgButtonChecked(hwnd, IDC_QUICK); + ss->state.bSwing = IsDlgButtonChecked(hwnd, IDC_SWING); + ss->state.bUseMouse = IsDlgButtonChecked(hwnd, IDC_USEMOUSE); + ss->state.bBlackBackground = !IsDlgButtonChecked(hwnd, IDC_BACK); + SetWindowLong(hwnd, DWL_MSGRESULT, FALSE); + return TRUE; + } + break; + + case PSN_RESET: + SetWindowLong(hwnd, DWL_MSGRESULT, FALSE); + return TRUE; + break; + + case PSN_APPLY: + ss->WriteBehaviorRegistry(); + SetWindowLong(hwnd, DWL_MSGRESULT, FALSE); + break; + } + break; + + case WM_COMMAND: + { + int id = LOWORD(wParam); + BOOL bStatus; + CHOOSECOLOR chooseColor; + int nR, nG, nB; + if ( (id >= IDC_COLOR1) && (id <= IDC_COLOR4) ) + { + i = id - IDC_COLOR1; + nR = (int)(255 * ss->state.fColorR[i]); + nG = (int)(255 * ss->state.fColorG[i]); + nB = (int)(255 * ss->state.fColorB[i]); + chooseColor.lStructSize = sizeof(CHOOSECOLOR); + chooseColor.hwndOwner = hwnd; + chooseColor.rgbResult = RGB(nR, nG, nB); + chooseColor.lpCustColors = ss->customColors; + chooseColor.Flags = CC_ANYCOLOR | CC_RGBINIT | CC_FULLOPEN; + chooseColor.lpfnHook = NULL; + chooseColor.lpTemplateName = NULL; + bStatus = ChooseColor(&chooseColor); + if (bStatus) + { + nR = GetRValue(chooseColor.rgbResult); + nG = GetGValue(chooseColor.rgbResult); + nB = GetBValue(chooseColor.rgbResult); + ss->state.fColorR[i] = (float)nR / 255.0f; + ss->state.fColorG[i] = (float)nG / 255.0f; + ss->state.fColorB[i] = (float)nB / 255.0f; + hstb = GetDlgItem(hwnd, id); + InvalidateRect(hstb, NULL, FALSE); + } + } + else if (id == IDC_ABOUT) + { + DialogBox( + hInstance, MAKEINTRESOURCE(IDD_ABOUT), + hwnd, AboutDialogProc + ); + } + } + break; + + case WM_HELP: + { + LPHELPINFO lphi = (LPHELPINFO)lParam; + if (lphi->iContextType == HELPINFO_WINDOW) + { + WinHelp((HWND)lphi->hItemHandle, "Moebius Clock.hlp", HELP_WM_HELP, (DWORD)(LPSTR)aHelpIDs); + } + return TRUE; + } + break; + + case WM_CONTEXTMENU: + WinHelp((HWND)wParam, "Moebius Clock.hlp", HELP_CONTEXTMENU, (DWORD)(LPVOID)aHelpIDs); + return TRUE; + break; + } + return FALSE; +} + diff --git a/Debug.h b/Debug.h new file mode 100644 index 0000000..9651ce4 --- /dev/null +++ b/Debug.h @@ -0,0 +1,17 @@ +//========================================================================== +// +// File: Debug.h +// +//========================================================================== + +#ifndef DEBUG_H +#define DEBUG_H + +#ifndef DEBUG +#define DEBUG FALSE +#endif + +void Debug(char *); + +#endif + diff --git a/Dialogs.h b/Dialogs.h new file mode 100644 index 0000000..f9cdaee --- /dev/null +++ b/Dialogs.h @@ -0,0 +1,25 @@ +//========================================================================== +// +// File: Dialogs.h +// +//========================================================================== + +#ifndef DIALOGS_H +#define DIALOGS_H + +#include + +/****************************************************************************/ + +BOOL APIENTRY +GeneralDialogProc(HWND win, UINT msg, UINT wparam, LONG lparam); + +BOOL APIENTRY +GraphicConfigDialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + +BOOL APIENTRY +BehaviorDialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + +/****************************************************************************/ + +#endif diff --git a/GeneralDialog.cpp b/GeneralDialog.cpp new file mode 100644 index 0000000..96f98be --- /dev/null +++ b/GeneralDialog.cpp @@ -0,0 +1,286 @@ +//========================================================================== +// +// File: GeneralDialog.cpp +// +//========================================================================== + +#include +#include +#include + +#include "SaverSettings.h" +#include "TransparentBitmap.h" +#include "HotCorners.h" +#include "resource.h" +#include "resource.hm" + +extern SaverSettings* ss; +extern HINSTANCE hInstance; + +#define BMPMONITOR_WIDTH 184 +#define BMPMONITOR_HEIGHT 169 + +#define BMPBUTTON_WIDTH 25 +#define BMPBUTTON_HEIGHT 23 + +static bool firstTime = true; + +static const DWORD aHelpIDs[] = +{ + ID_MUTE, HID_MUTE, + ID_THRESHOLD, HID_THRESHOLD, + ID_WAITBOX, HID_WAITBOX, + ID_WAITBUDDY, HID_WAITTEXT, + ID_WAITTEXT, HID_WAITTEXT, + IDC_UL, HIDC_UL, + IDC_UR, HIDC_UL, + IDC_DL, HIDC_UL, + IDC_DR, HIDC_UL, + IDC_MONITOR, HIDC_UL, + 0, 0 +}; + +/****************************************************************************/ +// +// Process the messages for the 'General' dialog. +// +BOOL APIENTRY +GeneralDialogProc(HWND win, UINT msg, UINT wparam, LONG lparam) +{ + HWND hstaticOK, hstaticBad; + HWND hmute; + HWND hcomboTh; + HWND hstaticPasswd, hbuddyPasswd, htextPasswd, hcomboPasswd; + HWND hstb; + HWND hmonitor; + static HBITMAP hbcheck=0, hbdot=0, hbnone=0; + HBITMAP hbmpmonitor; + HGDIOBJ holdbmp; + HANDLE hbuttonim; + DWORD nText; + char achNum[10]; + RECT rectBmp, rectDlg; + int nBtnCoordx[] = { 17, 143, 143, 17 }; + int nBtnCoordy[] = { 18, 18, 106, 106 }; + int nComboSel, i; + DWORD nSpinSel; + + // Check the message + switch (msg) + { + // If we received an InitDialog message, just return true + case WM_INITDIALOG: + hmonitor = GetDlgItem(win, IDC_MONITOR); + GetWindowRect(win, &rectDlg); + GetWindowRect(hmonitor, &rectBmp); + rectBmp.top -= rectDlg.top; + rectBmp.left -= rectDlg.left; + MoveWindow(hmonitor, + rectBmp.left, rectBmp.top, + BMPMONITOR_WIDTH, BMPMONITOR_HEIGHT, TRUE + ); + return TRUE; + + case WM_DRAWITEM: + { + LPDRAWITEMSTRUCT lpdis; + lpdis = (LPDRAWITEMSTRUCT)lparam; + if (lpdis->CtlType == ODT_BUTTON) + { + hbmpmonitor = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_MONITOR)); + holdbmp = SelectObject(lpdis->hDC, hbmpmonitor); + DrawTransparentBitmap(lpdis->hDC, hbmpmonitor, 0, 0, RGB(255, 0, 0)); + SelectObject(lpdis->hDC, holdbmp); + DeleteObject(hbmpmonitor); + for (i=0; i < 4; i++) + { + hstb = GetDlgItem(win, IDC_UL+i); + InvalidateRect(hstb, NULL, FALSE); + } + return TRUE; + } + } + break; + + case WM_NOTIFY: + switch (((NMHDR FAR *) lparam)->code) + { + case PSN_SETACTIVE: + hstaticOK = GetDlgItem(win, ID_SAGEOK); + hstaticBad = GetDlgItem(win, ID_SAGEBAD); + hmute = GetDlgItem(win, ID_MUTE); + hcomboTh = GetDlgItem(win, ID_THRESHOLD); + hstaticPasswd = GetDlgItem(win, ID_WAITSUMMARY); + hbuddyPasswd = GetDlgItem(win, ID_WAITBUDDY); + htextPasswd = GetDlgItem(win, ID_WAITTEXT); + hcomboPasswd = GetDlgItem(win, ID_WAITBOX); + ShowWindow(hmute, SW_HIDE); + ShowWindow(hstaticPasswd, SW_HIDE); + ShowWindow(hbuddyPasswd, SW_SHOW); + ShowWindow(htextPasswd, SW_SHOW); + ShowWindow(hcomboPasswd, SW_SHOW); + if (CheckHots()) + { + ShowWindow(hstaticOK, SW_SHOW); + ShowWindow(hstaticBad, SW_HIDE); + } + else + { + ShowWindow(hstaticOK, SW_HIDE); + ShowWindow(hstaticBad, SW_SHOW); + } + if (firstTime) + { + SendMessage(hcomboTh, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"High"); + SendMessage(hcomboTh, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"Normal"); + SendMessage(hcomboTh, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"Low"); + SendMessage(hcomboTh, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"Ignore mouse movement"); + SendMessage(hcomboPasswd, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"seconds"); + SendMessage(hcomboPasswd, CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"minutes"); + firstTime = false; + } + SendMessage(hcomboTh, CB_SETCURSEL, (WPARAM)ss->MouseThresholdIndex, 0L); + SendMessage(hcomboPasswd, CB_SETCURSEL, (WPARAM)ss->PasswordDelayIndex, 0L); + if (ss->PasswordDelayIndex) nText = ss->PasswordDelay / 60; + else nText = ss->PasswordDelay; + sprintf(achNum, "%d", nText); + SendMessage(htextPasswd, WM_SETTEXT, 0, (LPARAM)(LPCTSTR)achNum); + SendMessage(hbuddyPasswd, UDM_SETRANGE, 0L, MAKELONG(99, 0)); + SendMessage(hbuddyPasswd, UDM_SETPOS, 0L, MAKELONG(nText, 0)); + CheckDlgButton(win, ID_MUTE, ss->MuteSound); + hbcheck = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BCHECK)); + hbdot = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BDOT)); + hbnone = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BNONE)); + hmonitor = GetDlgItem(win, IDC_MONITOR); + GetWindowRect(win, &rectDlg); + GetWindowRect(hmonitor, &rectBmp); + rectBmp.top -= rectDlg.top; + rectBmp.left -= rectDlg.left; + for (i=0; i < 4; i++) + { + hstb = GetDlgItem(win, IDC_UL+i); + switch (ss->Corners[i]) + { + case '-': hbuttonim = hbnone; break; + case 'Y': hbuttonim = hbcheck; break; + case 'N': hbuttonim = hbdot; break; + } + SendMessage(hstb, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)(HANDLE)hbuttonim); + MoveWindow(hstb, + nBtnCoordx[i] + rectBmp.left, + nBtnCoordy[i] + rectBmp.top, + BMPBUTTON_WIDTH, BMPBUTTON_HEIGHT, TRUE + ); + } + break; + + case PSN_RESET: + SetWindowLong(win, DWL_MSGRESULT, FALSE); + break; + + case PSN_KILLACTIVE: + if (hbcheck) DeleteObject(hbcheck); + if (hbdot) DeleteObject(hbdot); + if (hbnone) DeleteObject(hbnone); + hmute = GetDlgItem(win, ID_MUTE); + hcomboTh = GetDlgItem(win, ID_THRESHOLD); + hbuddyPasswd = GetDlgItem(win, ID_WAITBUDDY); + hcomboPasswd = GetDlgItem(win, ID_WAITBOX); + ss->MuteSound = IsDlgButtonChecked(win, ID_MUTE); + nSpinSel = SendMessage(hbuddyPasswd, UDM_GETPOS, 0, 0L); + nComboSel = SendMessage(hcomboPasswd, CB_GETCURSEL, 0, 0L); + ss->PasswordDelayIndex = nComboSel; + ss->PasswordDelay = LOWORD(nSpinSel); + if (nComboSel) ss->PasswordDelay *= 60; + nComboSel = SendMessage(hcomboTh, CB_GETCURSEL, 0, 0L); + ss->MouseThresholdIndex = nComboSel; + switch (nComboSel) + { + case 0: + ss->MouseThreshold = 0; + break; + case 1: + ss->MouseThreshold = 200; + break; + case 2: + ss->MouseThreshold = 400; + break; + case 3: + ss->MouseThreshold = 999999; + break; + } + SetWindowLong(win, DWL_MSGRESULT, FALSE); + return TRUE; + break; + + case PSN_APPLY: + ss->WriteGeneralRegistry(); + NotifyHots(); + SetWindowLong(win, DWL_MSGRESULT, TRUE); + break; + } + + case WM_COMMAND: + { + HMENU hpopup; + POINT point; + int nButton; // 0=UL 1=UR 2=DR 3=DL + int id = LOWORD(wparam); + UINT nMenu; + if ( (id >= IDC_UL) && (id <= IDC_DL) ) + { + nButton = id - IDC_UL; + hpopup = CreatePopupMenu(); + AppendMenu(hpopup, + MF_STRING | (ss->Corners[nButton] == '-' ? MF_CHECKED : 0), + ID_DEFAULT, "Default"); + AppendMenu(hpopup, + MF_STRING | (ss->Corners[nButton] == 'Y' ? MF_CHECKED : 0), + ID_NOW, "Now"); + AppendMenu(hpopup, + MF_STRING | (ss->Corners[nButton] == 'N' ? MF_CHECKED : 0), + ID_NEVER, "Never"); + GetCursorPos(&point); + nMenu = TrackPopupMenu(hpopup, + TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | TPM_LEFTBUTTON, + point.x, point.y, 0, win, NULL); + DestroyMenu(hpopup); + hstb = GetDlgItem(win, id); + switch (nMenu) + { + case 0: break; + case ID_DEFAULT: + ss->Corners[nButton] = '-'; + SendMessage(hstb, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)(HANDLE)hbnone); + break; + case ID_NOW: + ss->Corners[nButton] = 'Y'; + SendMessage(hstb, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)(HANDLE)hbcheck); + break; + case ID_NEVER: + ss->Corners[nButton] = 'N'; + SendMessage(hstb, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)(HANDLE)hbdot); + break; + } + } + } + break; + case WM_HELP: + { + LPHELPINFO lphi = (LPHELPINFO)lparam; + if (lphi->iContextType == HELPINFO_WINDOW) + { + WinHelp((HWND)lphi->hItemHandle, "Moebius Clock.hlp", HELP_WM_HELP, (DWORD)(LPSTR)aHelpIDs); + } + return TRUE; + } + break; + + case WM_CONTEXTMENU: + WinHelp((HWND)wparam, "Moebius Clock.hlp", HELP_CONTEXTMENU, (DWORD)(LPVOID)aHelpIDs); + return TRUE; + break; + } + // Otherwise, return false + return FALSE; +} diff --git a/GraphicConfigDialog.cpp b/GraphicConfigDialog.cpp new file mode 100644 index 0000000..ca69be3 --- /dev/null +++ b/GraphicConfigDialog.cpp @@ -0,0 +1,148 @@ +//========================================================================== +// +// File: GraphicConfigDialog.cpp +// +//========================================================================== + +#include + +#include "SaverSettings.h" +#include "resource.h" +#include "resource.hm" + +extern SaverSettings* ss; + +static const DWORD aHelpIDs[] = +{ + IDC_FLAT, HIDC_FLAT, + IDC_GOURAUD, HIDC_GOURAUD, + IDC_ANTIALIAS, HIDC_ANTIALIAS, + IDC_BLEND, HIDC_BLEND, + IDC_NORMALS, HIDC_NORMALS, + IDC_WIREFRAME, HIDC_WIREFRAME, + IDC_ZBUFFER, HIDC_ZBUFFER, + IDC_CULL, HIDC_CULL, + IDC_NOGLASS, HIDC_NOGLASS, + IDC_NOTEXTURES, HIDC_NOTEXTURES, + IDC_NEAREST, HIDC_NEAREST, + IDC_LINEAR, HIDC_NEAREST, + IDC_WMIPMAPS, HIDC_WMIPMAPS, + IDC_NMIPMAPS, HIDC_WMIPMAPS, + IDC_LMIPMAPS, HIDC_WMIPMAPS, + 0, 0 +}; + +/****************************************************************************/ +// +// Process the messages for the 'GraphicConfig' dialog. +// +BOOL APIENTRY +GraphicConfigDialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_INITDIALOG: + return TRUE; + + case WM_NOTIFY: + switch (((NMHDR FAR *) lParam)->code) + { + case PSN_SETACTIVE: + CheckDlgButton(hwnd, IDC_BLEND, ss->state.bBlend); + CheckDlgButton(hwnd, IDC_ANTIALIAS, ss->state.bSmooth); + CheckDlgButton(hwnd, IDC_NORMALS, ss->state.bNormals); + CheckDlgButton( + hwnd, IDC_WIREFRAME, + (ss->state.nPolygonMode == GL_FILL) ? FALSE : TRUE + ); + CheckDlgButton(hwnd, IDC_ZBUFFER, ss->state.bDepthTest); + CheckDlgButton(hwnd, IDC_CULL, ss->state.bCulling); + CheckDlgButton(hwnd, IDC_NOGLASS, ss->state.bNoGlass); + EnableWindow(GetDlgItem(hwnd, IDC_BLEND), !ss->state.bNoGlass); + CheckDlgButton(hwnd, IDC_NOTEXTURES, ss->state.bNoExtraTextures); + CheckRadioButton( + hwnd, IDC_FLAT, IDC_GOURAUD, + ss->state.nShadeModel == GL_FLAT ? IDC_FLAT : IDC_GOURAUD + ); + CheckRadioButton( + hwnd, IDC_NEAREST, IDC_LINEAR, + ss->state.nLinear == 1 ? IDC_LINEAR : IDC_NEAREST + ); + CheckRadioButton( + hwnd, IDC_WMIPMAPS, IDC_LMIPMAPS, + IDC_WMIPMAPS + ss->state.nMipmap + ); + break; + + case PSN_KILLACTIVE: + { + BOOL bBlend; + ss->state.bCulling = IsDlgButtonChecked(hwnd, IDC_CULL); + ss->state.bDepthTest = IsDlgButtonChecked(hwnd, IDC_ZBUFFER); + ss->state.bNormals = IsDlgButtonChecked(hwnd, IDC_NORMALS); + ss->state.bNoGlass = IsDlgButtonChecked(hwnd, IDC_NOGLASS); + ss->state.bNoExtraTextures = IsDlgButtonChecked(hwnd, IDC_NOTEXTURES); + ss->state.nLinear = + IsDlgButtonChecked(hwnd, IDC_LINEAR) ? 1 : 0; + ss->state.nMipmap = + IsDlgButtonChecked(hwnd, IDC_WMIPMAPS) ? 0 : 1; + ss->state.nMipmap = + IsDlgButtonChecked(hwnd, IDC_LMIPMAPS) ? 2 : ss->state.nMipmap; + ss->state.nPolygonMode = + IsDlgButtonChecked(hwnd, IDC_WIREFRAME) ? GL_LINE : GL_FILL; + ss->state.nShadeModel = + IsDlgButtonChecked(hwnd, IDC_FLAT) ? GL_FLAT : GL_SMOOTH; + ss->state.bSmooth = IsDlgButtonChecked(hwnd, IDC_ANTIALIAS); + bBlend = IsDlgButtonChecked(hwnd, IDC_BLEND); + if (ss->state.bBlend != bBlend) + { + ss->state.da = -ss->state.da; + ss->state.bBlend = bBlend; + } + SetWindowLong(hwnd, DWL_MSGRESULT, FALSE); + return TRUE; + } + break; + + case PSN_RESET: + SetWindowLong(hwnd, DWL_MSGRESULT, FALSE); + return TRUE; + break; + + case PSN_APPLY: + ss->WriteGraphicConfigRegistry(); + SetWindowLong(hwnd, DWL_MSGRESULT, FALSE); + break; + } + break; + + case WM_COMMAND: + { + int id = LOWORD(wParam); + if (id == IDC_NOGLASS) + { + HWND hblend = GetDlgItem(hwnd, IDC_BLEND); + EnableWindow(hblend, !IsWindowEnabled(hblend)); + } + } + break; + + case WM_HELP: + { + LPHELPINFO lphi = (LPHELPINFO)lParam; + if (lphi->iContextType == HELPINFO_WINDOW) + { + WinHelp((HWND)lphi->hItemHandle, "Moebius Clock.hlp", HELP_WM_HELP, (DWORD)(LPSTR)aHelpIDs); + } + return TRUE; + } + break; + + case WM_CONTEXTMENU: + WinHelp((HWND)wParam, "Moebius Clock.hlp", HELP_CONTEXTMENU, (DWORD)(LPVOID)aHelpIDs); + return TRUE; + break; + } + return FALSE; +} + diff --git a/HotCorners.cpp b/HotCorners.cpp new file mode 100644 index 0000000..bce04be --- /dev/null +++ b/HotCorners.cpp @@ -0,0 +1,71 @@ +//========================================================================== +// +// File: HotCorners.cpp +// +//========================================================================== + +#include + +//****************************************************************************************** +// CheckHots: this routine checks for Hot Corner services. +// It first tries with SAGE.DLL, which comes with Windows Plus! +// Failint this it tries with ScrHots, a third-party hot-corner +// service program written by the author that is freely +// distributable and works with NT and '95. +// It's not actually used in the saver, but code is included here +// just to be useful. +BOOL +CheckHots() +{ + typedef BOOL (WINAPI *SYSTEMAGENTDETECT)(); + HINSTANCE sagedll = LoadLibrary("Sage.dll"); + if (sagedll != NULL) + { + SYSTEMAGENTDETECT detectproc = + (SYSTEMAGENTDETECT)GetProcAddress(sagedll, "System_Agent_Detect"); + BOOL res = FALSE; + if (detectproc != NULL) res = detectproc(); + FreeLibrary(sagedll); + if (res) return TRUE; + } + HINSTANCE hotsdll = LoadLibrary("ScrHots.dll"); + if (hotsdll != NULL) + { + SYSTEMAGENTDETECT detectproc = + (SYSTEMAGENTDETECT)GetProcAddress(hotsdll, "System_Agent_Detect"); + BOOL res = FALSE; + if (detectproc != NULL) res = detectproc(); + FreeLibrary(hotsdll); + if (res) return TRUE; + } + return FALSE; +} + +//****************************************************************************************** +// NotifyHots: if you make any changes to the hot corner +// information in the registry, you must call NotifyHots +// to inform the hot corner services of your change. +// It's not actually used in the saver, but code is included here +// just to be useful. +void __fastcall +NotifyHots() +{ + typedef VOID (WINAPI *SCREENSAVERCHANGED)(); + HINSTANCE sagedll = LoadLibrary("Sage.DLL"); + if (sagedll != NULL) + { + SCREENSAVERCHANGED changedproc = + (SCREENSAVERCHANGED)GetProcAddress(sagedll, "Screen_Saver_Changed"); + if (changedproc != NULL) changedproc(); + FreeLibrary(sagedll); + } + HINSTANCE hotsdll = LoadLibrary("ScrHots.dll"); + if (hotsdll != NULL) + { + SCREENSAVERCHANGED changedproc = + (SCREENSAVERCHANGED)GetProcAddress(hotsdll, "Screen_Saver_Changed"); + if (changedproc != NULL) changedproc(); + FreeLibrary(hotsdll); + } +} + diff --git a/HotCorners.h b/HotCorners.h new file mode 100644 index 0000000..ba4df01 --- /dev/null +++ b/HotCorners.h @@ -0,0 +1,19 @@ +//========================================================================== +// +// File: HotCorners.h +// +//========================================================================== + +#ifndef HOTCORNERS_H +#define HOTCORNERS_H + +#include + +//****************************************************************************************** + +BOOL CheckHots(); +void __fastcall NotifyHots(); + +//****************************************************************************************** + +#endif diff --git a/Moebius Clock.hlp b/Moebius Clock.hlp new file mode 100644 index 0000000..7ce6d7a Binary files /dev/null and b/Moebius Clock.hlp differ diff --git a/Moebius.cpp b/Moebius.cpp new file mode 100644 index 0000000..97e3b55 --- /dev/null +++ b/Moebius.cpp @@ -0,0 +1,692 @@ +//========================================================================== +// +// File: Mobius.cpp +// +//========================================================================== + +#include +#include +#include "afxres.h" +#include "resource.h" +#include "OpenGLenv.h" + +#define TIMERID 1000 +#define UPDATE_TIME 10 + +#define SIGN_EXTEND(w) ((((int)(w)) << 16) >> 16) + + +/****************************************************************************/ + +#ifndef _SIM_DLL + int style = WS_OVERLAPPEDWINDOW; +#else + int style = WS_CHILD | WS_CAPTION; // style + char* str_DllName = "SimOpenGLDLL"; +#endif + +/****************************************************************************/ +// Forward function declarations + +static BOOL FirstInstance(HINSTANCE); +static BOOL AnyInstance(HWND&, HINSTANCE, int); +long FAR PASCAL WindowProc(HWND, UINT, WPARAM, LPARAM); + +/****************************************************************************/ +// Frame rate stuff +DWORD g_dwBegTime = 0; +DWORD g_dwLastTime = 0; +DWORD g_dwCurTime = 0; +DWORD g_dwFpsTime = 0; +DWORD g_dwDeltaTime = 0; +DWORD g_dwFramesRendered = 0; +DWORD g_dwFps = 0; +DWORD g_faces = 0; + +/****************************************************************************/ + +HINSTANCE _prev_inst = NULL; +LPSTR _cmdline = NULL; +int _cmdshow = SW_SHOW; + +int hChildLeft = 0; +int hChildTop = 0; +int hChildWidth = 512; +int hChildHeight= 512; +HWND hParwin = NULL; +HWND hWin = NULL; // Child application +HDC hdc = NULL; +HGLRC hglrc = NULL; + +static char ClassName[32] = "OpenGLClass"; +static char CaptionName[32] = "OpenGL Moebius Clock"; + +BOOL done = FALSE; // If simulation should be finished +BOOL bQuit = FALSE; // Set if we are quitting +BOOL bMovement = FALSE; + +extern GraphicEnvState state; + +/****************************************************************************/ +// +// Register the window class for the application. Also perform other +// desired application initialization +// +static BOOL +FirstInstance(HINSTANCE this_inst) +{ + // Contains the window class attributes to be registered + WNDCLASS wc; + // Status of the RegisteredClass call + BOOL rc; + + // + // Fill the slots of and register the window class + // + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = WindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = sizeof(DWORD); + wc.hInstance = this_inst; + wc.hIcon = LoadIcon(this_inst, MAKEINTRESOURCE(IDI_ICON1)); + //wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); + wc.lpszMenuName = "OpenGLMenu"; + wc.lpszClassName = ClassName; + rc = RegisterClass(&wc); + + // Return the initialized object + return rc; +} + +/****************************************************************************/ +// +// Perform the setup required for every instance of the application - +// Creation of the window and initialization of the data. +// + +static BOOL +AnyInstance(HWND& win, HINSTANCE this_inst, int cmdshow) +{ + HMENU hmenu = LoadMenu(this_inst, MAKEINTRESOURCE(IDR_MENU1)); + + // + // Create the main window + // + win = CreateWindow( + ClassName, // class + CaptionName, // caption + style, // style + hChildLeft, // init. x pos + hChildTop, // init. y pos + hChildWidth, // init. x size + hChildHeight, // init. y size + hParwin, // parent window + hmenu, // menu handle + this_inst, // program handle + NULL // create params + ); + if (!win) return FALSE; + + if (!InitGraphicEnv(hWin, &hdc, &hglrc)) return FALSE; + + InitState(); + InitTexture(); + InitDisplayLists(); + + SetTimer(win, TIMERID, UPDATE_TIME, NULL); + + // + // Show and update the window + // + ShowWindow(win, cmdshow); + UpdateWindow(win); + + return TRUE; +} + +/****************************************************************************/ + +BOOL +InitWindow(HINSTANCE this_inst, HWND hPar, int xleft, int xright, int width, int height) +{ + hParwin = hPar; + hChildLeft = xleft; + hChildTop = xright; + hChildWidth = width; + hChildHeight = height; + + g_dwBegTime = timeGetTime(); + + // If there is no previous instance set, register the window class + // for the application + if (!_prev_inst) + if (!FirstInstance(this_inst)) + return FALSE; + + // If we cannot do the remaining window setup, return an error + if (!AnyInstance(hWin, this_inst, _cmdshow)) + return FALSE; + + return TRUE; +} + +/****************************************************************************/ + +BOOL +ReInitWindow() +{ + KillTimer(hWin, TIMERID); + DestroyGraphicEnv(hWin, hdc, hglrc); + CloseWindow(hWin); + + return TRUE; +} + +/****************************************************************************/ + +int +WinOpen(HINSTANCE this_inst, HWND hPar, int xleft, int xright, int width, int height) +{ + MSG msg; + + if (InitWindow(this_inst, hPar, xleft, xright, width, height) == FALSE) + return FALSE; + + // Loop until we are done - either the user quits or an error occurs + while (!done) + { + // Check the thread message queue for a message and place it in + // message if there is one. + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + if (msg.message == WM_QUIT) + { + done = TRUE; + break; + } + // Translate the virtual key messages into character messages + TranslateMessage(&msg); + + // Dispatch the message to the window proceedure + DispatchMessage(&msg); + } + } + + ReInitWindow(); + return msg.wParam; +} + +/****************************************************************************/ +// +// This function is the main routine containing the message loop. +// Here we call the functions to create, initialize, and activate +// the program's main window and handle the various messages. +// + +int PASCAL +WinMain(HINSTANCE this_inst, HINSTANCE prev_inst, LPSTR cmdline, int cmdshow) +{ + _prev_inst = prev_inst; + _cmdline = cmdline; + _cmdshow = cmdshow; + + return WinOpen(this_inst, NULL, 0, 0, 512, 512); +} + +/****************************************************************************/ + +BOOL +TimerProc(HWND hwnd) +{ + if (!bQuit) + { + // Try to render the screen + g_dwCurTime = timeGetTime(); + + // Perform some timing stuff + g_dwDeltaTime = g_dwCurTime - g_dwLastTime; + g_dwLastTime = g_dwCurTime; + g_dwFpsTime += g_dwDeltaTime; + g_dwFramesRendered++; + + // Update every second + if (g_dwFpsTime > 1000) + { + char str[256]; + + g_dwFps = g_dwFramesRendered; + g_dwFramesRendered = 0; + + sprintf ( (LPSTR)str, "OpenGLDemo - FPS: %.3f", + 1000.0*(float)g_dwFps/(float)g_dwFpsTime ); + SetWindowText(hWin, (LPSTR)str); + + g_dwFpsTime = 0; + } + UpdateTime(); + InvalidateRect(hwnd, NULL, FALSE); + } + + return TRUE; +} + +/****************************************************************************/ +// +// Process the messages for the 'about' dialog. +// +BOOL FAR PASCAL +AboutDlgProc(HWND win, unsigned msg, WORD wparam, LONG lparam) +{ + // Check the message + switch (msg) + { + // If we received an InitDialog message, just return true + case WM_INITDIALOG: + return TRUE; + + // If we received an OK button selection, + // close the dialog and return true + case WM_COMMAND: + if (wparam == IDOK) + { + EndDialog(win, TRUE); + return TRUE; + } + break; + } + // Otherwise, return false + return FALSE; +} + +/****************************************************************************/ + +void +OnCreate(HWND win) +{ + CheckMenuItem( + GetMenu(win), ID_VIEW_ANTIALIAS, + state.bSmooth ? MF_CHECKED : MF_UNCHECKED + ); + CheckMenuItem( + GetMenu(win), ID_VIEW_BLEND, + state.bBlend ? MF_CHECKED : MF_UNCHECKED + ); + CheckMenuItem( + GetMenu(win), ID_VIEW_CULL, + state.bCulling ? MF_CHECKED : MF_UNCHECKED + ); + CheckMenuRadioItem( + GetMenu(win), ID_VIEW_METHOD_NICEST, ID_VIEW_METHOD_FASTEST, + state.nLineSmoothHint == GL_NICEST ? ID_VIEW_METHOD_NICEST : + ID_VIEW_METHOD_FASTEST, MF_BYCOMMAND + ); + CheckMenuRadioItem( + GetMenu(win), + ID_VIEW_SHADE_FLAT, ID_VIEW_SHADE_GOURARD, + state.nShadeModel == GL_SMOOTH ? ID_VIEW_SHADE_GOURARD : + ID_VIEW_SHADE_FLAT, MF_BYCOMMAND + ); + CheckMenuItem( + GetMenu(win), ID_VIEW_LINEAR, + state.nLinear == 1 ? MF_CHECKED : MF_UNCHECKED + ); + + CheckMenuItem(GetMenu(win), ID_VIEW_MIDMAPS, MF_CHECKED); + + CheckMenuRadioItem( + GetMenu(win), + ID_VIEW_PERSP_NICEST, ID_VIEW_PERSP_FASTEST, + state.nPerspCorrectionHint == GL_NICEST ? ID_VIEW_PERSP_NICEST : + ID_VIEW_PERSP_FASTEST, MF_BYCOMMAND + ); + CheckMenuItem( + GetMenu(win), ID_VIEW_NORMALS, + state.bNormals ? MF_CHECKED : MF_UNCHECKED + ); + CheckMenuItem( + GetMenu(win), ID_VIEW_QUICK, + state.bQuick ? MF_CHECKED : MF_UNCHECKED + ); + CheckMenuItem( + GetMenu(win), ID_VIEW_SWING, + state.bSwing ? MF_CHECKED : MF_UNCHECKED + ); + CheckMenuItem( + GetMenu(win), ID_VIEW_ZBUFFER, + state.bDepthTest ? MF_CHECKED : MF_UNCHECKED + ); + CheckMenuItem( + GetMenu(win), ID_VIEW_WIREFRAME, + state.nPolygonMode == GL_LINE ? MF_CHECKED : MF_UNCHECKED + ); +} + +/****************************************************************************/ + +void +OnCommand(HWND win, WPARAM wparam, LPARAM lparam) +{ + switch( wparam & 0xffff ) + { + case ID_FILE_EXIT: + PostQuitMessage(0); + bQuit = TRUE; + break; + + case ID_VIEW_ANTIALIAS: + state.bSmooth = !state.bSmooth; + CheckMenuItem( + GetMenu(win), ID_VIEW_ANTIALIAS, + state.bSmooth ? MF_CHECKED : MF_UNCHECKED + ); + EnableGraphicOption(GL_LINE_SMOOTH, state.bSmooth); + EnableGraphicOption(GL_POLYGON_SMOOTH, state.bSmooth); + break; + + case ID_VIEW_BLEND: + state.da = -state.da; + state.bBlend = !state.bBlend; + CheckMenuItem( + GetMenu(win), ID_VIEW_BLEND, + state.bBlend ? MF_CHECKED : MF_UNCHECKED + ); + break; + + case ID_VIEW_CULL: + state.bCulling = !state.bCulling; + CheckMenuItem( + GetMenu(win), ID_VIEW_CULL, + state.bCulling ? MF_CHECKED : MF_UNCHECKED + ); + EnableGraphicOption(GL_CULL_FACE, state.bCulling); + break; + + case ID_VIEW_METHOD_NICEST: + if (state.nLineSmoothHint != GL_NICEST) + { + state.nLineSmoothHint = GL_NICEST; + CheckMenuRadioItem( + GetMenu(win), ID_VIEW_METHOD_NICEST, ID_VIEW_METHOD_FASTEST, + ID_VIEW_METHOD_NICEST, MF_BYCOMMAND + ); + glHint(GL_LINE_SMOOTH_HINT, state.nLineSmoothHint); + } + break; + + case ID_VIEW_METHOD_FASTEST: + if (state.nLineSmoothHint != GL_FASTEST) + { + state.nLineSmoothHint = GL_FASTEST; + CheckMenuRadioItem( + GetMenu(win), ID_VIEW_METHOD_NICEST, ID_VIEW_METHOD_FASTEST, + ID_VIEW_METHOD_FASTEST, MF_BYCOMMAND + ); + glHint(GL_LINE_SMOOTH_HINT, state.nLineSmoothHint); + } + break; + + case ID_VIEW_SHADE_FLAT: + if (state.nShadeModel != GL_FLAT) + { + state.nShadeModel = GL_FLAT; + CheckMenuRadioItem( + GetMenu(win), + ID_VIEW_SHADE_FLAT, ID_VIEW_SHADE_GOURARD, + ID_VIEW_SHADE_FLAT, MF_BYCOMMAND + ); + glShadeModel(state.nShadeModel); + } + break; + + case ID_VIEW_SHADE_GOURARD: + if (state.nShadeModel != GL_SMOOTH) + { + state.nShadeModel = GL_SMOOTH; + CheckMenuRadioItem( + GetMenu(win), + ID_VIEW_SHADE_FLAT, ID_VIEW_SHADE_GOURARD, + ID_VIEW_SHADE_GOURARD, MF_BYCOMMAND + ); + glShadeModel(state.nShadeModel); + } + break; + + case ID_VIEW_LINEAR: + state.nLinear = (state.nLinear == 1 ? 0 : 1); + CheckMenuItem( + GetMenu(win), ID_VIEW_LINEAR, + state.nLinear == 1 ? MF_CHECKED : MF_UNCHECKED + ); + break; + + case ID_VIEW_PERSP_NICEST: + if (state.nPerspCorrectionHint != GL_NICEST) + { + state.nPerspCorrectionHint = GL_NICEST; + CheckMenuRadioItem( + GetMenu(win), + ID_VIEW_PERSP_NICEST, ID_VIEW_PERSP_FASTEST, + ID_VIEW_PERSP_NICEST, MF_BYCOMMAND + ); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, state.nPerspCorrectionHint); + } + break; + + case ID_VIEW_PERSP_FASTEST: + if (state.nPerspCorrectionHint != GL_FASTEST) + { + state.nPerspCorrectionHint = GL_FASTEST; + CheckMenuRadioItem( + GetMenu(win), + ID_VIEW_PERSP_NICEST, ID_VIEW_PERSP_FASTEST, + ID_VIEW_PERSP_FASTEST, MF_BYCOMMAND + ); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, state.nPerspCorrectionHint); + } + break; + + case ID_VIEW_NORMALS: + state.bNormals = !state.bNormals; + CheckMenuItem( + GetMenu(win), ID_VIEW_NORMALS, + state.bNormals ? MF_CHECKED : MF_UNCHECKED + ); + break; + + case ID_VIEW_QUICK: + state.bQuick = !state.bQuick; + CheckMenuItem( + GetMenu(win), ID_VIEW_QUICK, + state.bQuick ? MF_CHECKED : MF_UNCHECKED + ); + break; + + case ID_VIEW_SWING: + state.bSwing = !state.bSwing; + CheckMenuItem( + GetMenu(win), ID_VIEW_SWING, + state.bSwing ? MF_CHECKED : MF_UNCHECKED + ); + break; + + case ID_VIEW_ZBUFFER: + state.bDepthTest = !state.bDepthTest; + CheckMenuItem( + GetMenu(win), ID_VIEW_ZBUFFER, + state.bDepthTest ? MF_CHECKED : MF_UNCHECKED + ); + EnableGraphicOption(GL_DEPTH_TEST, state.bDepthTest); + break; + + case ID_VIEW_WIREFRAME: + state.nPolygonMode = (state.nPolygonMode == GL_LINE ? GL_FILL : GL_LINE); + CheckMenuItem( + GetMenu(win), ID_VIEW_WIREFRAME, + state.nPolygonMode == GL_LINE ? MF_CHECKED : MF_UNCHECKED + ); + glPolygonMode(GL_FRONT_AND_BACK, state.nPolygonMode); + break; + + case ID_HELP_ABOUT: + DialogBox( + (HINSTANCE)GetWindowLong(win, GWL_HINSTANCE), + MAKEINTRESOURCE(IDD_ABOUT), win, + (DLGPROC)AboutDlgProc + ); + break; + } + InvalidateRect(win, NULL, FALSE); +} + +/****************************************************************************/ +// +// Process the messages for the main application window +// +LONG FAR PASCAL +WindowProc(HWND win, UINT msg, WPARAM wparam, LPARAM lparam) +{ + static BOOL bRoll = FALSE; + static POINT anchor; + + // Handle the various message that we received + switch (msg) + { + case WM_CREATE: + OnCreate(win); + break; + + case WM_KEYDOWN: + { + // Check for any keyboard key depression + switch (wparam) + { + case VK_SPACE: + ResetOrientationGraphicEnv(); + CheckMenuItem( + GetMenu(win), ID_VIEW_SWING, + state.bSwing ? MF_CHECKED : MF_UNCHECKED + ); + break; + + case 'T': + break; + case VK_UP: + break; + case VK_DOWN: + break; + case VK_RIGHT: + break; + case VK_LEFT: + break; + case VK_HOME: + break; + case VK_END: + break; + case VK_INSERT: + break; + case VK_DELETE: + break; + case VK_PRIOR: // PageUp + break; + case VK_NEXT: // PageDown + break; + case VK_NUMPAD4: + break; + } + } + break; + + // If the user releases a key, see which one it was and do the appropriate action + case WM_KEYUP: + switch (wparam) + { + case 'T': + break; + } + break; + + case WM_COMMAND: + OnCommand(win, wparam, lparam); + break; + + case WM_LBUTTONDOWN: + RECT rc; + bMovement = TRUE; + GetClientRect(win, &rc); + GetCursorPos(&anchor); + ScreenToClient(hWin, &anchor); + bRoll = (GetKeyState(VK_SHIFT) & 0x8000) >> 15; + SetCapture(win); + break; + + case WM_LBUTTONUP: + bMovement = FALSE; + bRoll = FALSE; + ReleaseCapture(); + break; + + case WM_RBUTTONDOWN: + break; + case WM_RBUTTONUP: + break; + + case WM_MOUSEMOVE: + if (bMovement & wparam & MK_LBUTTON) + { + POINT mouse; + mouse.x = SIGN_EXTEND(LOWORD(lparam)); + mouse.y = SIGN_EXTEND(HIWORD(lparam)); + MotionOfGraphicEnv(&anchor, mouse, bRoll); + } + break; + + case WM_TIMER: + if (wparam == TIMERID) + TimerProc(win); + break; + + // We are quitting and destroying the window + case WM_DESTROY: + PostQuitMessage(0); + bQuit = TRUE; + break; + + case WM_SIZE: + { + int width = LOWORD(lparam); + int height = HIWORD(lparam); + if (width && height) + { + Reshape(hdc, width, height); + } + } + break; + + case WM_ACTIVATE: + break; + + // Handle the window paint message and update the window + case WM_PAINT: + { + RECT r; + PAINTSTRUCT ps; + + // Retrieve the coordinates of the smallest rectangle that completely encloses the + // update region of the specified window (win) + if (GetUpdateRect(win, &r, FALSE)) + { + BeginPaint(win, &ps); + Display(hdc); + EndPaint(win, &ps); + } + } + + default: + // Default to just handling any messages not explicitly handled above + return DefWindowProc(win, msg, wparam, lparam); + } + return 0L; +} + diff --git a/Moebius.ico b/Moebius.ico new file mode 100644 index 0000000..dd02f8a Binary files /dev/null and b/Moebius.ico differ diff --git a/Moebius32.aps b/Moebius32.aps new file mode 100644 index 0000000..ec08808 Binary files /dev/null and b/Moebius32.aps differ diff --git a/Moebius32.rc b/Moebius32.rc new file mode 100644 index 0000000..fb4d943 --- /dev/null +++ b/Moebius32.rc @@ -0,0 +1,318 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +// Generated Help ID header file +#define APSTUDIO_HIDDEN_SYMBOLS +#include "resource.hm" +#undef APSTUDIO_HIDDEN_SYMBOLS + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1255) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_CAFE BITMAP DISCARDABLE "cafe.bmp" +IDB_HOURS0 BITMAP DISCARDABLE "hours0.bmp" +IDB_HOURS1 BITMAP DISCARDABLE "hours1.bmp" +IDB_HOURS2 BITMAP DISCARDABLE "hours2.bmp" +IDB_HOURS3 BITMAP DISCARDABLE "hours3.bmp" +IDB_OGLLOGO BITMAP DISCARDABLE "ogllogo.bmp" +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + +///////////////////////////////////////////////////////////////////////////// +// Unknown language: 0xD, 0x1 resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_HEB) +#ifdef _WIN32 +LANGUAGE 0xD, 0x1 +#pragma code_page(1255) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_MONITOR BITMAP DISCARDABLE "monitor.bmp" +IDB_BCHECK BITMAP DISCARDABLE "bcheck.bmp" +IDB_BDOT BITMAP DISCARDABLE "bdot.bmp" +IDB_BNONE BITMAP DISCARDABLE "bnone.bmp" +IDB_MONITOR2 BITMAP DISCARDABLE "monitor2.bmp" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU1 MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "E&xit", ID_FILE_EXIT + END + POPUP "&View" + BEGIN + MENUITEM "&Antialiasing", ID_VIEW_ANTIALIAS + POPUP "Antialiasing &Method" + BEGIN + MENUITEM "&Nicest", ID_VIEW_METHOD_NICEST + MENUITEM "&Fastest", ID_VIEW_METHOD_FASTEST + END + POPUP "&Shading Model" + BEGIN + MENUITEM "&Flat", ID_VIEW_SHADE_FLAT + MENUITEM "&Gourard", ID_VIEW_SHADE_GOURARD + END + MENUITEM "Alpha &Blending", ID_VIEW_BLEND + MENUITEM "&Linear Filtering", ID_VIEW_LINEAR + MENUITEM "Mi&dmaps", ID_VIEW_MIDMAPS + MENUITEM SEPARATOR + MENUITEM "Swin&g Clock", ID_VIEW_SWING + MENUITEM "Speed &Up Clock", ID_VIEW_QUICK + MENUITEM SEPARATOR + MENUITEM "Show &Wireframe", ID_VIEW_WIREFRAME + MENUITEM "Show &Normals", ID_VIEW_NORMALS + MENUITEM SEPARATOR + MENUITEM "Use &Z-Buffer", ID_VIEW_ZBUFFER + MENUITEM "Backface &Culling", ID_VIEW_CULL + POPUP "&Perspective Correction" + BEGIN + MENUITEM "&Nicest", ID_VIEW_PERSP_NICEST + MENUITEM "&Fastest", ID_VIEW_PERSP_FASTEST + END + END + POPUP "&Help" + BEGIN + MENUITEM "&About", ID_HELP_ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON DISCARDABLE "Moebius.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUT DIALOG DISCARDABLE 0, 0, 246, 98 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About Moebius Clock Screensaver" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,189,7,50,14 + ICON IDI_ICON1,IDC_STATIC,15,25,20,20 + LTEXT "Moebius Clock Screensaver v 1.8",IDC_STATIC,50,15,131, + 15 + LTEXT "Concept and OpenGL implementation by\n\tRon Inbar :\trinbar@netvision.net.il\nWin32 implementation by\n\t Uriel Cohen :\turielc@actcom.co.il", + IDC_STATIC,50,35,185,35 + LTEXT "Copyright © 1999-2000 by Uriel Cohen && Ron Inbar", + IDC_STATIC,50,75,185,15 +END + +IDD_GRAPHIC_CONFIG DIALOGEX 0, 0, 239, 220 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "OpenGL" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + GROUPBOX "Rendering",IDC_STATIC,15,20,120,95 + CONTROL "Flat Shading",IDC_FLAT,"Button",BS_AUTORADIOBUTTON | + WS_GROUP | WS_TABSTOP,30,35,70,15,0,HIDC_FLAT + CONTROL "Gouraud Shading",IDC_GOURAUD,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,30,50,75,15,0, + HIDC_GOURAUD + CONTROL "Alpha Blending",IDC_BLEND,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,30,90,75,15,0,HIDC_BLEND + GROUPBOX "Texture Filtering",IDC_STATIC,15,130,205,70 + CONTROL "Nearest",IDC_NEAREST,"Button",BS_AUTORADIOBUTTON | + WS_GROUP | WS_TABSTOP,30,150,60,15,0,HIDC_NEAREST + CONTROL "Linear",IDC_LINEAR,"Button",BS_AUTORADIOBUTTON | + WS_TABSTOP,30,165,60,15,0,HIDC_LINEAR + CONTROL "Without Mipmaps",IDC_WMIPMAPS,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,105,145,105, + 15,0,HIDC_WMIPMAPS + CONTROL "Nearest Mipmap",IDC_NMIPMAPS,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,105,160,105,15,0, + HIDC_NMIPMAPS + CONTROL "Linear Between Mipmaps",IDC_LMIPMAPS,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,105,175,105,15,0, + HIDC_LMIPMAPS + CONTROL "Normals",IDC_NORMALS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,155,25,75,15,0,HIDC_NORMALS + CONTROL "Wireframe",IDC_WIREFRAME,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,155,40,75,15,0,HIDC_WIREFRAME + CONTROL "Z-Buffer",IDC_ZBUFFER,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,155,55,75,15,0,HIDC_ZBUFFER + CONTROL "Backface Culling",IDC_CULL,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,155,70,75,15,0,HIDC_CULL + CONTROL "No Covering Glass",IDC_NOGLASS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,155,85,75,15,0,HIDC_NOGLASS + CONTROL "No Extra Textures",IDC_NOTEXTURES,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,155,100,75,15,0, + HIDC_NOTEXTURES + CONTROL "Antialiasing",IDC_ANTIALIAS,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,30,75,75,15,0,HIDC_ANTIALIAS +END + +IDD_GENERAL DIALOGEX 0, 0, 237, 220 +STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_VISIBLE | WS_CAPTION | + WS_SYSMENU +CAPTION "General" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + LTEXT "You can display the screen saver immediately or prevent it from\nappearing at all,by moving the mouse pointer to a corner on \nthe screen. Click the corners you want to use.", + ID_SAGEOK,13,8,282,32 + LTEXT "The system agent must be active in order for you to display \nthe screen saver immediately by moving the mouse \npointer to a corner on the screen.", + ID_SAGEBAD,13,13,282,32 + GROUPBOX "Options for dismissing the screen saver", + ID_DISMISSGROUP,7,154,223,47 + LTEXT "&Mouse sensitivity",ID_THRESHOLDDESC,13,169,58,12 + COMBOBOX ID_THRESHOLD,74,167,148,72,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP,0,HID_THRESHOLD + RTEXT "&Wait",ID_WAITDESC,13,184,16,12 + EDITTEXT ID_WAITTEXT,32,184,25,12,0,0,HID_WAITTEXT + CONTROL "Generic1",ID_WAITBUDDY,"msctls_updown32", + UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | + UDS_ARROWKEYS,57,184,11,36,0,HID_WAITBUDDY + COMBOBOX ID_WAITBOX,74,184,50,36,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP,0,HID_WAITBOX + LTEXT "before requiring a password",ID_WAITMOREDESC,130,185,95, + 11 + LTEXT "Always require password",ID_WAITSUMMARY,13,184,282,11, + NOT WS_GROUP + CONTROL "Mute Sound",ID_MUTE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,11,202,65,15,0,HID_MUTE + CONTROL 122,IDC_UL,"Static",SS_BITMAP | SS_NOTIFY,64,54,12,11,0, + HIDC_UL + CONTROL 122,IDC_UR,"Static",SS_BITMAP | SS_NOTIFY,127,54,12,11,0, + HIDC_UR + CONTROL 122,IDC_DL,"Static",SS_BITMAP | SS_NOTIFY,64,98,12,11,0, + HIDC_DL + CONTROL 122,IDC_DR,"Static",SS_BITMAP | SS_NOTIFY,127,98,12,11,0, + HIDC_DR + CONTROL "Monitor",IDC_MONITOR,"Button",BS_OWNERDRAW | WS_TABSTOP, + 55,45,92,85,0,HIDC_MONITOR +END + +IDD_BEHAVIOR DIALOGEX 0, 0, 239, 220 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Behavior" +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "Speed Up Clock",IDC_QUICK,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,150,70,70,15,0,HIDC_QUICK + CONTROL "Swing Clock",IDC_SWING,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,150,85,70,15,0,HIDC_SWING + CONTROL "Interactive",IDC_USEMOUSE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,150,100,70,15,0,HIDC_USEMOUSE + CONTROL "Backdrop",IDC_BACK,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,150,115,70,15,0,HIDC_BACK + LTEXT "Moebius Strip Twists",IDC_STATIC,65,173,65,15 + EDITTEXT IDC_EDIT1,132,171,30,15,ES_AUTOHSCROLL | ES_READONLY | + ES_NUMBER,0,HIDC_EDIT1 + CONTROL "Spin1",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS,164,170,7, + 15,0,HIDC_SPIN1 + PUSHBUTTON "About...",IDC_ABOUT,160,15,50,14,0,0,HIDC_ABOUT + CONTROL "Monitor",IDC_MONITOR,"Button",BS_OWNERDRAW | + WS_DISABLED | WS_TABSTOP,15,60,92,85,0,HIDC_MONITOR + LTEXT "Backdrop Colors:",IDC_STATIC,15,45,85,10 + CONTROL "Color 1",IDC_COLOR1,"Button",BS_OWNERDRAW | WS_TABSTOP, + 24,69,12,11,0,HIDC_COLOR1 + CONTROL "Color 2",IDC_COLOR2,"Button",BS_OWNERDRAW | WS_TABSTOP, + 87,70,12,11,0,HIDC_COLOR2 + CONTROL "Color 3",IDC_COLOR3,"Button",BS_OWNERDRAW | WS_TABSTOP, + 24,113,12,11,0,HIDC_COLOR3 + CONTROL "Color 4",IDC_COLOR4,"Button",BS_OWNERDRAW | WS_TABSTOP, + 87,113,12,11,0,HIDC_COLOR4 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_BEHAVIOR, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 232 + TOPMARGIN, 7 + BOTTOMMARGIN, 213 + END +END +#endif // APSTUDIO_INVOKED + +#endif // Unknown language: 0xD, 0x1 resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/MoebiusScreenSaver.dsp b/MoebiusScreenSaver.dsp new file mode 100644 index 0000000..07df511 --- /dev/null +++ b/MoebiusScreenSaver.dsp @@ -0,0 +1,231 @@ +# Microsoft Developer Studio Project File - Name="MoebiusScreenSaver" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=MoebiusScreenSaver - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "MoebiusScreenSaver.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "MoebiusScreenSaver.mak" CFG="MoebiusScreenSaver - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "MoebiusScreenSaver - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "MoebiusScreenSaver - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName ""$/MoebiusScreenSaver", BAAAAAAA" +# PROP Scc_LocalPath "." +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "MoebiusScreenSaver - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x40d /d "NDEBUG" +# ADD RSC /l 0x40d /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib winmm.lib comctl32.lib /nologo /subsystem:windows /machine:I386 /out:"Release/Moebius Clock.scr" + +!ELSEIF "$(CFG)" == "MoebiusScreenSaver - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FR /YX /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x40d /d "_DEBUG" +# ADD RSC /l 0x40d /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib winmm.lib comctl32.lib /nologo /subsystem:windows /debug /machine:I386 /out:"Debug/Moebius Clock.scr" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "MoebiusScreenSaver - Win32 Release" +# Name "MoebiusScreenSaver - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\BehaviorDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\GeneralDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\GraphicConfigDialog.cpp +# End Source File +# Begin Source File + +SOURCE=.\HotCorners.cpp +# End Source File +# Begin Source File + +SOURCE=.\Moebius32.rc +# End Source File +# Begin Source File + +SOURCE=.\OpenGLenv.cpp +# End Source File +# Begin Source File + +SOURCE=.\Password.cpp +# End Source File +# Begin Source File + +SOURCE=.\SaverSettings.cpp +# End Source File +# Begin Source File + +SOURCE=.\ScreenSaver.cpp +# End Source File +# Begin Source File + +SOURCE=.\texture.c +# End Source File +# Begin Source File + +SOURCE=.\TransparentBitmap.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\Debug.h +# End Source File +# Begin Source File + +SOURCE=.\Dialogs.h +# End Source File +# Begin Source File + +SOURCE=.\HotCorners.h +# End Source File +# Begin Source File + +SOURCE=.\OpenGLenv.h +# End Source File +# Begin Source File + +SOURCE=.\Password.h +# End Source File +# Begin Source File + +SOURCE=.\SaverSettings.h +# End Source File +# Begin Source File + +SOURCE=.\TransparentBitmap.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\bcheck.bmp +# End Source File +# Begin Source File + +SOURCE=.\bdot.bmp +# End Source File +# Begin Source File + +SOURCE=.\bnone.bmp +# End Source File +# Begin Source File + +SOURCE=.\cafe.bmp +# End Source File +# Begin Source File + +SOURCE=.\hours0.bmp +# End Source File +# Begin Source File + +SOURCE=.\hours1.bmp +# End Source File +# Begin Source File + +SOURCE=.\hours2.bmp +# End Source File +# Begin Source File + +SOURCE=.\hours3.bmp +# End Source File +# Begin Source File + +SOURCE=.\icon2.ico +# End Source File +# Begin Source File + +SOURCE=.\Moebius.ico +# End Source File +# Begin Source File + +SOURCE=.\monitor.bmp +# End Source File +# Begin Source File + +SOURCE=.\monitor.ico +# End Source File +# Begin Source File + +SOURCE=.\monitor2.bmp +# End Source File +# Begin Source File + +SOURCE=.\ogllogo.bmp +# End Source File +# End Group +# End Target +# End Project diff --git a/MoebiusScreenSaver.dsw b/MoebiusScreenSaver.dsw new file mode 100644 index 0000000..1d8654c --- /dev/null +++ b/MoebiusScreenSaver.dsw @@ -0,0 +1,45 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "Mobius32"="..\Mobius32\Mobius32.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "MoebiusScreenSaver"=".\MoebiusScreenSaver.dsp" - Package Owner=<4> + +Package=<5> +{{{ + begin source code control + "$/MoebiusScreenSaver", BAAAAAAA + . + end source code control +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/MoebiusScreenSaver.hpj b/MoebiusScreenSaver.hpj new file mode 100644 index 0000000..9fd87a5 --- /dev/null +++ b/MoebiusScreenSaver.hpj @@ -0,0 +1,35 @@ +; This file is maintained by HCW. Do not modify this file directly. + +[OPTIONS] +LCID=0x409 0x0 0x0 ; English (United States) +REPORT=Yes +HLP=Moebius Clock.hlp + +[FILES] +MoebiusScreenSaver.rtf + +[MAP] +HID_MUTE=0x80710404 +HID_THRESHOLD=0x807103fb +HID_WAITBOX=0x80710400 +HID_WAITTEXT=0x807103fe +HIDC_ABOUT=0x807b03ec +HIDC_ANTIALIAS=0x806f0415 +HIDC_BACK=0x807b03fa +HIDC_BLEND=0x806f03eb +HIDC_COLOR1=0x807b040f +HIDC_CULL=0x806f03f3 +HIDC_FLAT=0x806f03e9 +HIDC_GOURAUD=0x806f03ea +HIDC_NEAREST=0x806f040a +HIDC_NOGLASS=0x806f0413 +HIDC_NORMALS=0x806f03ee +HIDC_NOTEXTURES=0x806f0414 +HIDC_QUICK=0x807b03ed +HIDC_SPIN1=0x807b03f1 +HIDC_SWING=0x807b03f8 +HIDC_UL=0x80710406 +HIDC_USEMOUSE=0x807b03fc +HIDC_WIREFRAME=0x806f03ef +HIDC_WMIPMAPS=0x806f040c +HIDC_ZBUFFER=0x806f03f2 diff --git a/MoebiusScreenSaver.rtf b/MoebiusScreenSaver.rtf new file mode 100644 index 0000000..b7bbbb7 --- /dev/null +++ b/MoebiusScreenSaver.rtf @@ -0,0 +1,92 @@ +{\rtf1\adeflang1037\ansi\ansicpg1255\uc1\adeff15 \deff0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f11\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}MS Sans Serif{\*\falt Arial};} +{\f15\fbidi \fcharset177\fprq2{\*\panose 00000000000000000000}Miriam;}{\f17\froman\fcharset238\fprq2 Times New Roman CE;}{\f18\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f20\froman\fcharset161\fprq2 Times New Roman Greek;} +{\f21\froman\fcharset162\fprq2 Times New Roman Tur;}{\f22\fbidi \fcharset177\fprq2 Times New Roman (Hebrew);}{\f24\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f110\fbidi \fcharset177\fprq2 MS Sans Serif (Hebrew){\*\falt Arial};}} +{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0; +\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\ql\nowidctlpar\widctlpar\adjustright \ql \rtlch\af15\afs20 \ltrch\fs20 \snext0 Normal;}{\*\cs10 \additive +Default Paragraph Font;}{\s15\ql\nowidctlpar\widctlpar\adjustright \ql \rtlch\af15\afs20 \ltrch\fs20 \sbasedon0 \snext15 footnote text;}{\*\cs16 \additive \rtlch\af15\super \ltrch\super \sbasedon10 footnote reference;}{\s17\ql\li142\sb80\sl240\slmult0 +\nowidctlpar\adjustright \ql \rtlch\af15\afs20 \ltrch\f11\fs16\lang1024 \sbasedon0 \snext17 Body Text 2;}}{\info{\title Renders the clock model using flat shading (only one color is calculated for each polygon)}{\author Uriel Cohen}{\operator Uriel Cohen} +{\creatim\yr1999\mo11\dy28\hr18\min20}{\revtim\yr1999\mo11\dy29\hr20\min10}{\version46}{\edmins66}{\nofpages24}{\nofwords712}{\nofchars4063}{\*\company Cohen S.A}{\nofcharsws4989}{\vern89}}\ltrsect +\widowctrl\ftnbj\aenddoc\hyphcaps0\viewkind4\viewscale125 \fet0\ltrpar \qj \sectd \ltrsect\linex0\headery709\footery709\colsx709\sectdefaultcl {\*\pnseclvl1\pnucrm\pnqc\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2 +\pnucltr\pnqc\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnqc\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnqc\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnqc\pnstart1\pnindent720\pnhang{\pntxtb (} +{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnqc\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnqc\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnqc\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9 +\pnlcrm\pnqc\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\qj \qj\li142\sb80\sl240\slmult0\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\f11\fs16\super #{\footnote +\ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super #}{\rtlch \af15 \ltrch HID_THRESHOLD}}}{\rtlch \af15 \ltrch \f11\fs16 Determines the }{\rtlch \ab\af15 +\ltrch \b\f11\fs16 Mouse sensitivity}{\rtlch \af15 \ltrch \f11\fs16 to dismiss the screen saver. Click on }{\rtlch \ab\af15 \ltrch \b\f11\fs16 High}{\rtlch \af15 \ltrch \f11\fs16 , }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Normal}{\rtlch \af15 \ltrch +\f11\fs16 or }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Low}{\rtlch \af15 \ltrch \f11\fs16 to select one of the three corresponding levels of sensitivity. Click on }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Ignore mouse movement}{\rtlch \af15 \ltrch \f11\fs16 + not to allow dismissing the screen saver with the mouse; in this case the screen saver can only be dismissed with the keyboard. +\par }{\rtlch \af15 \ltrch \f11\fs16 \page }{\rtlch \cs16\af15\super \ltrch \cs16\f11\fs16\super #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super +#}{\rtlch \af15 \ltrch HID_WAITTEXT}}}{\rtlch \af15 \ltrch \f11\fs16 Specifies how m}{\rtlch \af15 \ltrch \f11\fs16 +uch time will be elapsed since the screen saver started until it starts requiring a password to dismiss it. If you dismiss the screen saver in this time lapse you will not be required to enter a password. Enter a number in here or use the spin button (the +}{\rtlch \af15 \ltrch \f11\fs16 }{\rtlch \af15 \ltrch \f11\fs16 up and down arrows). +\par }{\rtlch \af15 \ltrch \f11\fs16 \page }{\rtlch \cs16\af15\super \ltrch \cs16\f11\fs16\super #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super +#}{\rtlch \af15 \ltrch HID_WAITBOX}}}{\rtlch \af15 \ltrch \f11\fs16 +Specifies how much time will be elapsed since the screen saver started until it starts requiring a password to dismiss it. If you dismiss the screen saver in this time lapse you will not be required to enter a password.}{\rtlch \af15 \ltrch \f11\fs16 + Click on }{\rtlch \ab\af15 \ltrch \b\f11\fs16 seconds}{\rtlch \af15 \ltrch \f11\fs16 so that the number in the text box on the left will represent seconds unit, or click on }{\rtlch \ab\af15 \ltrch \b\f11\fs16 minutes}{\rtlch \af15 \ltrch \f11\fs16 + so that it will represent minutes unit. +\par }{\rtlch \af15 \ltrch \f11\fs16 \page }{\rtlch \cs16\af15\super \ltrch \cs16\f11\fs16\super #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super +#}{\rtlch \af15 \ltrch HIDC_UL}}}{\rtlch \af15 \ltrch \f11\fs16 Click on the monitor control corner buttons to open a pop-up menu to select the }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Hot Corner}{\rtlch \ab\af15 \ltrch \b\f11\fs16 s}{\rtlch \af15 \ltrch +\f11\fs16 action of the corresponding screen corner. Choose }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Default}{\rtlch \af15 \ltrch \f11\fs16 to deactivate the }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Hot Corner}{\rtlch \af15 \ltrch \f11\fs16 + of that corner. Choose }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Now}{\rtlch \af15 \ltrch \f11\fs16 so that you can start the screen saver by taking the cursor to the corresponding corner or choose }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Never}{\rtlch \af15 +\ltrch \f11\fs16 so that the screen saver will never }{\rtlch \af15 \ltrch \f11\fs16 start while you hold the cursor close to that corner. +\par }{\rtlch \af15 \ltrch \f11\fs16 Note that you need to have installed in your computer a }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Hot Corners}{\rtlch \af15 \ltrch \f11\fs16 manager like Microsoft}{\rtlch \af15 \ltrch \f11\fs16 \rquote }{\rtlch \af15 \ltrch +\f11\fs16 s Plus! or compatible.}{\rtlch \af15 \ltrch \f11\fs16 +\par }{\rtlch \af15 \ltrch \f11\fs16 \page }{\rtlch \cs16\af15\super \ltrch \cs16\f11\fs16\super #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super +#}{\rtlch \af15 \ltrch HID_MUTE}}}{\rtlch \af15 \ltrch \f11\fs16 Check this to mute the screen saver while it is running.}{\rtlch \af15 \ltrch \f11\fs16 +\par }{\rtlch \af15 \ltrch \f11\fs16 \page #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super #}{\rtlch \af15 \ltrch HIDC_FLAT}}}{\rtlch \af15 +\ltrch \f11\fs16 Renders the clock model using }{\rtlch \ab\af15 \ltrch \b\f11\fs16 flat shading}{\rtlch \af15 \ltrch \f11\fs16 (only one color is calculated f}{\rtlch \af15 \ltrch \f11\fs16 or each polygon). +\par }{\rtlch \af15 \ltrch \f11\fs16 \page #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super #}{\rtlch \af15 \ltrch HIDC_GOURAUD}}}{\rtlch \af15 +\ltrch \f11\fs16 Renders the clock model using }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Gouraud shading}{\rtlch \af15 \ltrch \f11\fs16 (one color is calculated for each polygon vertex). +\par }{\rtlch \af15 \ltrch \f11\fs16 \page #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super #}{\rtlch \af15 \ltrch HIDC_ANTIALIAS}}}{\rtlch +\af15 \ltrch \f11\fs16 Improves lines and polygons edges by rendering with }{\rtlch \ab\af15 \ltrch \b\f11\fs16 antialiasing}{\rtlch \af15 \ltrch \f11\fs16 (ignored in OpenGL implementations that }{\rtlch \af15 \ltrch \f11\fs16 doesn't support it). + +\par }{\rtlch \af15 \ltrch \f11\fs16 Not recommended for computers without a 3D-acceleration card. +\par }{\rtlch \af15 \ltrch \f11\fs16 \page #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super #}{\rtlch \af15 \ltrch HIDC_BLEND}}}{\rtlch \af15 +\ltrch \f11\fs16 Blends the colors of the covering glass with the rest of the clock giving a glass impression. Without this option only the environment texture is visible and }{\rtlch \af15 \ltrch \f11\fs16 the clock interior is hidden. +\par }{\rtlch \af15 \ltrch \f11\fs16 \page #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super #}{\rtlch \af15 \ltrch HIDC_NORMALS}}}{\rtlch \af15 +\ltrch \f11\fs16 Shows the }{\rtlch \ab\af15 \ltrch \b\f11\fs16 normal}{\rtlch \af15 \ltrch \f11\fs16 vector to every polygon by drawing a small line segment. +\par }{\rtlch \af15 \ltrch \f11\fs16 Not recommended for computers without a 3D-acceleration card. +\par }{\rtlch \af15 \ltrch \f11\fs16 \page #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super #}{\rtlch \af15 \ltrch HIDC_WIREFRAME}}}{\rtlch +\af15 \ltrch \f11\fs16 Renders the clock model using shaded }{\rtlch \ab\af15 \ltrch \b\f11\fs16 wireframe}{\rtlch \af15 \ltrch \f11\fs16 instead}{\rtlch \af15 \ltrch \f11\fs16 + of filled polygons (if not implemented in hardware may slow down performance dramatically). +\par }{\rtlch \af15 \ltrch \f11\fs16 Not recommended for computers without a 3D-acceleration card. +\par }{\rtlch \af15 \ltrch \f11\fs16 \page #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super #}{\rtlch \af15 \ltrch HIDC_ZBUFFER}}}{\rtlch \af15 +\ltrch \f11\fs16 Activates the use of the }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Z-buffer}{\rtlch \af15 \ltrch \f11\fs16 . This option should be checked for normal behavior}{\rtlch \af15 \ltrch \f11\fs16 of the clock model. +\par }{\rtlch \af15 \ltrch \f11\fs16 \page #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super #}{\rtlch \af15 \ltrch HIDC_CULL}}}{\rtlch \af15 +\ltrch \f11\fs16 Activates the use of }{\rtlch \ab\af15 \ltrch \b\f11\fs16 backface culling}{\rtlch \af15 \ltrch \f11\fs16 . This option should be checked for normal behavior of the clock model. +\par }{\rtlch \af15 \ltrch \f11\fs16 \page #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super #}{\rtlch \af15 \ltrch HIDC_NOGLASS}}}{\rtlch \af15 +\ltrch \f11\fs16 Drops the clock's }{\rtlch \ab\af15 \ltrch \b\f11\fs16 covering glass}{\rtlch \af15 \ltrch \f11\fs16 . +\par }{\rtlch \af15 \ltrch \f11\fs16 Recommended for computers without a 3D-acceleration card. +\par }{\rtlch \af15 \ltrch \f11\fs16 \page #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super #}{\rtlch \af15 \ltrch HIDC_NOTEXTURES}}}{\rtlch +\af15 \ltrch \f11\fs16 Drops the }{\rtlch \ab\af15 \ltrch \b\f11\fs16 texture}{\rtlch \af15 \ltrch \f11\fs16 inside the clock. +\par }{\rtlch \af15 \ltrch \f11\fs16 Recommended for computers without a 3D-acceleration card. +\par }{\rtlch \af15 \ltrch \f11\fs16 \page #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super #}{\rtlch \af15 \ltrch HIDC_NEAREST}}}{\rtlch \af15 +\ltrch \f11\fs16 Click }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Nearest}{\rtlch \af15 \ltrch \f11\fs16 to use the worst texture filtering algorithm (recommended for computers without a 3D acceleration card). Click }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Linear} +{\rtlch \af15 \ltrch \f11\fs16 to use a better algorithm. +\par }{\rtlch \af15 \ltrch \f11\fs16 \page #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super #}{\rtlch \af15 \ltrch HIDC_WMIPMAPS}}}{\rtlch \af15 +\ltrch \f11\fs16 Click }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Without Mipmaps}{\rtlch \af15 \ltrch \f11\fs16 not to use mipmaps' algorithm when filtering textures. Click }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Nearest Mipmap}{\rtlch \af15 \ltrch \f11\fs16 + to use the closest mipmap level algorithm. Click }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Linear Between Mipmaps}{\rtlch \af15 \ltrch \f11\fs16 for the best mipmaps' algorithm. +\par }{\rtlch \ab\af15 \ltrch \b\f11\fs16 W}{\rtlch \ab\af15 \ltrch \b\f11\fs16 ithout Mipmaps}{\rtlch \af15 \ltrch \f11\fs16 is recommended for computers without a 3D-acceleration card. +\par }{\rtlch \af15 \ltrch \f11\fs16 \page }{\rtlch \cs16\af15\super \ltrch \cs16\f11\fs16\super #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super +#}{\rtlch \af15 \ltrch HIDC_ABOUT}}}{\rtlch \af15 \ltrch \f11\fs16 Shows the }{\rtlch \ab\af15 \ltrch \b\f11\fs16 About}{\rtlch \af15 \ltrch \f11\fs16 dialog with the version number, credits and copyright information. +\par }{\rtlch \af15 \ltrch \f11\fs16 \page }{\rtlch \cs16\af15\super \ltrch \cs16\f11\fs16\super #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super +#}{\rtlch \af15 \ltrch HIDC_QUICK}}}{\rtlch \af15 \ltrch \f11\fs16 Check }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Speed Up Clock }{\rtlch \af15 \ltrch \f11\fs16 to accelerate the rotation speed of the clock}{\rtlch \af15 \ltrch \f11\fs16 \rquote }{\rtlch +\af15 \ltrch \f11\fs16 s hands. With this option the clock won}{\rtlch \af15 \ltrch \f11\fs16 \rquote }{\rtlch \af15 \ltrch \f11\fs16 +t show the correct time anymore (until the option is cleared). It is used mainly to see and understand the rotation effect of the Moebius strip. +\par }{\rtlch \af15 \ltrch \f11\fs16 \page }{\rtlch \cs16\af15\super \ltrch \cs16\f11\fs16\super #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super +#}{\rtlch \af15 \ltrch HIDC_SWING}}}{\rtlch \af15 \ltrch \f11\fs16 Check }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Swing Clock}{\rtlch \af15 \ltrch \f11\fs16 to allow the clock}{\rtlch \af15 \ltrch \f11\fs16 \rquote }{\rtlch \af15 \ltrch \f11\fs16 +s rotation when the}{\rtlch \af15 \ltrch \f11\fs16 screen saver is running. With this option the clock will rotate back and forth in a fixed pattern around it}{\rtlch \af15 \ltrch \f11\fs16 \rquote }{\rtlch \af15 \ltrch \f11\fs16 s center. +\par }{\rtlch \af15 \ltrch \f11\fs16 \page }{\rtlch \cs16\af15\super \ltrch \cs16\f11\fs16\super #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super +#}{\rtlch \af15 \ltrch HIDC_USEMOUSE}}}{\rtlch \af15 \ltrch \f11\fs16 Check this option to allow mouse interaction during screen saving. While the screen saver is running drag the mouse wit}{\rtlch \af15 \ltrch \f11\fs16 +h the left button pressed to rotate the clock around it}{\rtlch \af15 \ltrch \f11\fs16 \rquote }{\rtlch \af15 \ltrch \f11\fs16 s center, and drag the mouse with the right button to roll the clock. Double click on the left mouse button to reset the clock}{ +\rtlch \af15 \ltrch \f11\fs16 \rquote }{\rtlch \af15 \ltrch \f11\fs16 s orientation to the default. Press a key on the keyboard to close the sc}{\rtlch \af15 \ltrch \f11\fs16 reen saver. +\par }{\rtlch \af15 \ltrch \f11\fs16 Note that if }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Swing Clock}{\rtlch \af15 \ltrch \f11\fs16 is checked, then the clock will rotate when you stop dragging the mouse. +\par }{\rtlch \af15 \ltrch \f11\fs16 \page }{\rtlch \cs16\af15\super \ltrch \cs16\f11\fs16\super #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super +#}{\rtlch \af15 \ltrch HIDC_BACK}}}{\rtlch \af15 \ltrch \f11\fs16 Check }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Backdrop}{\rtlch \af15 \ltrch \f11\fs16 to draw a background with gradient using the colors specified inside the monitor control to the left. + +\par }{\rtlch \af15 \ltrch \f11\fs16 \page }{\rtlch \cs16\af15\super \ltrch \cs16\f11\fs16\super #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super +#}{\rtlch \af15 \ltrch HIDC_SPIN1}}}{\rtlch \af15 \ltrch \f11\fs16 Use the spin controls (the two arrow buttons) to choose the number of }{\rtlch \ab\af15 \ltrch \b\f11\fs16 twists}{\rtlch \af15 \ltrch \f11\fs16 + that the strip will have. The strip will actually be a }{\rtlch \ab\af15 \ltrch \b\f11\fs16 Moebius strip}{\rtlch \af15 \ltrch \f11\fs16 if the number of twists is odd. The number of twists is limited between 0 and 9. +\par }{\rtlch \af15 \ltrch \f11\fs16 \page }{\rtlch \cs16\af15\super \ltrch \cs16\f11\fs16\super #{\footnote \ltrpar \ql \pard\plain \ltrpar\ql \s15\ql\nowidctlpar\widctlpar\adjustright \rtlch\af15\afs20 \ltrch\fs20 {\rtlch \cs16\af15\super \ltrch \cs16\super +#}{\rtlch \af15 \ltrch HIDC_COLOR1}}}{\rtlch \af15 \ltrch \f11\fs16 Use this to s}{\rtlch \af15 \ltrch \f11\fs16 elect the four colors that will be used with the backdrop}{\rtlch \af15 \ltrch \f11\fs16 \rquote }{\rtlch \af15 \ltrch \f11\fs16 +s gradient. Press on the sunken square color areas in the monitor control corners to open the color selection dialog. The color selected will be shown on the sunken areas. +\par }} \ No newline at end of file diff --git a/MoebiusScreenSaver.sln b/MoebiusScreenSaver.sln new file mode 100644 index 0000000..de32ab3 --- /dev/null +++ b/MoebiusScreenSaver.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MoebiusScreenSaver", "MoebiusScreenSaver.vcproj", "{222966EC-A4AB-4FAC-8A40-8266695C44B6}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {222966EC-A4AB-4FAC-8A40-8266695C44B6}.Debug.ActiveCfg = Debug|Win32 + {222966EC-A4AB-4FAC-8A40-8266695C44B6}.Debug.Build.0 = Debug|Win32 + {222966EC-A4AB-4FAC-8A40-8266695C44B6}.Release.ActiveCfg = Release|Win32 + {222966EC-A4AB-4FAC-8A40-8266695C44B6}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/MoebiusScreenSaver.suo b/MoebiusScreenSaver.suo new file mode 100644 index 0000000..badb7e2 Binary files /dev/null and b/MoebiusScreenSaver.suo differ diff --git a/MoebiusScreenSaver.vcproj b/MoebiusScreenSaver.vcproj new file mode 100644 index 0000000..5285c63 --- /dev/null +++ b/MoebiusScreenSaver.vcproj @@ -0,0 +1,429 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenGLenv.cpp b/OpenGLenv.cpp new file mode 100644 index 0000000..1368a35 --- /dev/null +++ b/OpenGLenv.cpp @@ -0,0 +1,931 @@ +//========================================================================== +// +// File: OpenGLenv.cpp +// +//========================================================================== + +#define _USE_MATH_DEFINES +#include +#include +#include "OpenGLenv.h" +#include "texture.h" +#include "resource.h" +#include "SaverSettings.h" + +#define max3(a, b, c) (max(max((a), (b)), (c))) + +extern SaverSettings* ss; + +/****************************************************************************/ + +// Colors +const GLfloat no_color[]= { 0.0, 0.0, 0.0, 0.0 }; +const GLfloat black[]= { 0.0, 0.0, 0.0, 1.0 }; +const GLfloat white[]= { 1.0, 1.0, 1.0, 1.0 }; +const GLfloat gray5[]= { 0.5, 0.5, 0.5, 1.0 }; +const GLfloat gray25[]= { 0.25, 0.25, 0.25, 1.0 }; +const GLfloat gray75[]= { 0.75, 0.75, 0.75, 1.0 }; +const GLfloat gray125[]= { 0.125, 0.125, 0.125, 1.0 }; +const GLfloat gray375[]= { 0.375, 0.375, 0.375, 1.0 }; +const GLfloat gray625[]= { 0.625, 0.625, 0.625, 1.0 }; +const GLfloat gray875[]= { 0.875, 0.875, 0.875, 1.0 }; +const GLfloat red[]= { 1.0, 0.0, 0.0, 1.0 }; +const GLfloat red5[]= { 0.5, 0.0, 0.0, 1.0 }; +const GLfloat green[]= { 0.0, 1.0, 0.0, 1.0 }; +const GLfloat green5[]= { 0.0, 0.5, 0.0, 1.0 }; +const GLfloat green25[]= { 0.0, 0.25, 0.0, 1.0 }; +const GLfloat green75[]= { 0.0, 0.75, 0.0, 1.0 }; +const GLfloat blue[]= { 0.0, 0.0, 1.0, 1.0 }; +const GLfloat blue5[]= { 0.0, 0.0, 0.5, 1.0 }; +const GLfloat yellow[]= { 1.0, 1.0, 0.0, 1.0 }; +const GLfloat yellow5[]= { 0.5, 0.5, 0.0, 1.0 }; +const GLfloat yellow25[]= { 0.25, 0.25, 0.0, 1.0 }; +const GLfloat yellow75[]= { 0.75, 0.75, 0.0, 1.0 }; +const GLfloat magenta[]= { 1.0, 0.0, 1.0, 1.0 }; +const GLfloat magenta5[]= { 0.5, 0.0, 0.5, 1.0 }; +const GLfloat cyan[]= { 0.0, 1.0, 1.0, 1.0 }; +const GLfloat cyan5[]= { 0.0, 0.5, 0.5, 1.0 }; +const GLfloat orange[]= { 1.0, 0.8f, 0.0, 1.0 }; +const GLfloat gold[]= { 1.0, 0.8f, 0.5, 1.0 }; +const GLfloat copper[]= { 0.5, 0.3f, 0.125, 1.0 }; + +// Tranlucent colors +const GLfloat white_5[]= { 1.0, 1.0, 1.0, 0.5 }; +const GLfloat white_25[]= { 1.0, 1.0, 1.0, 0.25 }; +const GLfloat white_75[]= { 1.0, 1.0, 1.0, 0.75 }; + +// Texture filter methods +const GLenum filter[2][3]= { + GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, + GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR +}; + +// Constants +const double step= M_PI / 120.0; +const double R= 10.0, h= 1.0; +const double epsilon= 0.001; +const double t0= M_PI, dt0= 0.0; + +// Global variables +GLuint hours[4], envmap, face; // Texture objects +GLuint frisbee, disc, rim; // Display lists +struct { + double msec, sec, min, hour, day; +} time; +double t= t0, dt= dt0; +double alpha= 1.0; + +int frames= 0; + +/****************************************************************************/ + +void +EnableGraphicOption(GLenum which, BOOL bEnable) +{ + if (bEnable) glEnable(which); + else glDisable(which); +} + +/****************************************************************************/ + +void +ResetOrientationGraphicEnv() +{ + glLoadIdentity(); + glTranslatef(0.0, 0.0, -25.0); + t = t0; + dt= dt0; +} + +/****************************************************************************/ + +void +MotionOfGraphicEnv(POINT* pAnchor, POINT mouse, BOOL roll) +{ + double dx = mouse.x - pAnchor->x, dy = mouse.y - pAnchor->y; + double distance = sqrt(dx * dx + dy * dy); + double u[3]= { + roll ? 0.0 : dy, + roll ? 0.0 : dx, + roll ? -dx : 0.0 + }; + double M[4][4], v[3]= { 0.0, 0.0, 0.0 }; + + glGetDoublev(GL_MODELVIEW_MATRIX, (GLdouble *) M); + + for (int i= 0; i < 3; i++) + for (int j= 0; j < 3; j++) + v[i]+= M[i][j] * u[j]; + + glRotated(0.25 * distance, v[0], v[1], v[2]); + + pAnchor->x = mouse.x; + pAnchor->y = mouse.y; +} + +/****************************************************************************/ + +static BOOL +bSetupPixelFormat(HDC hdc) +{ + PIXELFORMATDESCRIPTOR pfd, *ppfd; + int pixelformat; + + ppfd = &pfd; + memset(&pfd, 0, sizeof(pfd)); + + ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR); + ppfd->nVersion = 1; + ppfd->dwFlags = PFD_DRAW_TO_WINDOW | + PFD_SUPPORT_OPENGL | + PFD_DOUBLEBUFFER; + + ppfd->iPixelType= PFD_TYPE_RGBA; + ppfd->cColorBits= 32; + + pixelformat = ChoosePixelFormat(hdc, &pfd); + if (pixelformat == 0) + { + MessageBox( + NULL, "ChoosePixelFormat() failed: " + "Cannot find a suitable pixel format.", "Error", MB_OK + ); + return 0; + } + + if (SetPixelFormat(hdc, pixelformat, &pfd) == FALSE) + { + MessageBox( + NULL, "SetPixelFormat() failed: " + "Cannot set format specified.", "Error", MB_OK + ); + return 0; + } + DescribePixelFormat(hdc, pixelformat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + + return TRUE; +} + +/****************************************************************************/ + +BOOL +InitGraphicEnv(HWND wnd, HDC* phdc, HGLRC* phglrc) +{ + // Get the windows device context + *phdc = GetDC(wnd); + if (!bSetupPixelFormat(*phdc)) + return FALSE; + + *phglrc = wglCreateContext(*phdc); + wglMakeCurrent(*phdc, *phglrc); + + return TRUE; +} + +/****************************************************************************/ + +void +DestroyGraphicEnv(HWND hwnd, HDC hdc, HGLRC hglrc) +{ + wglMakeCurrent(NULL, NULL); + wglDeleteContext(hglrc); + ReleaseDC(hwnd, hdc); +} + +/****************************************************************************/ + +void +InitState() +{ + // Polygon Mode + glPolygonMode(GL_FRONT_AND_BACK, ss->state.nPolygonMode); + + // Material properties + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white); + glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 128); + glEnable(GL_COLOR_MATERIAL); // for ambient and diffuse reflection + + // Lighting + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHTING); + + // Face Culling + EnableGraphicOption(GL_CULL_FACE, ss->state.bCulling); + + // Blending + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + // Antialiasing + EnableGraphicOption(GL_LINE_SMOOTH, ss->state.bSmooth); + EnableGraphicOption(GL_POLYGON_SMOOTH, ss->state.bSmooth); + + // Z-Buffering + EnableGraphicOption(GL_DEPTH_TEST, ss->state.bDepthTest); + + // Perspective Correction Hint + glHint(GL_PERSPECTIVE_CORRECTION_HINT, ss->state.nPerspCorrectionHint); + + // Shade Model + glShadeModel(ss->state.nShadeModel); + + // Line Smooth Hint + glHint(GL_LINE_SMOOTH_HINT, ss->state.nLineSmoothHint); + + // Clear Color + glClearColor(0.0, 0.0, 0.0, 1.0); + + // Clear Depth + glClearDepth(1.0); + + // Model/View + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -25.0); +} + +/****************************************************************************/ + +void +init_hours_texture(HWND hwnd, HDC hdc) +{ + + int width, height; + HBITMAP hbitmap; + BITMAPINFO bitmapinfo; + unsigned char* texture; + unsigned char* bitmap; + unsigned char *p, *q; + + glGenTextures(4, hours); + + hbitmap = (HBITMAP)LoadImage( + (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), + MAKEINTRESOURCE(IDB_HOURS0), IMAGE_BITMAP, + 0, 0, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION + ); + bitmapinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bitmapinfo.bmiHeader.biPlanes = 1; + bitmapinfo.bmiHeader.biBitCount = 0; + GetDIBits(hdc, hbitmap, 0, 0, NULL, &bitmapinfo, DIB_RGB_COLORS); + width = bitmapinfo.bmiHeader.biWidth; + height = bitmapinfo.bmiHeader.biHeight; + bitmap = new unsigned char[bitmapinfo.bmiHeader.biSizeImage]; + texture = new unsigned char[width * height * 4]; + for (int i=0; i < 4; i++) + { + if (i > 0) + hbitmap = (HBITMAP)LoadImage( + (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), + MAKEINTRESOURCE(IDB_HOURS0+i), IMAGE_BITMAP, + 0, 0, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION + ); + GetDIBits(hdc, hbitmap, 0, height, (LPVOID)bitmap, &bitmapinfo, DIB_RGB_COLORS); + p = texture; + q = bitmap; + for (int j=0; j < width*height; j++) + { + *(p++) = *(q++); + *(p++) = *(q++); + *(p++) = *(q++); + *(p) = max3( *(p-1), *(p-2), *(p-3) ); + p++; + } + glBindTexture(GL_TEXTURE_2D, hours[i]); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + gluBuild2DMipmaps(GL_TEXTURE_2D, 4, width, height, GL_RGBA, GL_UNSIGNED_BYTE, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + DeleteObject(hbitmap); + } + delete[] texture; + delete[] bitmap; +} + +/****************************************************************************/ + +void +loadTextureFromFile(GLuint &object, const char *filename) +{ + int width, height, components; + + unsigned char *texture= readTexture(filename, &width, &height, &components); + if (texture == NULL) + { + //logfile << "Failed to read " << filename << "\n"; + exit(-1); + } + glGenTextures(1, &object); + glBindTexture(GL_TEXTURE_2D, object); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + int err= gluBuild2DMipmaps(GL_TEXTURE_2D, 4, width, height, GL_RGBA, GL_UNSIGNED_BYTE, texture); + if (err != 0) + { + const unsigned char *errstr= gluErrorString(err); + //logfile << "Mipmap error: " << errstr << "\n"; + } + free(texture); + + //check_for_gl_error("creating texture #%d from %s", object, filename); +} + +/****************************************************************************/ + +void +loadTextureFromResource(HWND hwnd, HDC hdc, GLuint& object, UINT bitmapResID) +{ + int width, height; + HBITMAP hbitmap; + BITMAPINFO bitmapinfo; + unsigned char* texture; + + hbitmap = (HBITMAP)LoadImage( + (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), + MAKEINTRESOURCE(bitmapResID), IMAGE_BITMAP, + 0, 0, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION + ); + bitmapinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bitmapinfo.bmiHeader.biPlanes = 1; + bitmapinfo.bmiHeader.biBitCount = 0; + GetDIBits(hdc, hbitmap, 0, 0, NULL, &bitmapinfo, DIB_RGB_COLORS); + width = bitmapinfo.bmiHeader.biWidth; + height = bitmapinfo.bmiHeader.biHeight; + texture = new unsigned char[bitmapinfo.bmiHeader.biSizeImage]; + + GetDIBits(hdc, hbitmap, 0, height, (LPVOID)texture, &bitmapinfo, DIB_RGB_COLORS); + + glGenTextures(1, &object); + glBindTexture(GL_TEXTURE_2D, object); + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, texture); + + delete[] texture; + DeleteObject(hbitmap); +} + +/****************************************************************************/ + +void +InitTexture(HWND hwnd, HDC hdc) +{ + init_hours_texture(hwnd, hdc); + if (!ss->state.bNoGlass) + { + loadTextureFromResource(hwnd, hdc, envmap, IDB_CAFE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + if (!ss->state.bNoExtraTextures) + { + loadTextureFromResource(hwnd, hdc, face, IDB_OGLLOGO); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } +} + +/****************************************************************************/ + +void +draw_backdrop() +{ + GLfloat firstColor[4]; + GLfloat secondColor[4]; + GLfloat thirdColor[4]; + GLfloat fourthColor[4]; + + firstColor[0] = ss->state.fColorR[0]; + firstColor[1] = ss->state.fColorG[0]; + firstColor[2] = ss->state.fColorB[0]; + secondColor[0] = ss->state.fColorR[1]; + secondColor[1] = ss->state.fColorG[1]; + secondColor[2] = ss->state.fColorB[1]; + thirdColor[0] = ss->state.fColorR[2]; + thirdColor[1] = ss->state.fColorG[2]; + thirdColor[2] = ss->state.fColorB[2]; + fourthColor[0] = ss->state.fColorR[3]; + fourthColor[1] = ss->state.fColorG[3]; + fourthColor[2] = ss->state.fColorB[3]; + firstColor[3] = secondColor[3] = thirdColor[3] = fourthColor[3] = 1.0f; + + glPushAttrib(GL_ENABLE_BIT); + glDisable(GL_LIGHTING); + + glPushMatrix(); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -40.0); + + glBegin(GL_QUADS); + { + glColor4fv(fourthColor); + glVertex2f(-30.0, -20.0); + glColor4fv(thirdColor); + glVertex2f(+30.0, -20.0); + glColor4fv(secondColor); + glVertex2f(+30.0, +20.0); + glColor4fv(firstColor); + glVertex2f(-30.0, +20.0); + } + glEnd(); + + glPopMatrix(); + + glPopAttrib(); +} + +/****************************************************************************/ + +void +draw_frisbee() +{ + glPushAttrib(GL_ENABLE_BIT); + glEnable(GL_NORMALIZE); + + glPushMatrix(); + glScalef(1.0, 1.0, 0.2f); + + glBegin(GL_TRIANGLE_FAN); + { + glNormal3d(0.0, 0.0, 1.0); + glVertex3d(0.0, 0.0, R); + + const double r= R * sin(step); + const double z= R * cos(step); + + for (double f= -M_PI; f < +M_PI + epsilon; f+= step) + { + const double x= r * cos(f), y= r * sin(f); + + glNormal3d(x, y, z); + glVertex3d(x, y, z); + } + } + glEnd(); + + for (double t= step; t < 0.5 * M_PI - epsilon; t+= step) + { + const double r0= R * sin(t), r1= R * sin(t + step); + const double z0= R * cos(t), z1= R * cos(t + step); + + glBegin(GL_TRIANGLE_STRIP); + { + for (double f= -M_PI; f < +M_PI + epsilon; f+= step) + { + const double x0= r0 * cos(f), x1= r1 * cos(f); + const double y0= r0 * sin(f), y1= r1 * sin(f); + + glNormal3d(x0, y0, z0); + glVertex3d(x0, y0, z0); + glNormal3d(x1, y1, z1); + glVertex3d(x1, y1, z1); + } + } + glEnd(); + } + + glPopMatrix(); + glPopAttrib(); +} + +/****************************************************************************/ + +double texx(double x, double y) +{ + return x; +} + +double texy(double x, double y) +{ + return y; +} + +/****************************************************************************/ + +void +draw_disc() +{ + const double R= 9.9; + const double dr= R / 6.0; + + glNormal3f(0.0, 0.0, 1.0); + + glBegin(GL_TRIANGLE_FAN); + { + glTexCoord2d(texx(0.0, 0.0), texy(0.0, 0.0)); + glVertex2d(0.0, 0.0); + for (double t= 0.0; t < 2 * M_PI + epsilon; t+= step) + { + double x= dr * cos(t), y= dr * sin(t); + glTexCoord2d(texx(x / R, y / R), texy(x / R, y / R)); + glVertex2d(x, y); + } + } + glEnd(); + + for (double r= dr; r < R - epsilon; r+= dr) + { + glBegin(GL_TRIANGLE_STRIP); + { + for (double t= 0.0; t < 2 * M_PI + epsilon; t+= step) + { + double x0= r * cos(t), y0= r * sin(t); + glTexCoord2d(texx(x0 / R, y0 / R), texy(x0 / R, y0 / R)); + glVertex2d(x0, y0); + + double x1= (r + dr) * cos(t), y1= (r + dr) * sin(t); + glTexCoord2d(texx(x1 / R, y1 / R), texy(x1 / R, y1 / R)); + glVertex2d(x1 ,y1); + } + } + glEnd(); + } +} + +/****************************************************************************/ + +void +draw_rim() +{ + glBegin(GL_TRIANGLE_STRIP); + { + for (double t= 0.0; t < 2 * M_PI + epsilon; t+= step) + { + glNormal3d(cos(t), sin(t), 0.0); + glVertex3d(R * cos(t), R * sin(t), +h); + glVertex3d(R * cos(t), R * sin(t), -h); + } + } + glEnd(); +} + +/****************************************************************************/ + +void +draw_hours_strip(int base) +{ + const double R= 9.0, h= 1.0; + const double torsion= 2 * ss->state.nTwists * M_PI * time.day; + const GLfloat *color[]= { blue, green, yellow, red }; + + for (int i= 0; i < 2; i++) + { + glPushAttrib(GL_ENABLE_BIT); + glEnable(GL_TEXTURE_2D); + + + glBindTexture(GL_TEXTURE_2D, hours[base + i]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter[ss->state.nLinear][ss->state.nMipmap]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter[ss->state.nLinear][0]); + + glBegin(GL_TRIANGLE_STRIP); + { + for (float s= 0.0; s < 1.0 + epsilon; s+= float(step / M_PI)) + { + double t= (double(i) + s) * M_PI; + double tt= ss->state.nTwists * 0.5 * t - torsion; + double ct= cos(t), st= sin(t); + double ctt= cos(tt), stt= sin(tt); + double r1= R - h * ctt; + double r2= R + h * ctt; + double z1= -h * stt; + double z2= +h * stt; + + GLfloat vcolor[4]; + + for (int k = 0; k < 4; k++) + { + vcolor[k] = (1 - s) * color[base + i][k] + s * color[(base + i + 1) % 4][k]; + } + + glColor4fv(vcolor); + glNormal3d(-st * stt, -ct * stt, ct * ct * ctt + ctt * st * st); + + glTexCoord2d(t / M_PI, 0.0); + glVertex3d(r2 * st, r2 * ct, z2); + glTexCoord2d(t / M_PI, 1.0); + glVertex3d(r1 * st, r1 * ct, z1); + } + } + glEnd(); + + glPopAttrib(); + + if (ss->state.bNormals) + { + glPushAttrib(GL_LIGHTING_BIT); + glDisable(GL_LIGHTING); + glColor4fv(white); + + glBegin(GL_LINES); + { + for (double t= i * M_PI; t < (i + 1) * M_PI + epsilon; t+= M_PI / 24) + { + double tt= ss->state.nTwists * 0.5 * t - torsion; + double ct= cos(t), st= sin(t); + double ctt= cos(tt), stt= sin(tt); + double r1= R - h * ctt; + double r2= R + h * ctt; + double z1= -h * stt; + double z2= +h * stt; + + double n[3]= { -st * stt, -ct * stt, ct * ct * ctt + ctt * st * st }; + + glVertex3d(r2 * st, r2 * ct, z2); + glVertex3d(r2 * st + n[0], r2 * ct + n[1], z2 + n[2]); + glVertex3d(r1 * st, r1 * ct, z1); + glVertex3d(r1 * st + n[0], r1 * ct + n[1], z1 + n[2]); + } + } + glEnd(); + + glPopAttrib(); + } + } +} + +/****************************************************************************/ + +void +draw_hand(GLdouble rotation, GLdouble length, GLdouble width) +{ + glPushMatrix(); + glRotated(rotation, 0.0, 0.0, 1.0); + + glNormal3d(0.0, 0.0, 1.0); + glRectd(-width, -0.2 * length, +width, +length); + + glPopMatrix(); +} + +/****************************************************************************/ + +void +draw_cap() +{ + const double R= 0.5, h= 0.1; + const double norm= sqrt(h * h + R * R); + const double nR= R / norm, nh= h / norm; + + glBegin(GL_TRIANGLE_FAN); + { + glNormal3d(0.0, 0.0, 1.0); + glVertex3d(0.0, 0.0, h); + for (double t= 0.0; t < 2 * M_PI + epsilon; t+= 4 * step) + { + glNormal3d(nh * cos(t), nh * sin(t), nR); + glVertex2d(R * cos(t), R * sin(t)); + } + } + glEnd(); +} + +/****************************************************************************/ + +void +draw_face() +{ + if (!ss->state.bNoExtraTextures) + { + glPushAttrib(GL_ENABLE_BIT); + glEnable(GL_TEXTURE_2D); + + glBindTexture(GL_TEXTURE_2D, face); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter[ss->state.nLinear][ss->state.nMipmap]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter[ss->state.nLinear][0]); + glCallList(disc); + + glPopAttrib(); + } + else + { + glPushAttrib(GL_LIGHTING_BIT | GL_POLYGON_BIT); + glDisable(GL_LIGHTING); + glColor4fv(black); + glCallList(disc); + glPopAttrib(); + } +} + +/****************************************************************************/ + +void +draw_glass() +{ + glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT); + glDisable(GL_POLYGON_SMOOTH); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); + + glBindTexture(GL_TEXTURE_2D, envmap); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter[ss->state.nLinear][ss->state.nMipmap]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter[ss->state.nLinear][0]); + glCallList(frisbee); + + glPopAttrib(); +} + +/****************************************************************************/ + +void +draw_clock() +{ + // Inside of rim + glPushAttrib(GL_LIGHTING_BIT | GL_POLYGON_BIT); + glColor4fv(gold); + glCullFace(GL_FRONT); + glCallList(rim); + glPopAttrib(); + + // Face + glColor4fv(gold); + glPushMatrix(); + glTranslated(0.0, 0.0, -h); + draw_face(); + glPopMatrix(); + + // Hours strip + glPushAttrib(GL_POLYGON_BIT); + glCullFace(GL_BACK); + draw_hours_strip(0); + glCullFace(GL_FRONT); + draw_hours_strip(2); + glPopAttrib(); + + glPushAttrib(GL_LIGHTING_BIT); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, gray5); + + glPushMatrix(); + + // Hours hand + glColor4fv(gray25); + draw_hand(-30.0 * time.hour, 5.0, 0.1f); + glTranslatef(0.0, 0.0, 0.2f); + + // Minutes hand + glColor4fv(gray25); + draw_hand(-6.0 * time.min, 7.0, 0.1f); + glTranslatef(0.0, 0.0, 0.2f); + + // Seconds hand + glColor4fv(red5); + draw_hand(-6.0 * time.sec, 8.0, 0.02f); + glTranslatef(0.0, 0.0, 0.2f); + + // Hands axis cap + glColor4fv(gray125); + draw_cap(); + + glPopMatrix(); + + glPopAttrib(); + + // Case + glPushAttrib(GL_LIGHTING_BIT); + glMateriali(GL_FRONT, GL_SHININESS, 32); + glColor4fv(copper); + glPushMatrix(); + glRotated(180.0, 0.0, 1.0, 0.0); + glTranslated(0.0, 0.0, +h); + glCallList(frisbee); + glPopMatrix(); + glCallList(rim); + glPopAttrib(); + + if (!ss->state.bNoGlass) + { + // Fade Glass + alpha= alpha + ss->state.da; + alpha= min(alpha, 1.0); + alpha= max(alpha, 0.3); + + void (__stdcall *proc[2])(GLenum)= { glDisable, glEnable }; + + proc[alpha < 1.0](GL_BLEND); + + // Glass cover + glPushMatrix(); + glTranslated(0.0, 0.0, +h); + glColor4d(1.0, 1.0, 1.0, alpha); + draw_glass(); + glPopMatrix(); + } +} + +/****************************************************************************/ + +void +InitDisplayLists() +{ + frisbee = glGenLists(1); + glNewList(frisbee, GL_COMPILE); + { + draw_frisbee(); + } + glEndList(); + + disc = glGenLists(1); + glNewList(disc, GL_COMPILE); + { + draw_disc(); + } + glEndList(); + + rim = glGenLists(1); + glNewList(rim, GL_COMPILE); + { + draw_rim(); + } + glEndList(); +} + +/****************************************************************************/ + +void +Display(HDC hdc) +{ + static BOOL bfirstTime = TRUE; + + const double xrot = 30 * (1.0 + cos(t)); + const double zrot = 30 * sin(t); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotated(xrot, 1.0, 0.0, 0.0); + glRotated(zrot, 0.0, 0.0, 1.0); + + if (!ss->state.bBlackBackground) + draw_backdrop(); + draw_clock(); + + glPopMatrix(); + + if (ss->state.bSwing) + { + t+= dt; + dt+= -0.001 * t; + } + + SwapBuffers(hdc); + + frames++; +} + +/****************************************************************************/ + +void +Reshape(HDC hdc, int width, int height) +{ + const double w= width, h= height; + const double aspect= w / h; + double fw, fh; + + glViewport(0, 0, width, height); + + glPushAttrib(GL_TRANSFORM_BIT); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + if (width < height) + { + fw= 0.5; + fh= fw / aspect; + } + else + { + fh= 0.5; + fw= fh * aspect; + } + + glFrustum(-fw, +fw, -fh, +fh, 1.0, 100.0); + + glPopAttrib(); +} + +/****************************************************************************/ + +void +UpdateTime() +{ + SYSTEMTIME systime; + + GetLocalTime(&systime); + time.msec = (double) systime.wMilliseconds; + time.sec = (double) systime.wSecond + time.msec / 1000.0; + time.min = (double) systime.wMinute + time.sec / 60.0; + time.hour = (double) systime.wHour + time.min / 60.0; + time.day = time.hour / 24.0; + if (ss->state.bQuick) + { + time.sec= 0.0; + time.min*= 900.0; + time.hour*= 900.0; + time.day*= 900.0; + } +} + diff --git a/OpenGLenv.h b/OpenGLenv.h new file mode 100644 index 0000000..a1ff8b7 --- /dev/null +++ b/OpenGLenv.h @@ -0,0 +1,76 @@ +//========================================================================== +// +// File: OpenGLenv.h +// +//========================================================================== + +#ifndef OPENGLENV_H +#define OPENGLENV_H + +#include +#include +#include + +/****************************************************************************/ + +class GraphicEnvState +{ +public: + GraphicEnvState() : + nLinear(1), nMipmap(2), da(-0.02f), bBlend(TRUE), nTwists(3), + bNormals(FALSE), bQuick(FALSE), bSwing(TRUE), bBlackBackground(TRUE), + bCulling(TRUE), bSmooth(TRUE), bDepthTest(TRUE), bUseMouse(FALSE), + bNoGlass(FALSE), bNoExtraTextures(FALSE), + nLineSmoothHint(GL_FASTEST), nShadeModel(GL_SMOOTH), + nPerspCorrectionHint(GL_FASTEST), nPolygonMode(GL_FILL) + { + fColorR[0] = fColorR[1] = 1.0f; // red - top corners + fColorG[0] = fColorG[1] = 0.0f; + fColorB[0] = fColorB[1] = 0.0f; + fColorR[2] = fColorR[3] = 1.0f; // orange - bottom corners + fColorG[2] = fColorG[3] = 0.8f; + fColorB[2] = fColorB[3] = 0.0f; + }; + + short nLinear; + short nMipmap; + short nTwists; // Number of 180-degree twists + float da; + BOOL bBlend; + BOOL bNormals; + BOOL bQuick; + BOOL bSwing; + BOOL bCulling; + BOOL bSmooth; + BOOL bDepthTest; + BOOL bBlackBackground; + BOOL bUseMouse; + BOOL bNoGlass; + BOOL bNoExtraTextures; + GLint nLineSmoothHint; // GL_NICEST or GL_FASTEST + GLint nShadeModel; // GL_SMOOTH or GL_FLAT + GLint nPerspCorrectionHint; // GL_NICEST or GL_FASTEST + GLint nPolygonMode; // GL_FILL or GL_LINE + float fColorR[4]; + float fColorG[4]; + float fColorB[4]; +}; + +/****************************************************************************/ + +BOOL InitGraphicEnv(HWND wnd, HDC* phdc, HGLRC* phglrc); +void DestroyGraphicEnv(HWND hwnd, HDC hdc, HGLRC hglrc); +void EnableGraphicOption(GLenum which, BOOL bEnable); +void ResetOrientationGraphicEnv(); +void MotionOfGraphicEnv(POINT* pAnchor, POINT mouse, BOOL roll); + +void InitState(); +void InitTexture(HWND hwnd, HDC hdc); +void InitDisplayLists(); + +void Display(HDC hdc); +void Reshape(HDC hdc, int width, int height); + +void UpdateTime(); + +#endif diff --git a/Password.cpp b/Password.cpp new file mode 100644 index 0000000..1729c1c --- /dev/null +++ b/Password.cpp @@ -0,0 +1,72 @@ +//========================================================================== +// +// File: Password.cpp +// +//========================================================================== + +#include "Password.h" +#include "Debug.h" + +//****************************************************************************************** + +BOOL +VerifyPassword(HWND hwnd) +{ + // Under NT, we return TRUE immediately. This lets the saver quit, + // and the system manages passwords. + // Under '95, we call VerifyScreenSavePwd. + // This checks the appropriate registry key and, if necessary, + // pops up a verify dialog + OSVERSIONINFO osv; + + osv.dwOSVersionInfoSize = sizeof(osv); + GetVersionEx(&osv); + if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT) + return TRUE; + + HINSTANCE hpwdcpl = ::LoadLibrary("PASSWORD.CPL"); + if (hpwdcpl == NULL) + { + Debug("Unable to load PASSWORD.CPL. Aborting"); + return TRUE; + } + typedef BOOL (WINAPI *VERIFYSCREENSAVEPWD)(HWND hwnd); + VERIFYSCREENSAVEPWD VerifyScreenSavePwd; + VerifyScreenSavePwd = + (VERIFYSCREENSAVEPWD)GetProcAddress(hpwdcpl, "VerifyScreenSavePwd"); + if (VerifyScreenSavePwd == NULL) + { + Debug("Unable to get VerifyPwProc address. Aborting"); + FreeLibrary(hpwdcpl); + return TRUE; + } + Debug("About to call VerifyPwProc"); + BOOL bres = VerifyScreenSavePwd(hwnd); + FreeLibrary(hpwdcpl); + return bres; +} + +//****************************************************************************************** + +void +ChangePassword(HWND hwnd) +{ + // This only ever gets called under '95, when started with the /a option. + HINSTANCE hmpr = ::LoadLibrary("MPR.DLL"); + if (hmpr == NULL) + { + Debug("MPR.DLL not found: cannot change password."); + return; + } + typedef VOID (WINAPI *PWDCHANGEPASSWORD) (LPCSTR lpcRegkeyname, HWND hwnd, UINT uiReserved1, UINT uiReserved2); + PWDCHANGEPASSWORD PwdChangePassword = + (PWDCHANGEPASSWORD)::GetProcAddress(hmpr, "PwdChangePasswordA"); + if (PwdChangePassword == NULL) + { + FreeLibrary(hmpr); + Debug("PwdChangeProc not found: cannot change password"); + return; + } + PwdChangePassword("SCRSAVE", hwnd, 0, 0); + FreeLibrary(hmpr); +} diff --git a/Password.h b/Password.h new file mode 100644 index 0000000..4604046 --- /dev/null +++ b/Password.h @@ -0,0 +1,20 @@ +//========================================================================== +// +// File: Password.h +// +//========================================================================== + +#ifndef PASSWORD_H +#define PASSWORD_H + +#include + +//****************************************************************************************** + +BOOL VerifyPassword(HWND hwnd); +void ChangePassword(HWND hwnd); + +//****************************************************************************************** + +#endif + diff --git a/Readme.txt b/Readme.txt new file mode 100644 index 0000000..abb8a6e --- /dev/null +++ b/Readme.txt @@ -0,0 +1,116 @@ +------------------------------------------------------------------------------- +Moebius Clock Screen Saver v 1.7 README.TXT November 1999 + Copyright (c) 1999-2000 by Uriel Cohen & Ron Inbar. +------------------------------------------------------------------------------- + +I. INTRODUCTION + Thank you for trying the Moebius Clock Screen Saver! This file contains + installation/removal instructions, requirements and a brief help section. + + +II. CONTENTS + 1. INTRODUCTION + A. THE CLOCK CONCEPT + B. THE SCREEN SAVER + 2. REQUIREMENTS + 3. INSTALLATION INSTRUCTIONS + 4. REMOVING INSTRUCTIONS + 5. CREDITS + + +1. INTRODUCTION + + A. THE CLOCK CONCEPT + The Moebius Clock is an original clock concept designed to show the 24 hours + with regular clock hands and without addins showing AM or PM time. Instead of + a regular flat ring of numbers (the 12 numbers) it has a vertical Moebius + strip with the 24 numbers on it. + The Moebius strip is a circular strip which was twisted before being closed + (before one extreme was connected with the other). If you follow one side of + it with your finger along the strip you will finish where you started. Thus, + we say that the Moebius strip has no inside or outside. + The Moebius Clock has the 24 hours numbers arranged on a Moebius strip on such + a way that numbers with 12 hours difference fall back to back (for example 2:00 + and 14:00; 2:00 AM and PM). + The hours hand will turn normaly, and will show the hour where we expect it to + point. The Moebius strip at that point will have the correct number (in the 24 + hours interval) facing the hours hand. How is this possible? Simple...the + Moebius strip turns on itself while the hands are turning, so that it turns 180 + degrees in 12 hours. When the hours hand returns to this place, the strip will + have the other number facing it (the number with 12 hours difference). + + B. THE SCREEN SAVER + The Moebius Clock Screen Saver shows a fully functional Moebius Clock in 3D + in the middle of the screen, which shows the correct hour taken from your + system settings. + The screen saver has several options to control how the Moebius Clock will be + rendered (quality and performance options), and other options that control the + behavior of the clock. It even implements some other options compatible with + Microsoft's Plus! screen savers (like Hot Spots and mouse sensitivity). + The Moebius Clock Screen Saver was implemented in OpenGL and depends highly on + the current OpenGL implementation installed in your computer (see Requirements + and Installation instructions). + +2. REQUIREMENTS + 1) Operating System. The Moebius Clock Screen Saver was fully tested in Windows + NT 4, Windows 95 and Windows 98. It requires the OpenGL drivers/dlls installed + on your computer. Luckily, Windows NT 4 and Windows 98 come with a software + implementation of those drivers. If you own Windows 95 you will have to + download and install the drivers/dlls since they are not included in this + package. + 2) Hardware requirements. The hardware requirements are simple: the faster your + processor and the better your 3D acceleration card the best performance you + will get. It was fully tested with a Pentium II 350 Mhz and a Creative Riva TNT + 3D acceleration card and found to run smoothly. It was executed also with + several other graphic cards and processor speeds. The thumb rule: you'll need + a reasonable good 3D accelerator with OpenGL implementation and support for + texture mapping in hardware. + Some settings have been added to improve the performance in non 3D accelerated + computers. With those options it was tested on a Pentium 266 Mhz with a regular + VGA card. Check every option with the question mark cursor in the settings + dialog for an explanation. + We recommend a resolution of at least 800x600 with 16 bits color depth. + +3. INSTALLATION INSTRUCTIONS + The installation instructions are a bit more complicated than the usual since we + didn't use an automatic installer with this version (we plan to use it in the + next one). We apologize in advance for the inconvinience. + 1) To install the screen saver from this ZIP distribution, you must first + decompress it. Decompression requires a ZIP extraction program like PKUNZIP or + WinZip. + You should extract all files in the archive to a temporary directory (see + the PKZIP or WinZip documentation for instructions). If the files were + extracted succesfully you should see the following files in your temporary + directory: + Readme.txt - this readme + Moebius Clock.scr - the screen saver executable + Moebius Clock.hlp - the screen saver context help + + 2) After extracting all the files, you should copy the "Moebius Clock.scr" and the + "Moebius Clock.hlp" files to your Windows System directory (usually + Windows\System for Windows 95/98 and WinNT\System32 for NT 4). + 3) Then open the Display properties by double clicking on it's icon from the Control + Panel. Press on the Screen Saver tab at the top of the dialog. On the screen + saver section you should see a combo box with the name of the current screen + saver displayed on it. Press on the combo box and scroll until you see "Moebius + Clock". Select it. Close the dialog by pressing OK or Preview the screen saver + before. It is recommended to configure the screen saver by pressing on Settings + before you run it for the first time. + +4. REMOVING INTRUCTIONS + 1) Select another screen saver by following the 3rd step of the previous section. + 2) Delete the "Moebius Clock.scr" and "Moebius Clock.hlp" files from your Windows + System directory (see 2nd step of the previous section). + 3) If you like to clean up the registry entries that the screen saver added (for + advanced Windows users only) open the Registry Editor (regedit). Delete all the + subtree from the following registry path: + HKEY_CURRENT_USER\Software\Moebius Clock + +5. CREDITS + The original Moebius Clock concept was created by Ron Inbar. He also did the + OpenGL implementation. The Win32 porting and documentation was done by + Uriel Cohen. Thank you to all who supported us and gave us constructive criticism. + + Contact us at: + Uriel Cohen : urielc@actcom.co.il + Ron Inbar : rinbar@netvision.net.il diff --git a/Readppm.cpp b/Readppm.cpp new file mode 100644 index 0000000..9b192df --- /dev/null +++ b/Readppm.cpp @@ -0,0 +1,35 @@ +#include +#include + +#define max3(a, b, c) (max(max((a), (b)), (c))) + +unsigned char *ReadPPM(const char *filename, int *width, int *height) +{ + FILE *file= fopen(filename, "r"); + + char magic[10]; + + fscanf(file, "%s", magic); + fscanf(file, "%d %d", width, height); + + int maxcolor; + + fscanf(file, "%d", &maxcolor); + + int npixels= *width * *height; + unsigned char (*data)[4]= new unsigned char[npixels][4]; + unsigned char (*p)[4]= data - 1; + + fseek(file, -3 * npixels, SEEK_END); + + while (npixels--) + { + fread(++p, 3, 1, file); + (*p)[3]= max3((*p)[0], (*p)[1], (*p)[2]); + } + + fclose(file); + + return (unsigned char *) data; +} + diff --git a/SaverSettings.cpp b/SaverSettings.cpp new file mode 100644 index 0000000..f82284e --- /dev/null +++ b/SaverSettings.cpp @@ -0,0 +1,291 @@ +//========================================================================== +// +// File: SaverSettings.cpp +// +//========================================================================== + +#include +#include +#include +#include "SaverSettings.h" + +#define REGSTR_PATH_PLUSSCR (REGSTR_PATH_SETUP "\\Screen Savers") +#define REGSTR_PATH_CONFIG ("Software\\Moebius Clock\\Moebius Clock Saver") + +//****************************************************************************************** + +SaverSettings::SaverSettings() : + state(), hwnd(NULL), ReallyClose(FALSE), idTimer(0), + hdc(NULL), hglrc(NULL) +{ + int i; + + for (i=0; i < 16; i++) + customColors[i] = RGB(255, 255, 255); +} + +//****************************************************************************************** + +void +SaverSettings::ReadGeneralRegistry() +{ + PasswordDelay = 15; // default values in case they're not in registry + PasswordDelayIndex = 0; + MouseThreshold = 0; + MouseThresholdIndex = 1; + IsDialogActive = FALSE; + Corners[0] = '-'; Corners[1] = '-'; Corners[2] = '-'; Corners[3] = '-'; + Corners[4] = '\0'; + + LONG res; + HKEY skey; + DWORD valtype, valsize, val; + char achVal[5]; + + res = RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_PLUSSCR, 0, KEY_ALL_ACCESS, &skey); + if (res != ERROR_SUCCESS) return; + valsize = sizeof(val); + res = RegQueryValueEx(skey, "Password Delay", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) PasswordDelay = val; + valsize = sizeof(val); + res = RegQueryValueEx(skey, "Password Delay Index", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) PasswordDelayIndex = val; + valsize = sizeof(val); + res = RegQueryValueEx(skey, "Mouse Threshold", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) MouseThreshold = val; + valsize = sizeof(val); + res = RegQueryValueEx(skey, "Mouse Threshold Index", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) MouseThresholdIndex = val; + valsize = sizeof(val); + res = RegQueryValueEx(skey, "Mute Sound", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) MuteSound = val; + valsize = sizeof(char)*5; + res = RegQueryValueEx(skey, "Mouse Corners", 0, &valtype, (LPBYTE)achVal, &valsize); + if (res == ERROR_SUCCESS) + { + Corners[0] = achVal[0]; Corners[1] = achVal[1]; Corners[2] = achVal[2]; + Corners[3] = achVal[3]; Corners[4] = achVal[4]; + } + RegCloseKey(skey); +} + +//****************************************************************************************** + +void +SaverSettings::ReadGraphicConfigRegistry() +{ + LONG res; + HKEY skey; + DWORD valtype, valsize, val; + + res = RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_CONFIG, 0, KEY_ALL_ACCESS, &skey); + if (res != ERROR_SUCCESS) return; + valsize = sizeof(val); + + res = RegQueryValueEx(skey, "Alpha Blending", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) state.bBlend = val; + res = RegQueryValueEx(skey, "Antialiasing", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) state.bSmooth = val; + res = RegQueryValueEx(skey, "Backface Culling", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) state.bCulling = val; + res = RegQueryValueEx(skey, "Use Z-Buffer", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) state.bDepthTest = val; + res = RegQueryValueEx(skey, "Show Normals", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) state.bNormals = val; + res = RegQueryValueEx(skey, "No Glass", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) state.bNoGlass = val; + res = RegQueryValueEx(skey, "No Extra Textures", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) state.bNoExtraTextures = val; + res = RegQueryValueEx(skey, "Linear", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) state.nLinear = (short)val; + res = RegQueryValueEx(skey, "Mipmaps", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) state.nMipmap = (short)val; + res = RegQueryValueEx(skey, "Show Wireframe", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) + state.nPolygonMode = (val ? GL_LINE : GL_FILL); + res = RegQueryValueEx(skey, "Gouraud Shading", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) + state.nShadeModel = (val ? GL_SMOOTH : GL_FLAT); + if (!state.bBlend) + state.da = -state.da; + + RegCloseKey(skey); +} + +//****************************************************************************************** + +void +SaverSettings::ReadBehaviorRegistry() +{ + int i; + char str[20]; + LONG res; + HKEY skey; + DWORD valtype, valsize, val; + float fval; + + res = RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_CONFIG, 0, KEY_ALL_ACCESS, &skey); + if (res != ERROR_SUCCESS) return; + valsize = sizeof(fval); + + for (i=0; i < 4; i++) + { + sprintf(str, "Color %d Red", i+1); + res = RegQueryValueEx(skey, str, 0, &valtype, (LPBYTE)&fval, &valsize); + if (res == ERROR_SUCCESS) state.fColorR[i] = fval; + sprintf(str, "Color %d Green", i+1); + res = RegQueryValueEx(skey, str, 0, &valtype, (LPBYTE)&fval, &valsize); + if (res == ERROR_SUCCESS) state.fColorG[i] = fval; + sprintf(str, "Color %d Blue", i+1); + res = RegQueryValueEx(skey, str, 0, &valtype, (LPBYTE)&fval, &valsize); + if (res == ERROR_SUCCESS) state.fColorB[i] = fval; + } + res = RegQueryValueEx(skey, "Speed Up Clock", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) state.bQuick = val; + res = RegQueryValueEx(skey, "Swing Clock", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) state.bSwing = val; + res = RegQueryValueEx(skey, "Use Backdrop", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) + val == TRUE ? state.bBlackBackground = FALSE : state.bBlackBackground = TRUE; + res = RegQueryValueEx(skey, "Use Mouse", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) state.bUseMouse = val; + res = RegQueryValueEx(skey, "Moebius Strip Twists", 0, &valtype, (LPBYTE)&val, &valsize); + if (res == ERROR_SUCCESS) state.nTwists = (short)val; + + RegCloseKey(skey); +} + +//****************************************************************************************** + +void +SaverSettings::WriteGeneralRegistry() +{ + LONG res; + HKEY skey; + DWORD val, disp; + + res = RegCreateKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_PLUSSCR, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &skey, &disp); + if (res != ERROR_SUCCESS) return; + + val = PasswordDelay; + RegSetValueEx(skey, "Password Delay", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + val = PasswordDelayIndex; + RegSetValueEx(skey, "Password Delay Index", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + val = MouseThreshold; + RegSetValueEx(skey, "Mouse Threshold", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + val = MouseThresholdIndex; + RegSetValueEx(skey, "Mouse Threshold Index", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + val = MuteSound; + RegSetValueEx(skey, "Mute Sound", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + RegSetValueEx(skey, "Mouse Corners", 0, REG_SZ, (CONST BYTE*)Corners, sizeof(char)*5); + + RegCloseKey(skey); +} + +//****************************************************************************************** + +void +SaverSettings::WriteGraphicConfigRegistry() +{ + LONG res; + HKEY skey; + DWORD val, disp; + + res = RegCreateKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_CONFIG, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &skey, &disp); + if (res != ERROR_SUCCESS) return; + + val = state.bBlend; + RegSetValueEx(skey, "Alpha Blending", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + val = state.bSmooth; + RegSetValueEx(skey, "Antialiasing", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + val = state.bCulling; + RegSetValueEx(skey, "Backface Culling", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + val = state.bDepthTest; + RegSetValueEx(skey, "Use Z-Buffer", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + val = state.bNormals; + RegSetValueEx(skey, "Show Normals", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + val = state.bNoGlass; + RegSetValueEx(skey, "No Glass", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + val = state.bNoExtraTextures; + RegSetValueEx(skey, "No Extra Textures", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + val = state.nLinear; + RegSetValueEx(skey, "Linear", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + val = state.nMipmap; + RegSetValueEx(skey, "Mipmaps", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + val = (state.nPolygonMode == GL_LINE ? TRUE : FALSE); + RegSetValueEx(skey, "Show Wireframe", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + val = (state.nShadeModel == GL_SMOOTH ? TRUE : FALSE); + RegSetValueEx(skey, "Gouraud Shading", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + + RegCloseKey(skey); +} + +//****************************************************************************************** + +void +SaverSettings::WriteBehaviorRegistry() +{ + int i; + char str[20]; + LONG res; + HKEY skey; + DWORD disp, val; + float fval; + + res = RegCreateKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_CONFIG, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &skey, &disp); + if (res != ERROR_SUCCESS) return; + + for (i=0; i < 4; i++) + { + fval = state.fColorR[i]; + sprintf(str, "Color %d Red", i+1); + RegSetValueEx(skey, str, 0, REG_DWORD, (CONST BYTE*)&fval, sizeof(fval)); + fval = state.fColorG[i]; + sprintf(str, "Color %d Green", i+1); + RegSetValueEx(skey, str, 0, REG_DWORD, (CONST BYTE*)&fval, sizeof(fval)); + fval = state.fColorB[i]; + sprintf(str, "Color %d Blue", i+1); + RegSetValueEx(skey, str, 0, REG_DWORD, (CONST BYTE*)&fval, sizeof(fval)); + } + val = state.bQuick; + RegSetValueEx(skey, "Speed Up Clock", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + val = state.bSwing; + RegSetValueEx(skey, "Swing Clock", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + val = state.bUseMouse; + RegSetValueEx(skey, "Use Mouse", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + state.bBlackBackground == TRUE ? val = FALSE : val = TRUE; + RegSetValueEx(skey, "Use Backdrop", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + val = state.nTwists; + RegSetValueEx(skey, "Moebius Strip Twists", 0, REG_DWORD, (CONST BYTE*)&val, sizeof(val)); + + RegCloseKey(skey); +} + +//****************************************************************************************** + +void +SaverSettings::CloseSaverWindow() +{ + ReallyClose = TRUE; + PostMessage(hwnd, WM_CLOSE, 0, 0); +} + +//****************************************************************************************** + +void +SaverSettings::StartDialog() +{ + IsDialogActive = TRUE; + SendMessage(hwnd, WM_SETCURSOR, 0, 0); +} + +//****************************************************************************************** + +void +SaverSettings::EndDialog() +{ + IsDialogActive = FALSE; + SendMessage(hwnd, WM_SETCURSOR, 0, 0); + GetCursorPos(&InitCursorPos); +} + diff --git a/SaverSettings.h b/SaverSettings.h new file mode 100644 index 0000000..ca84272 --- /dev/null +++ b/SaverSettings.h @@ -0,0 +1,51 @@ +//========================================================================== +// +// File: SaverSettings.h +// +//========================================================================== + +#ifndef SAVERSETTINGS_H +#define SAVERSETTINGS_H + +#include "OpenGLenv.h" + +//****************************************************************************************** + +class SaverSettings +{ +public: + HWND hwnd; + HDC hdc; + HGLRC hglrc; + UINT idTimer; // a timer id, because this particular saver uses a timer + DWORD customColors[16]; + + DWORD PasswordDelay; // in seconds + DWORD PasswordDelayIndex; + DWORD MouseThreshold; // in pixels + DWORD MouseThresholdIndex; + BOOL MuteSound; + char Corners[5]; + POINT InitCursorPos; + DWORD InitTime; // in ms + BOOL IsDialogActive; + BOOL ReallyClose; // for NT, so we know if a WM_CLOSE came from us or it. + + GraphicEnvState state; + + SaverSettings(); + + void ReadGeneralRegistry(); + void WriteGeneralRegistry(); + void ReadGraphicConfigRegistry(); + void WriteGraphicConfigRegistry(); + void ReadBehaviorRegistry(); + void WriteBehaviorRegistry(); + void CloseSaverWindow(); + void StartDialog(); + void EndDialog(); +}; + +//****************************************************************************************** + +#endif diff --git a/ScreenSaver.cpp b/ScreenSaver.cpp new file mode 100644 index 0000000..37c316f --- /dev/null +++ b/ScreenSaver.cpp @@ -0,0 +1,570 @@ +// Minimal Screensaver +// --------------------- +// (c) 1998 Lucian Wischik. You may do whatever you want with this code, without restriction. +// +// This code is a basic minimal screensaver. It does not use SCRNSAVE.LIB or any other library: +// absolutely all the code is in this source file. +// The saver works perfectly fine under '95 and NT. It respects the Plus! configuration settings +// (password delay, mouse movement threshold). It can handle passwords correctly. +// It makes all the correct calls in the correct places, including calls that are undocumented +// by Microsoft. +// This code accompanies the guide 'How To Write a 32bit Screen Saver'. All documentation for this +// code is in that guide. It can be found at http://classic.physiol.cam.ac.uk/scr/ +// +// Notes: +// 0. All of this is a real hassle. If you used my ScrPlus library then it would all be much much +// easier. And you'd get lots of extra features, like a standard 'Plus!' style configuration dialog +// with preview in it, and proper handling of hot corners under NT as well as '95, and a high +// performance multimedia timer, and lots of examples including some that use full-screen DirectDraw. +// http://classic.physiol.cam.ac.uk/scr/ +// If you have C++Builder then you should use my ScrPlus/C++Builder library which has an expert +// and components for easily generating screensavers. +// If you remain blind to the joys of using ScrPlus and are willing to waste time programming it +// all yourself, then read on... +// 1. Having a 'DEBUG' flag, with diagnostic output, is ABSOLUTELY ESSENTIAL. I can guarantee +// that if you develop a screensaver without diagnostic output for every single message that +// you handle, your screensaver will crash and you won't know why. +// 2. If you also wanted to write a configuration dialog that was able to set the standard Plus! +// options, you'd need to use two additional calls: SystemAgentDetect, and ScreenSaverChanged. +// They are documented in my 'how to write a 32bit screensaver' technical guide. +// 3. NT and '95 handle passwords differently. Under NT, the saver must terminate and then the +// verify-password dialog comes up. If the user fails, then the screensaver is launched again from +// scratch. Under '95, the password dialog comes up while the saver is running. +// 4. You should probably use WM_TIMER messages for your animation, rather than idle-processing. +// By using WM_TIMER messages your animation will keep going even when (under '95) the password +// dialog is up. +// 5. Changing the saver to allow interraction is easy. All you have to do is figure out which +// messages (keyboard, mouse, ...) will be used by you and stop them from closing the window. +// 6. Changing the saver to implement your own password routine is easy under '95: all you have +// to do is change the VerifyPassword routine. Under NT it's not really possible. + +#include +#include +#include +#include + +#pragma hdrstop + +#include "resource.h" +#include "SaverSettings.h" +#include "Password.h" +#include "Debug.h" +#include "Dialogs.h" + +//****************************************************************************************** + +#define TIMERID 1000 +#define UPDATE_TIME 10 + +#define SIGN_EXTEND(w) ((((int)(w)) << 16) >> 16) + +//****************************************************************************************** + +enum TScrMode { smNone, smConfig, smPassword, smPreview, smSaver}; + +HINSTANCE hInstance = NULL; +HWND hScrWindow = NULL; +TScrMode ScrMode = smNone; +SaverSettings* ss = NULL; + +//****************************************************************************************** + +#if DEBUG +void Debug(char *c) { OutputDebugString(c); OutputDebugString("\n"); } +#else +void Debug(char *) {} +#endif + +//****************************************************************************************** + +LRESULT CALLBACK +SaverWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + static BOOL bRoll = FALSE; + static BOOL bMovement = FALSE; + static POINT anchor; + + switch (msg) + { + case WM_CREATE: + { + Debug("WM_CREATE..."); + ss->hwnd = hwnd; + GetCursorPos(&(ss->InitCursorPos)); + ss->InitTime = GetTickCount(); + ss->idTimer = SetTimer(hwnd, TIMERID, UPDATE_TIME, NULL); + if (!InitGraphicEnv(ss->hwnd, &ss->hdc, &ss->hglrc)) + return FALSE; + InitState(); + InitTexture(ss->hwnd, ss->hdc); + InitDisplayLists(); + } + break; + + case WM_TIMER: + { + UpdateTime(); + InvalidateRect(hwnd, NULL, FALSE); + } + break; + + case WM_ACTIVATE: + case WM_ACTIVATEAPP: + case WM_NCACTIVATE: + { + if (ScrMode==smSaver && !ss->IsDialogActive && LOWORD(wParam)==WA_INACTIVE && !DEBUG) + { + Debug("WM_ACTIVATE: about to inactive window, so sending close"); + ss->CloseSaverWindow(); + } + } + break; + + case WM_SETCURSOR: + { + if (ScrMode==smSaver && !ss->IsDialogActive && !DEBUG) + SetCursor(NULL); + else + SetCursor(LoadCursor(NULL, IDC_ARROW)); + } + break; + + case WM_KEYDOWN: + case WM_MBUTTONDOWN: + ss->CloseSaverWindow(); + break; + + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + { + if (ScrMode==smSaver && !ss->IsDialogActive) + { + if (ss->state.bUseMouse) + { + RECT rc; + bMovement = TRUE; + GetClientRect(hwnd, &rc); + GetCursorPos(&anchor); + ScreenToClient(hwnd, &anchor); + if (msg == WM_RBUTTONDOWN) bRoll = TRUE; + else bRoll = FALSE; + SetCapture(hwnd); + } + else // Not using mouse so we can try to close the screensaver + { + Debug("WM_BUTTONDOWN: sending close"); + ss->CloseSaverWindow(); + } + } + } + break; + + case WM_LBUTTONUP: + { + if (ScrMode==smSaver && !ss->IsDialogActive) + { + bMovement = FALSE; + bRoll = FALSE; + ReleaseCapture(); + } + } + break; + + case WM_LBUTTONDBLCLK: + { + if (ScrMode==smSaver && !ss->IsDialogActive) + { + if (ss->state.bUseMouse) + { + ResetOrientationGraphicEnv(); + } + else // Not using mouse so we can try to close the screensaver + { + Debug("WM_BUTTONDOWN: sending close"); + ss->CloseSaverWindow(); + } + } + } + break; + + case WM_MOUSEMOVE: + { + if (ScrMode==smSaver && !ss->IsDialogActive) + { + if (ss->state.bUseMouse) + { + if (bMovement & ((wParam & MK_LBUTTON) || (wParam & MK_RBUTTON)) ) + { + POINT mouse; + mouse.x = SIGN_EXTEND(LOWORD(lParam)); + mouse.y = SIGN_EXTEND(HIWORD(lParam)); + MotionOfGraphicEnv(&anchor, mouse, bRoll); + } + } + else // Not using mouse so we can try to close the screensaver + { + POINT pt; + GetCursorPos(&pt); + int dx = pt.x-ss->InitCursorPos.x; + if (dx<0) dx=-dx; + int dy=pt.y-ss->InitCursorPos.y; + if (dy<0) dy=-dy; + if (dx>(int)ss->MouseThreshold || dy>(int)ss->MouseThreshold) + { + Debug("WM_MOUSEMOVE: gone beyond threshold, sending close"); + ss->CloseSaverWindow(); + } + } + } + } + break; + + case (WM_SYSCOMMAND): + { + if (ScrMode == smSaver) + { + if (wParam == SC_SCREENSAVE) + { + Debug("WM_SYSCOMMAND: gobbling up a SC_SCREENSAVE to stop a new saver from running."); + return FALSE; + } + if (wParam == SC_CLOSE && !DEBUG) + { + Debug("WM_SYSCOMMAND: gobbling up a SC_CLOSE"); + return FALSE; + } + } + } + break; + + case WM_SIZE: + { + int width = LOWORD(lParam); + int height = HIWORD(lParam); + if (width && height) + { + Reshape(ss->hdc, width, height); + } + } + break; + + case WM_PAINT: + { + RECT r; + PAINTSTRUCT ps; + + // Retrieve the coordinates of the smallest rectangle that completely encloses the + // update region of the specified window (win) + if (GetUpdateRect(ss->hwnd, &r, FALSE)) + { + BeginPaint(ss->hwnd, &ps); + Display(ss->hdc); + EndPaint(ss->hwnd, &ps); + } + } + break; + + case WM_CLOSE: + { + if (ScrMode==smSaver && ss->ReallyClose && !ss->IsDialogActive) + { + Debug("WM_CLOSE: maybe we need a password"); + BOOL CanClose = TRUE; + if (GetTickCount()-ss->InitTime > 1000*ss->PasswordDelay) + { + ss->StartDialog(); + CanClose = VerifyPassword(hwnd); + ss->EndDialog(); + } + if (CanClose) + { + Debug("WM_CLOSE: doing a DestroyWindow"); + DestroyWindow(hwnd); + } + else + { + Debug("WM_CLOSE: but failed password, so doing nothing"); + } + } + if (ScrMode == smSaver) + return FALSE; // so that DefWindowProc doesn't get called, because it would just DestroyWindow + } + break; + + case WM_DESTROY: + { + if (ss->idTimer != 0) + KillTimer(hwnd, ss->idTimer); + DestroyGraphicEnv(ss->hwnd, ss->hdc, ss->hglrc); + ss->idTimer = 0; + Debug("POSTQUITMESSAGE from WM_DESTROY!!"); + PostQuitMessage(0); + } + break; + } + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +//****************************************************************************************** + +void +DoSaver(HWND hparwnd) +{ + WNDCLASS wc; + wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; + wc.lpfnWndProc = SaverWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = NULL; + wc.hCursor = NULL; + wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = "ScrClass"; + RegisterClass(&wc); + if (ScrMode == smPreview) + { + RECT rc; + GetWindowRect(hparwnd, &rc); + int cx = rc.right-rc.left, cy = rc.bottom-rc.top; + hScrWindow = CreateWindowEx( + 0, "ScrClass", "SaverPreview", + WS_CHILD | WS_VISIBLE, + 0, 0, cx, cy, + hparwnd, NULL, hInstance, NULL + ); + } + else + { + int cx = GetSystemMetrics(SM_CXSCREEN), cy = GetSystemMetrics(SM_CYSCREEN); + DWORD exstyle, style; + if (DEBUG) + { + cx = cx/3; + cy = cy/3; + exstyle = 0; + style = WS_OVERLAPPEDWINDOW | WS_VISIBLE; + } + else + { + exstyle = WS_EX_TOPMOST; + style = WS_POPUP | WS_VISIBLE; + } + hScrWindow = CreateWindowEx( + exstyle, "ScrClass", "SaverWindow", + style, 0, 0, cx, cy, + NULL, NULL, hInstance, NULL + ); + } + if (hScrWindow == NULL) return; + + UINT oldval; + if (ScrMode == smSaver) + SystemParametersInfo(SPI_SCREENSAVERRUNNING, 1, &oldval, 0); + MSG msg; + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + if (ScrMode == smSaver) + SystemParametersInfo(SPI_SCREENSAVERRUNNING, 0, &oldval, 0); + + return; +} + +/****************************************************************************/ +// +// Creates the Property Sheets - Replaces calls to DialogBox +// +int +CreatePropertySheet(HWND hwndOwner) +{ + PROPSHEETPAGE psp[3]; + PROPSHEETHEADER psh; + + psp[0].dwSize = sizeof(PROPSHEETPAGE); + psp[0].dwFlags = PSP_USETITLE; + psp[0].hInstance = hInstance; + psp[0].pszTemplate = MAKEINTRESOURCE(IDD_GENERAL); + psp[0].pszIcon = NULL; + psp[0].pfnDlgProc = GeneralDialogProc; + psp[0].pszTitle = "General"; + psp[0].lParam = 0; + + psp[1].dwSize = sizeof(PROPSHEETPAGE); + psp[1].dwFlags = PSP_USETITLE; + psp[1].hInstance = hInstance; + psp[1].pszTemplate = MAKEINTRESOURCE(IDD_GRAPHIC_CONFIG); + psp[1].pszIcon = NULL; + psp[1].pfnDlgProc = GraphicConfigDialogProc; + psp[1].pszTitle = "OpenGL"; + psp[1].lParam = 0; + + psp[2].dwSize = sizeof(PROPSHEETPAGE); + psp[2].dwFlags = PSP_USETITLE; + psp[2].hInstance = hInstance; + psp[2].pszTemplate = MAKEINTRESOURCE(IDD_BEHAVIOR); + psp[2].pszIcon = NULL; + psp[2].pfnDlgProc = BehaviorDialogProc; + psp[2].pszTitle = "Behavior"; + psp[2].lParam = 0; + + psh.dwSize = sizeof(PROPSHEETHEADER); + psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW | PSH_USEICONID; + psh.hwndParent = hwndOwner; + psh.hInstance = hInstance; + psh.pszIcon = MAKEINTRESOURCE(IDI_ICON1); + psh.pszCaption = (LPSTR) "Screen Saver Properties"; + psh.nPages = sizeof(psp) / sizeof(PROPSHEETPAGE); + psh.nStartPage = 1; + psh.ppsp = (LPCPROPSHEETPAGE) &psp; + + return (PropertySheet(&psh)); +} + +//****************************************************************************************** +// This routine is for using ScrPrev. It's so that you can start the saver +// with the command line /p scrprev and it runs itself in a preview window. +// You must first copy ScrPrev somewhere in your search path. + +HWND +CheckForScrprev() +{ + HWND hwnd = FindWindow("Scrprev", NULL); // looks for the Scrprev class + if (hwnd == NULL) // try to load it + { + STARTUPINFO si; + PROCESS_INFORMATION pi; + ZeroMemory(&si, sizeof(si)); + ZeroMemory(&pi, sizeof(pi)); + si.cb = sizeof(si); + si.lpReserved = NULL; + si.lpTitle = NULL; + si.dwFlags = 0; + si.cbReserved2 = 0; + si.lpReserved2 = 0; + si.lpDesktop = 0; + BOOL cres = CreateProcess( + NULL, "Scrprev", 0, 0, FALSE, + CREATE_NEW_PROCESS_GROUP | CREATE_DEFAULT_ERROR_MODE, + 0, 0, &si, &pi + ); + if (!cres) + { + Debug("Error creating scrprev process"); + return NULL; + } + DWORD wres = WaitForInputIdle(pi.hProcess, 2000); + if (wres == WAIT_TIMEOUT) + { + Debug("Scrprev never becomes idle"); + return NULL; + } + if (wres == 0xFFFFFFFF) + { + Debug("ScrPrev, misc error after ScrPrev execution"); + return NULL; + } + hwnd = FindWindow("Scrprev", NULL); + } + if (hwnd == NULL) + { + Debug("Unable to find Scrprev window"); + return NULL; + } + ::SetForegroundWindow(hwnd); + hwnd = GetWindow(hwnd, GW_CHILD); + if (hwnd == NULL) + { + Debug("Couldn't find Scrprev child"); + return NULL; + } + return hwnd; +} + +//****************************************************************************************** + +int WINAPI +WinMain(HINSTANCE h, HINSTANCE, LPSTR, int) +{ + hInstance = h; + HWND hwnd = NULL; + INITCOMMONCONTROLSEX initCntrls; + + char *c = GetCommandLine(); + if (*c == '\"') + { + c++; + while (*c!=0 && *c!='\"') c++; + } + else + { + while (*c!=0 && *c!=' ') c++; + } + if (*c != 0) c++; + while (*c == ' ') c++; + + if (*c == 0) + { + ScrMode = smConfig; + hwnd = NULL; + } + else + { + if (*c=='-' || *c=='/') c++; + if (*c=='p' || *c=='P' || *c=='l' || *c=='L') + { + c++; + while (*c==' ' || *c==':') c++; + if ( (strcmp(c, "scrprev") == 0) || (strcmp(c, "ScrPrev") == 0) || + (strcmp(c, "SCRPREV") == 0) ) + hwnd = CheckForScrprev(); + else hwnd = (HWND)atoi(c); + ScrMode = smPreview; + } + else if (*c=='s' || *c=='S') + { + ScrMode = smSaver; + } + else if (*c=='c' || *c=='C') + { + c++; + while (*c==' ' || *c==':') c++; + if (*c == 0) hwnd = GetForegroundWindow(); + else hwnd = (HWND)atoi(c); + ScrMode = smConfig; + } + else if (*c=='a' || *c=='A') + { + c++; + while (*c==' ' || *c==':') c++; + hwnd = (HWND)atoi(c); + ScrMode = smPassword; + } + } + + initCntrls.dwSize = sizeof(INITCOMMONCONTROLSEX); + initCntrls.dwICC = ICC_WIN95_CLASSES; + InitCommonControlsEx(&initCntrls); + + // We create a global SaverSettings here, for convenience. + // It will get used by the config dialog and by the saver as it runs. + + ss = new SaverSettings(); + ss->ReadGeneralRegistry(); + ss->ReadGraphicConfigRegistry(); + ss->ReadBehaviorRegistry(); + + if (ScrMode == smPassword) ChangePassword(hwnd); + if (ScrMode == smConfig) + { + CreatePropertySheet(hwnd); + } + if (ScrMode == smSaver || ScrMode == smPreview) DoSaver(hwnd); + + delete ss; + return 0; +} + +//****************************************************************************************** diff --git a/TransparentBitmap.cpp b/TransparentBitmap.cpp new file mode 100644 index 0000000..9cca657 --- /dev/null +++ b/TransparentBitmap.cpp @@ -0,0 +1,105 @@ +//========================================================================== +// +// File: TransparentBitmap.cpp +// +//========================================================================== + +#include + +void +DrawTransparentBitmap(HDC hdc, HBITMAP hBitmap, short xStart, + short yStart, COLORREF cTransparentColor) +{ + BITMAP bm; + COLORREF cColor; + HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave; + HGDIOBJ bmBackOld, bmObjectOld, bmMemOld, bmSaveOld; + HDC hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave; + POINT ptSize; + + hdcTemp = CreateCompatibleDC(hdc); + SelectObject(hdcTemp, hBitmap); // Select the bitmap + + GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm); + ptSize.x = bm.bmWidth; // Get width of bitmap + ptSize.y = bm.bmHeight; // Get height of bitmap + DPtoLP(hdcTemp, &ptSize, 1); // Convert from device + // to logical points + + // Create some DCs to hold temporary data. + hdcBack = CreateCompatibleDC(hdc); + hdcObject = CreateCompatibleDC(hdc); + hdcMem = CreateCompatibleDC(hdc); + hdcSave = CreateCompatibleDC(hdc); + + // Create a bitmap for each DC. DCs are required for a number of + // GDI functions. + + // Monochrome DC + bmAndBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL); + + // Monochrome DC + bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL); + + bmAndMem = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y); + bmSave = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y); + + // Each DC must select a bitmap object to store pixel data. + bmBackOld = SelectObject(hdcBack, bmAndBack); + bmObjectOld = SelectObject(hdcObject, bmAndObject); + bmMemOld = SelectObject(hdcMem, bmAndMem); + bmSaveOld = SelectObject(hdcSave, bmSave); + + // Set proper mapping mode. + SetMapMode(hdcTemp, GetMapMode(hdc)); + + // Save the bitmap sent here, because it will be overwritten. + BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY); + + // Set the background color of the source DC to the color. + // contained in the parts of the bitmap that should be transparent + cColor = SetBkColor(hdcTemp, cTransparentColor); + + // Create the object mask for the bitmap by performing a BitBlt + // from the source bitmap to a monochrome bitmap. + BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY); + + // Set the background color of the source DC back to the original + // color. + SetBkColor(hdcTemp, cColor); + + // Create the inverse of the object mask. + BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, NOTSRCCOPY); + + // Copy the background of the main DC to the destination. + BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, xStart, yStart, SRCCOPY); + + // Mask out the places where the bitmap will be placed. + BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND); + + // Mask out the transparent colored pixels on the bitmap. + BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND); + + // XOR the bitmap with the background on the destination DC. + BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT); + + // Copy the destination to the screen. + BitBlt(hdc, xStart, yStart, ptSize.x, ptSize.y, hdcMem, 0, 0, SRCCOPY); + + // Place the original bitmap back into the bitmap sent here. + BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY); + + // Delete the memory bitmaps. + DeleteObject(SelectObject(hdcBack, bmBackOld)); + DeleteObject(SelectObject(hdcObject, bmObjectOld)); + DeleteObject(SelectObject(hdcMem, bmMemOld)); + DeleteObject(SelectObject(hdcSave, bmSaveOld)); + + // Delete the memory DCs. + DeleteDC(hdcMem); + DeleteDC(hdcBack); + DeleteDC(hdcObject); + DeleteDC(hdcSave); + DeleteDC(hdcTemp); +} + diff --git a/TransparentBitmap.h b/TransparentBitmap.h new file mode 100644 index 0000000..06eb28c --- /dev/null +++ b/TransparentBitmap.h @@ -0,0 +1,17 @@ +//========================================================================== +// +// File: TransparentBitmap.h +// +//========================================================================== + +#ifndef TRANSPARENTBITMAP_H +#define TRANSPARENTBITMAP_H + +#include + +void DrawTransparentBitmap( + HDC hdc, HBITMAP hBitmap, short xStart, + short yStart, COLORREF cTransparentColor +); + +#endif diff --git a/bcheck.bmp b/bcheck.bmp new file mode 100644 index 0000000..6d19f32 Binary files /dev/null and b/bcheck.bmp differ diff --git a/bdot.bmp b/bdot.bmp new file mode 100644 index 0000000..c19e228 Binary files /dev/null and b/bdot.bmp differ diff --git a/bnone.bmp b/bnone.bmp new file mode 100644 index 0000000..fb03915 Binary files /dev/null and b/bnone.bmp differ diff --git a/cafe.bmp b/cafe.bmp new file mode 100644 index 0000000..9328a3e Binary files /dev/null and b/cafe.bmp differ diff --git a/hours0.bmp b/hours0.bmp new file mode 100644 index 0000000..d2d0b37 Binary files /dev/null and b/hours0.bmp differ diff --git a/hours1.bmp b/hours1.bmp new file mode 100644 index 0000000..70633ef Binary files /dev/null and b/hours1.bmp differ diff --git a/hours2.bmp b/hours2.bmp new file mode 100644 index 0000000..6c0082d Binary files /dev/null and b/hours2.bmp differ diff --git a/hours3.bmp b/hours3.bmp new file mode 100644 index 0000000..bb24a85 Binary files /dev/null and b/hours3.bmp differ diff --git a/monitor.bmp b/monitor.bmp new file mode 100644 index 0000000..0b12889 Binary files /dev/null and b/monitor.bmp differ diff --git a/monitor2.bmp b/monitor2.bmp new file mode 100644 index 0000000..2343420 Binary files /dev/null and b/monitor2.bmp differ diff --git a/ogllogo.bmp b/ogllogo.bmp new file mode 100644 index 0000000..5143ee7 Binary files /dev/null and b/ogllogo.bmp differ diff --git a/resource.h b/resource.h new file mode 100644 index 0000000..5ed825a --- /dev/null +++ b/resource.h @@ -0,0 +1,100 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by Moebius32.rc +// +#define IDR_MENU1 101 +#define ID_DEFAULT 101 +#define IDI_ICON1 102 +#define ID_NOW 102 +#define IDD_ABOUT 103 +#define ID_NEVER 103 +#define DLG_CONFIG 104 +#define IDB_CAFE 105 +#define IDB_HOURS0 106 +#define IDB_HOURS1 107 +#define IDB_HOURS2 108 +#define IDB_HOURS3 109 +#define IDB_OGLLOGO 110 +#define IDD_GRAPHIC_CONFIG 111 +#define IDD_GENERAL 113 +#define IDB_MONITOR 116 +#define IDB_BCHECK 120 +#define IDB_BDOT 121 +#define IDB_BNONE 122 +#define IDD_BEHAVIOR 123 +#define IDB_MONITOR2 125 +#define IDC_FLASH 1000 +#define IDC_FLAT 1001 +#define IDC_GOURAUD 1002 +#define IDC_BLEND 1003 +#define IDC_ABOUT 1004 +#define IDC_QUICK 1005 +#define IDC_NORMALS 1006 +#define IDC_WIREFRAME 1007 +#define IDC_EDIT1 1008 +#define IDC_SPIN1 1009 +#define IDC_ZBUFFER 1010 +#define IDC_CULL 1011 +#define IDC_MIPMAPS 1012 +#define ID_SAGEOK 1013 +#define ID_SAGEBAD 1014 +#define ID_DISMISSGROUP 1015 +#define IDC_SWING 1016 +#define ID_THRESHOLDDESC 1017 +#define IDC_BACK 1018 +#define ID_THRESHOLD 1019 +#define IDC_USEMOUSE 1020 +#define ID_WAITDESC 1021 +#define ID_WAITTEXT 1022 +#define ID_WAITBUDDY 1023 +#define ID_WAITBOX 1024 +#define ID_WAITMOREDESC 1025 +#define ID_WAITSUMMARY 1026 +#define ID_MONITOR 1027 +#define ID_MUTE 1028 +#define IDC_MONITOR 1029 +#define IDC_UL 1030 +#define IDC_UR 1031 +#define IDC_DR 1032 +#define IDC_DL 1033 +#define IDC_NEAREST 1034 +#define IDC_LINEAR 1035 +#define IDC_WMIPMAPS 1036 +#define IDC_NMIPMAPS 1037 +#define IDC_LMIPMAPS 1038 +#define IDC_COLOR1 1039 +#define IDC_COLOR2 1040 +#define IDC_COLOR3 1041 +#define IDC_COLOR4 1042 +#define IDC_NOGLASS 1043 +#define IDC_NOTEXTURES 1044 +#define IDC_ANTIALIAS 1045 +#define ID_FILE_EXIT 40001 +#define ID_HELP_ABOUT 40002 +#define ID_VIEW_ANTIALIAS 40003 +#define ID_VIEW_BLEND 40004 +#define ID_VIEW_CULL 40005 +#define ID_VIEW_METHOD_NICEST 40006 +#define ID_VIEW_METHOD_FASTEST 40007 +#define ID_VIEW_SHADE_FLAT 40008 +#define ID_VIEW_SHADE_GOURARD 40009 +#define ID_VIEW_LINEAR 40010 +#define ID_VIEW_MIDMAPS 40011 +#define ID_VIEW_PERSP_NICEST 40012 +#define ID_VIEW_PERSP_FASTEST 40013 +#define ID_VIEW_NORMALS 40014 +#define ID_VIEW_QUICK 40015 +#define ID_VIEW_SWING 40016 +#define ID_VIEW_WIREFRAME 40017 +#define ID_VIEW_ZBUFFER 40018 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 126 +#define _APS_NEXT_COMMAND_VALUE 40019 +#define _APS_NEXT_CONTROL_VALUE 1046 +#define _APS_NEXT_SYMED_VALUE 104 +#endif +#endif diff --git a/resource.hm b/resource.hm new file mode 100644 index 0000000..3ce1c74 --- /dev/null +++ b/resource.hm @@ -0,0 +1,39 @@ +// Microsoft Developer Studio generated Help ID include file. +// Used by Moebius32.rc +// +#define HIDC_ABOUT 0x807b03ec // IDD_BEHAVIOR +#define HIDC_ANTIALIAS 0x806f0415 // IDD_GRAPHIC_CONFIG +#define HIDC_BACK 0x807b03fa // IDD_BEHAVIOR +#define HIDC_BLEND 0x806f03eb // IDD_GRAPHIC_CONFIG +#define HIDC_COLOR1 0x807b040f // IDD_BEHAVIOR +#define HIDC_COLOR2 0x807b0410 // IDD_BEHAVIOR +#define HIDC_COLOR3 0x807b0411 // IDD_BEHAVIOR +#define HIDC_COLOR4 0x807b0412 // IDD_BEHAVIOR +#define HIDC_CULL 0x806f03f3 // IDD_GRAPHIC_CONFIG +#define HIDC_DL 0x80710409 // IDD_GENERAL +#define HIDC_DR 0x80710408 // IDD_GENERAL +#define HIDC_EDIT1 0x807b03f0 // IDD_BEHAVIOR +#define HIDC_FLAT 0x806f03e9 // IDD_GRAPHIC_CONFIG +#define HIDC_GOURAUD 0x806f03ea // IDD_GRAPHIC_CONFIG +#define HIDC_LINEAR 0x806f040b // IDD_GRAPHIC_CONFIG +#define HIDC_LMIPMAPS 0x806f040e // IDD_GRAPHIC_CONFIG +#define HIDC_MONITOR 0x807b0405 // IDD_BEHAVIOR +#define HIDC_NEAREST 0x806f040a // IDD_GRAPHIC_CONFIG +#define HIDC_NMIPMAPS 0x806f040d // IDD_GRAPHIC_CONFIG +#define HIDC_NOGLASS 0x806f0413 // IDD_GRAPHIC_CONFIG +#define HIDC_NORMALS 0x806f03ee // IDD_GRAPHIC_CONFIG +#define HIDC_NOTEXTURES 0x806f0414 // IDD_GRAPHIC_CONFIG +#define HIDC_QUICK 0x807b03ed // IDD_BEHAVIOR +#define HIDC_SPIN1 0x807b03f1 // IDD_BEHAVIOR +#define HIDC_SWING 0x807b03f8 // IDD_BEHAVIOR +#define HIDC_UL 0x80710406 // IDD_GENERAL +#define HIDC_UR 0x80710407 // IDD_GENERAL +#define HIDC_USEMOUSE 0x807b03fc // IDD_BEHAVIOR +#define HIDC_WIREFRAME 0x806f03ef // IDD_GRAPHIC_CONFIG +#define HIDC_WMIPMAPS 0x806f040c // IDD_GRAPHIC_CONFIG +#define HIDC_ZBUFFER 0x806f03f2 // IDD_GRAPHIC_CONFIG +#define HID_MUTE 0x80710404 // IDD_GENERAL +#define HID_THRESHOLD 0x807103fb // IDD_GENERAL +#define HID_WAITBOX 0x80710400 // IDD_GENERAL +#define HID_WAITBUDDY 0x807103ff // IDD_GENERAL +#define HID_WAITTEXT 0x807103fe // IDD_GENERAL diff --git a/texture.c b/texture.c new file mode 100644 index 0000000..a7ec776 --- /dev/null +++ b/texture.c @@ -0,0 +1,256 @@ +#include +#include +#include + +void +bwtorgba(unsigned char *b,unsigned char *l,int n) { + while(n--) { + l[0] = *b; + l[1] = *b; + l[2] = *b; + l[3] = 0xff; + l += 4; b++; + } +} + +void +latorgba(unsigned char *b, unsigned char *a,unsigned char *l,int n) { + while(n--) { + l[0] = *b; + l[1] = *b; + l[2] = *b; + l[3] = *a; + l += 4; b++; a++; + } +} + +void +rgbtorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) { + while(n--) { + l[0] = r[0]; + l[1] = g[0]; + l[2] = b[0]; + l[3] = 0xff; + l += 4; r++; g++; b++; + } +} + +void +rgbatorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *a,unsigned char *l,int n) { + while(n--) { + l[0] = r[0]; + l[1] = g[0]; + l[2] = b[0]; + l[3] = a[0]; + l += 4; r++; g++; b++; a++; + } +} + +typedef struct _ImageRec { + unsigned short imagic; + unsigned short type; + unsigned short dim; + unsigned short xsize, ysize, zsize; + unsigned int min, max; + unsigned int wasteBytes; + char name[80]; + unsigned long colorMap; + FILE *file; + unsigned char *tmp, *tmpR, *tmpG, *tmpB; + unsigned long rleEnd; + unsigned int *rowStart; + int *rowSize; +} ImageRec; + +static void +ConvertShort(unsigned short *array, long length) { + unsigned b1, b2; + unsigned char *ptr; + + ptr = (unsigned char *)array; + while (length--) { + b1 = *ptr++; + b2 = *ptr++; + *array++ = (b1 << 8) | (b2); + } +} + +static void +ConvertLong(unsigned *array, long length) { + unsigned b1, b2, b3, b4; + unsigned char *ptr; + + ptr = (unsigned char *)array; + while (length--) { + b1 = *ptr++; + b2 = *ptr++; + b3 = *ptr++; + b4 = *ptr++; + *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4); + } +} + +static ImageRec *ImageOpen(const char *fileName) +{ + union { + int testWord; + char testByte[4]; + } endianTest; + ImageRec *image; + int swapFlag; + int x; + + endianTest.testWord = 1; + if (endianTest.testByte[0] == 1) { + swapFlag = 1; + } else { + swapFlag = 0; + } + + image = (ImageRec *)malloc(sizeof(ImageRec)); + if (image == NULL) { + fprintf(stderr, "Out of memory!\n"); + exit(1); + } + if ((image->file = fopen(fileName, "rb")) == NULL) { + perror(fileName); + exit(1); + } + + fread(image, 1, 12, image->file); + + if (swapFlag) { + ConvertShort(&image->imagic, 6); + } + + image->tmp = (unsigned char *)malloc(image->xsize*256); + image->tmpR = (unsigned char *)malloc(image->xsize*256); + image->tmpG = (unsigned char *)malloc(image->xsize*256); + image->tmpB = (unsigned char *)malloc(image->xsize*256); + if (image->tmp == NULL || image->tmpR == NULL || image->tmpG == NULL || + image->tmpB == NULL) { + fprintf(stderr, "Out of memory!\n"); + exit(1); + } + + if ((image->type & 0xFF00) == 0x0100) { + x = image->ysize * image->zsize * sizeof(unsigned); + image->rowStart = (unsigned *)malloc(x); + image->rowSize = (int *)malloc(x); + if (image->rowStart == NULL || image->rowSize == NULL) { + fprintf(stderr, "Out of memory!\n"); + exit(1); + } + image->rleEnd = 512 + (2 * x); + fseek(image->file, 512, SEEK_SET); + fread(image->rowStart, 1, x, image->file); + fread(image->rowSize, 1, x, image->file); + if (swapFlag) { + ConvertLong(image->rowStart, x/sizeof(unsigned)); + ConvertLong((unsigned *)image->rowSize, x/sizeof(int)); + } + } + return image; +} + +static void +ImageClose(ImageRec *image) { + fclose(image->file); + free(image->tmp); + free(image->tmpR); + free(image->tmpG); + free(image->tmpB); + free(image); +} + +static void +ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) { + unsigned char *iPtr, *oPtr, pixel; + int count; + + if ((image->type & 0xFF00) == 0x0100) { + fseek(image->file, image->rowStart[y+z*image->ysize], SEEK_SET); + fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize], + image->file); + + iPtr = image->tmp; + oPtr = buf; + while (1) { + pixel = *iPtr++; + count = (int)(pixel & 0x7F); + if (!count) { + return; + } + if (pixel & 0x80) { + while (count--) { + *oPtr++ = *iPtr++; + } + } else { + pixel = *iPtr++; + while (count--) { + *oPtr++ = pixel; + } + } + } + } else { + fseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize), + SEEK_SET); + fread(buf, 1, image->xsize, image->file); + } +} + +unsigned char* +readTexture(char *name, int *width, int *height, int *components) { + unsigned *base, *lptr; + unsigned char *rbuf, *gbuf, *bbuf, *abuf; + ImageRec *image; + int y; + + image = ImageOpen(name); + + if(!image) + return NULL; + (*width)=image->xsize; + (*height)=image->ysize; + (*components)=image->zsize; + base = (unsigned *)malloc(image->xsize*image->ysize*sizeof(unsigned)); + rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char)); + gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char)); + bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char)); + abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char)); + if(!base || !rbuf || !gbuf || !bbuf) + return NULL; + lptr = base; + for(y=0; yysize; y++) { + if(image->zsize>=4) { + ImageGetRow(image,rbuf,y,0); + ImageGetRow(image,gbuf,y,1); + ImageGetRow(image,bbuf,y,2); + ImageGetRow(image,abuf,y,3); + rgbatorgba(rbuf,gbuf,bbuf,abuf,(unsigned char *)lptr,image->xsize); + lptr += image->xsize; + } else if(image->zsize==3) { + ImageGetRow(image,rbuf,y,0); + ImageGetRow(image,gbuf,y,1); + ImageGetRow(image,bbuf,y,2); + rgbtorgba(rbuf,gbuf,bbuf,(unsigned char *)lptr,image->xsize); + lptr += image->xsize; + } else if(image->zsize==2) { + ImageGetRow(image,rbuf,y,0); + ImageGetRow(image,abuf,y,1); + latorgba(rbuf,abuf,(unsigned char *)lptr,image->xsize); + lptr += image->xsize; + } else { + ImageGetRow(image,rbuf,y,0); + bwtorgba(rbuf,(unsigned char *)lptr,image->xsize); + lptr += image->xsize; + } + } + ImageClose(image); + free(rbuf); + free(gbuf); + free(bbuf); + free(abuf); + + return (unsigned char*) base; +} diff --git a/texture.h b/texture.h new file mode 100644 index 0000000..27e601d --- /dev/null +++ b/texture.h @@ -0,0 +1,24 @@ +/* + * read_texture() - read in an image file in SGI 'libimage' format + * currently its very simple minded and converts all images + * to RGBA8 regardless of the input format and returns the + * original number of components in the appropriate parameter. + * + * + * the components are converted as follows + * L -> LLL 1.0 + * LA -> LLL A + * RGB -> RGB 1.0 + * RGBA -> RGB A + * + */ +#ifdef __cplusplus + extern "C" { +#endif + +unsigned char* +readTexture(const char *name, int *width, int *height, int *components); + +#ifdef __cplusplus + }; +#endif