void Update() { const float t_sens=float(0.1); const float r_sens=float(0.1); euler_rotation.y+=input::mouseX; euler_rotation.x+=input::mouseY; rotation = quaternionf(vec3f(1,0,0),r_sens*euler_rotation.x*NV_PI/180); rotation*= quaternionf(vec3f(0,1,0),r_sens*euler_rotation.y*NV_PI/180); vec3f l_right(1,0,0); vec3f l_forward(0,0,1); quaternionf rev = inverse(rotation); rev.mult_vec(l_forward); rev.mult_vec(l_right); position-= (t_sens * (input::Forward-input::Backward))*l_forward; position-= (t_sens * (input::LeftStrafe-input::RightStrafe))*l_right; }
/* draw_thread This is the drawing-thread. You have a valid presentation space handle (hps), a valid window handle (hwndSaver) and the configuration_data structure is loaded. The screen size is stored in "screenSizeX" and "screenSizeY". IMPORTANT NOTE 1: You must check the "stop_draw_thread" flag regularly. If it is set, free all resources you have allocated and call _endthread (or just return) to end the drawing-thread. IMPORTANT NOTE 2: If the "low_priority" flag is NOT set (that means you run with regular priority, sharing CPU usage with other programs), you should call DosSleep(x) with "x" set at least to 1 as often as possible, to allow other programs to do their work. A screen saver should not eat up other program's CPU time! IMPORTANT NOTE 3: For some of the PM calls to work properly, your thread needs an own HAB and maybe even a message queue. You have to get and release both of them here if you use such PM calls. The following sample code is from the "Pyramids" module that comes with the ScreenSaver distribution. It selects a random color and a random point on the screen, then draws lines in the selected color from each corner of the screen to the selected point (looks somewhat like a pyramid). It remembers a number of points (this number can be set in the configuration dialog). Having filled the point memory, it redraws the "oldest" visible pyramid in black. This has the effect that more and more pixels on the screen get black, only a few constantly changing colored lines remain. */ void draw_thread(void *args) { POINTL BitmapPoints[4] = { 1, 1, screenSizeX + 2, screenSizeY + 2, -1, -1, screenSizeX, screenSizeY }; POINTL l_b = { 0, 0 }, l_t = { 0, screenSizeY - 1 }, r_b = { screenSizeX - 1, 0 }, r_t = { screenSizeX - 1, screenSizeY - 1 }; INT i, step; VOID l_left() { GpiMove( hps, &l_b ); GpiLine( hps, &l_t ); } VOID l_right() { GpiMove( hps, &r_b ); GpiLine( hps, &r_t ); } VOID l_top() { GpiMove( hps, &l_t ); GpiLine( hps, &r_t ); } VOID l_bottom() { GpiMove( hps, &l_b ); GpiLine( hps, &r_b ); } srand(WinGetCurrentTime( hab )); GpiSetColor( hps, CLR_BLACK ); l_left(); while(!stop_draw_thread){ if( configuration_data.drunken ){ step = (unsigned)rand() % 8; switch ( step ){ case 0: BitmapPoints[0].x = -1; BitmapPoints[0].y = 0; BitmapPoints[1].x = screenSizeX; BitmapPoints[1].y = screenSizeY + 1; l_bottom(); break; case 1: BitmapPoints[0].x = 0; BitmapPoints[0].y = 0; BitmapPoints[1].x = screenSizeX + 1; BitmapPoints[1].y = screenSizeY + 1; l_bottom(); l_left(); break; case 2: BitmapPoints[0].x = 0; BitmapPoints[0].y = -1; BitmapPoints[1].x = screenSizeX + 1; BitmapPoints[1].y = screenSizeY; l_left(); break; case 3: BitmapPoints[0].x = 0; BitmapPoints[0].y = -2; BitmapPoints[1].x = screenSizeX + 1; BitmapPoints[1].y = screenSizeY - 1; l_left(); l_top(); break; case 4: BitmapPoints[0].x = -1; BitmapPoints[0].y = -2; BitmapPoints[1].x = screenSizeX; BitmapPoints[1].y = screenSizeY - 1; l_top(); break; case 5: BitmapPoints[0].x = -2; BitmapPoints[0].y = -2; BitmapPoints[1].x = screenSizeX - 1; BitmapPoints[1].y = screenSizeY - 1; l_top(); l_right(); break; case 6: BitmapPoints[0].x = -2; BitmapPoints[0].y = -1; BitmapPoints[1].x = screenSizeX - 1; BitmapPoints[1].y = screenSizeY; l_right(); break; case 7: BitmapPoints[0].x = -2; BitmapPoints[0].y = 0; BitmapPoints[1].x = screenSizeX - 1; BitmapPoints[1].y = screenSizeY + 1; l_right(); l_bottom(); break; } } for( i = 1; i < 5; i++){ GpiBitBlt( hps, hps, 3, BitmapPoints, ROP_SRCCOPY, BBO_IGNORE ); if( stop_draw_thread) i = 10; } // sleep if necessary if(low_priority == FALSE) DosSleep(1); // sleep if user requests slower animation switch(configuration_data.animation_speed){ case 4: break; case 3: DosSleep(10); break; case 2: DosSleep(30); break; case 1: DosSleep(50); break; case 0: DosSleep(70); break; } } // free resources _endthread(); }