#include "main.h" #include "scene.h" #include "modes.h" #include #include #include #include #include #include #include "resource.h" #define MY_HKEY "Software\\Fireflies\\2.0" //Define a Windows timer #define TIMER 1 // the default fps double fps = 20; Scene scene; static struct timeb then; void init_gl(HWND hWnd, HDC & hDC, HGLRC & hRC) { PIXELFORMATDESCRIPTOR pfd; ZeroMemory( &pfd, sizeof pfd ); pfd.nSize = sizeof pfd; pfd.nVersion = 1; //pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; //blaine's pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 24; hDC = GetDC( hWnd ); int i = ChoosePixelFormat( hDC, &pfd ); SetPixelFormat( hDC, i, &pfd ); hRC = wglCreateContext( hDC ); wglMakeCurrent( hDC, hRC ); } // Shut down OpenGL void close_gl(HWND hWnd, HDC hDC, HGLRC hRC) { wglMakeCurrent( NULL, NULL ); wglDeleteContext( hRC ); ReleaseDC( hWnd, hDC ); } void start_animate(int width, int height) { glViewport(0, 0, width, height); scene.resize(width, height); scene.create(); ftime(&then); } void on_timer(HDC hDC) //increment and display { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); struct timeb now; ftime(&now); double t = double(now.time - then.time) + double((now.millitm - then.millitm)/1000.0); then = now; scene.elapse(t); scene.apply_camera(); scene.draw(); glFinish(); SwapBuffers(hDC); } // Registry bullshit void reg_get_val(HKEY key, char *str, bool *val) { DWORD dsize = sizeof(int); DWORD dwtype = 0; int tmp; if (RegQueryValueEx(key, str, 0, &dwtype, (BYTE*)&tmp, &dsize)==0) *val = (tmp==1); } void reg_get_val(HKEY key, char *str, int *val) { DWORD dsize = sizeof(int); DWORD dwtype = 0; int tmp; if (RegQueryValueEx(key, str, 0, &dwtype, (BYTE*)&tmp, &dsize)==0) *val = tmp; } void reg_get_val(HKEY key, char *str, unsigned *val) { DWORD dsize = sizeof(int); DWORD dwtype = 0; int tmp; if (RegQueryValueEx(key, str, 0, &dwtype, (BYTE*)&tmp, &dsize)==0) *val = (unsigned)tmp; } void reg_get_val(HKEY key, char *str, double *val) { DWORD dsize = sizeof(int); DWORD dwtype = 0; int tmp; if (RegQueryValueEx(key, str, 0, &dwtype, (BYTE*)&tmp, &dsize)==0) *val = (double)tmp; } void reg_get_val_div10(HKEY key, char *str, double *val) { DWORD dsize = sizeof(int); DWORD dwtype = 0; int tmp; if (RegQueryValueEx(key, str, 0, &dwtype, (BYTE*)&tmp, &dsize)==0) *val = (double)tmp/10.0; } void reg_get_val_div100(HKEY key, char *str, double *val) { DWORD dsize = sizeof(int); DWORD dwtype = 0; int tmp; if (RegQueryValueEx(key, str, 0, &dwtype, (BYTE*)&tmp, &dsize)==0) *val = (double)tmp/100.0; } void reg_set_val(HKEY key, char *str, bool val) { int tmp = val ? 1 : 0; RegSetValueEx(key, str, 0, REG_DWORD, (BYTE*)&tmp, sizeof(tmp)); } void reg_set_val(HKEY key, char *str, int val) { RegSetValueEx(key, str, 0, REG_DWORD, (BYTE*)&val, sizeof(val)); } void reg_set_val(HKEY key, char *str, unsigned val) { RegSetValueEx(key, str, 0, REG_DWORD, (BYTE*)&val, sizeof(val)); } void reg_set_val(HKEY key, char *str, double val) { int tmp = (int)val; RegSetValueEx(key, str, 0, REG_DWORD, (BYTE*)&tmp, sizeof(tmp)); } void reg_set_val_tim10(HKEY key, char *str, double val) { int tmp = (int)(val*10); RegSetValueEx(key, str, 0, REG_DWORD, (BYTE*)&tmp, sizeof(tmp)); } void reg_set_val_tim100(HKEY key, char *str, double val) { int tmp = (int)(val*100); RegSetValueEx(key, str, 0, REG_DWORD, (BYTE*)&tmp, sizeof(tmp)); } void read_config() { HKEY key; char buf[256]; double tmp; scene.set_defaults(); if (RegOpenKeyEx( HKEY_CURRENT_USER, MY_HKEY, 0, //reserved KEY_QUERY_VALUE, &key) == ERROR_SUCCESS) { reg_get_val(key, "minbaits", &scene.minbaits); reg_get_val(key, "maxbaits", &scene.maxbaits); reg_get_val(key, "minflies", &scene.minflies); reg_get_val(key, "maxflies", &scene.maxflies); reg_get_val_div10(key, "fsize", &scene.fsize); reg_get_val(key, "bspeed", &scene.bspeed); reg_get_val(key, "baccel", &scene.baccel); reg_get_val(key, "fspeed", &scene.fspeed); reg_get_val(key, "faccel", &scene.faccel); reg_get_val(key, "hue_rate", &scene.hue_rate); reg_get_val_div10(key, "tail_length", &scene.tail_length); reg_get_val_div10(key, "tail_width", &scene.tail_width); reg_get_val_div100(key, "tail_opaq", &scene.tail_opaq); reg_get_val_div10(key, "glow_factor", &scene.glow_factor); reg_get_val_div10(key, "wind_speed", &scene.wind_speed); reg_get_val(key, "draw_bait", &scene.draw_bait); reg_get_val(key, "fast_forward", &scene.fast_forward); reg_get_val(key, "fps", &fps); for (GLuint i = 0; i < NUM_BMODES; i++) { snprintf(buf, sizeof(buf), "bmode%d", i); reg_get_val(key, buf, &tmp); scene.bmodes.change(i, tmp); } for (GLuint i = 0; i < NUM_SMODES; i++) { snprintf(buf, sizeof(buf), "smode%d", i); reg_get_val(key, buf, &tmp); scene.smodes.change(i, tmp); } RegCloseKey(key); } } void write_config(HWND hDlg) { HKEY key; DWORD lpdw; scene.minbaits = (int)GetDlgItemInt(hDlg, IDC_CONF_MINBAITS, 0, TRUE); scene.maxbaits = (int)GetDlgItemInt(hDlg, IDC_CONF_MAXBAITS, 0, TRUE); scene.minflies = (int)GetDlgItemInt(hDlg, IDC_CONF_MINFLIES, 0, TRUE); scene.maxflies = (int)GetDlgItemInt(hDlg, IDC_CONF_MAXFLIES, 0, TRUE); scene.fsize = ((int)GetDlgItemInt(hDlg, IDC_CONF_FSIZE, 0, TRUE))/10.0; scene.bspeed = (int)GetDlgItemInt(hDlg, IDC_CONF_BSPEED, 0, TRUE); scene.baccel = (int)GetDlgItemInt(hDlg, IDC_CONF_BACCEL, 0, TRUE); scene.fspeed = (int)GetDlgItemInt(hDlg, IDC_CONF_FSPEED, 0, TRUE); scene.faccel = (int)GetDlgItemInt(hDlg, IDC_CONF_FACCEL, 0, TRUE); scene.hue_rate = (int)GetDlgItemInt(hDlg, IDC_CONF_HUERATE, 0, TRUE); scene.tail_length = ((int)GetDlgItemInt(hDlg, IDC_CONF_TAILLENGTH, 0, TRUE))/10.0; scene.tail_width = ((int)GetDlgItemInt(hDlg, IDC_CONF_TAILWIDTH, 0, TRUE))/10.0; scene.tail_opaq = ((int)GetDlgItemInt(hDlg, IDC_CONF_TAILOPAQ, 0, TRUE))/100.0; scene.glow_factor = ((int)GetDlgItemInt(hDlg, IDC_CONF_GLOWFACTOR, 0, TRUE))/10.0; scene.wind_speed = ((int)GetDlgItemInt(hDlg, IDC_CONF_WIND, 0, TRUE))/10.0; scene.draw_bait = (IsDlgButtonChecked(hDlg, IDC_CONF_DRAWBAIT)==BST_CHECKED); scene.fast_forward = (int)GetDlgItemInt(hDlg, IDC_CONF_FASTFORWARD, 0, TRUE); fps = (int)GetDlgItemInt(hDlg, IDC_CONF_FPS, 0, TRUE); for (GLuint i = 0; i < NUM_BMODES; i++) { scene.bmodes.change(i, (double) (UINT)GetDlgItemInt(hDlg, IDC_CONF_BMODE(i), 0, FALSE)); } for (GLuint i = 0; i < NUM_SMODES; i++) { scene.smodes.change(i, (double) (UINT)GetDlgItemInt(hDlg, IDC_CONF_SMODE(i), 0, FALSE)); } if (RegCreateKeyEx( HKEY_CURRENT_USER, MY_HKEY, 0, //reserved "", //ptr to null-term string specifying the object type of this key REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &key, &lpdw) == ERROR_SUCCESS) { reg_set_val(key, "minbaits", scene.minbaits); reg_set_val(key, "maxbaits", scene.maxbaits); reg_set_val(key, "minflies", scene.minflies); reg_set_val(key, "maxflies", scene.maxflies); reg_set_val_tim10(key, "fsize", scene.fsize); reg_set_val(key, "bspeed", scene.bspeed); reg_set_val(key, "baccel", scene.baccel); reg_set_val(key, "fspeed", scene.fspeed); reg_set_val(key, "faccel", scene.faccel); reg_set_val(key, "hue_rate", scene.hue_rate); reg_set_val_tim10(key, "tail_length", scene.tail_length); reg_set_val_tim10(key, "tail_width", scene.tail_width); reg_set_val_tim100(key, "tail_opaq", scene.tail_opaq); reg_set_val_tim10(key, "glow_factor", scene.glow_factor); reg_set_val_tim10(key, "wind_speed", scene.wind_speed); reg_set_val(key, "draw_bait", scene.draw_bait); reg_set_val(key, "fast_forward", scene.fast_forward); reg_set_val(key, "fps", fps); char buf[256]; for (GLuint i = 0; i < NUM_BMODES; i++) { snprintf(buf, sizeof(buf), "bmode%d", i); reg_set_val(key, buf, scene.bmodes.events[i].second); } for (GLuint i = 0; i < NUM_SMODES; i++) { snprintf(buf, sizeof(buf), "smode%d", i); reg_set_val(key, buf, scene.smodes.events[i].second); } RegCloseKey(key); } } // main() function LRESULT WINAPI ScreenSaverProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static HDC hDC; static HGLRC hRC; static RECT rect; int width, height; srand(time(0)); switch ( message ) { case WM_CREATE: GetClientRect(hWnd, &rect); width = rect.right; height = rect.bottom; read_config(); init_gl( hWnd, hDC, hRC ); start_animate(width, height); // tick every 1000/fps ms SetTimer( hWnd, TIMER, (unsigned)(1000/fps), NULL ); return 0; case WM_DESTROY: KillTimer( hWnd, TIMER ); close_gl(hWnd, hDC, hRC); return 0; case WM_TIMER: on_timer(hDC); return 0; } return DefScreenSaverProc(hWnd, message, wParam, lParam); } void set_dialog(HWND hDlg) { SetDlgItemInt(hDlg, IDC_CONF_MINBAITS, (UINT)scene.minbaits, TRUE); SetDlgItemInt(hDlg, IDC_CONF_MAXBAITS, (UINT)scene.maxbaits, TRUE); SetDlgItemInt(hDlg, IDC_CONF_MINFLIES, (UINT)scene.minflies, TRUE); SetDlgItemInt(hDlg, IDC_CONF_MAXFLIES, (UINT)scene.maxflies, TRUE); SetDlgItemInt(hDlg, IDC_CONF_FSIZE, (UINT)(scene.fsize*10), TRUE); SetDlgItemInt(hDlg, IDC_CONF_BSPEED, (UINT)scene.bspeed, TRUE); SetDlgItemInt(hDlg, IDC_CONF_BACCEL, (UINT)scene.baccel, TRUE); SetDlgItemInt(hDlg, IDC_CONF_FSPEED, (UINT)scene.fspeed, TRUE); SetDlgItemInt(hDlg, IDC_CONF_FACCEL, (UINT)scene.faccel, TRUE); SetDlgItemInt(hDlg, IDC_CONF_HUERATE, (UINT)scene.hue_rate, TRUE); SetDlgItemInt(hDlg, IDC_CONF_TAILLENGTH, (UINT)(scene.tail_length*10), TRUE); SetDlgItemInt(hDlg, IDC_CONF_TAILWIDTH, (UINT)(scene.tail_width*10), TRUE); SetDlgItemInt(hDlg, IDC_CONF_TAILOPAQ, (UINT)(scene.tail_opaq*100), TRUE); SetDlgItemInt(hDlg, IDC_CONF_GLOWFACTOR, (UINT)(scene.glow_factor*10), TRUE); SetDlgItemInt(hDlg, IDC_CONF_WIND, (UINT)(scene.wind_speed*10), TRUE); SetDlgItemInt(hDlg, IDC_CONF_FASTFORWARD, (UINT)(scene.fast_forward), TRUE); SetDlgItemInt(hDlg, IDC_CONF_FPS, (UINT)(fps), TRUE); CheckDlgButton(hDlg, IDC_CONF_DRAWBAIT, scene.draw_bait ? BST_CHECKED : BST_UNCHECKED); for (GLuint i = 0; i < NUM_BMODES; i++) { SetDlgItemInt(hDlg, IDC_CONF_BMODE(scene.bmodes.events[i].first), (UINT)scene.bmodes.events[i].second, FALSE); } for (GLuint i = 0; i < NUM_SMODES; i++) { SetDlgItemInt(hDlg, IDC_CONF_SMODE(scene.smodes.events[i].first), (UINT)scene.smodes.events[i].second, FALSE); } } // configure dialog BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static HWND hIDOK; switch (message) { case WM_INITDIALOG: LoadString(hMainInstance, IDS_DESCRIPTION, szAppName, 40); read_config(); set_dialog(hDlg); hIDOK = GetDlgItem(hDlg, IDOK); return TRUE; case WM_COMMAND: switch (wParam) { case IDOK: write_config(hDlg); EndDialog(hDlg, TRUE); return TRUE; case IDCANCEL: EndDialog(hDlg, FALSE); return TRUE; case IDC_DEFAULTS: scene.set_defaults(); fps = 20; set_dialog(hDlg); return TRUE; } break; } return FALSE; } // needed for SCRNSAVE.LIB BOOL WINAPI RegisterDialogClasses(HANDLE hInst) { return TRUE; }