Unified windows Procs to eliminate redundant code. New dev keyboard camera controls. Screensaver now timer-based instead of waiting for WM_PAINT.

This commit is contained in:
Shamus Young 2009-05-07 14:30:09 +00:00
parent 0c5876b90d
commit fd21a23081
4 changed files with 340 additions and 396 deletions

View File

@ -454,6 +454,20 @@ void static do_help (void)
}
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
void do_fps ()
{
LIMIT_INTERVAL (1000);
current_fps = frames;
frames = 0;
}
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
@ -708,12 +722,13 @@ void RenderUpdate (void)
GLvector angle;
GLrgba color;
frames++;
do_fps ();
glViewport (0, 0, WinWidth (), WinHeight ());
glClearColor (0.0f, 0.0f, 0.0f, 1.0f);
if (letterbox)
glViewport (0, letterbox_offset, render_width, render_height);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (TextureReady () && !EntityReady ()) {
do_effects (-1);
SwapBuffers (hDC);
@ -776,23 +791,18 @@ void RenderUpdate (void)
}
do_effects (effect);
//Framerate tracker
if (GetTickCount () > next_fps) {
current_fps = frames;
frames = 0;
next_fps = GetTickCount () + 1000;
}
if (show_fps && !show_help) {
RenderPrint (1, "FPS=%d", current_fps);
RenderPrint (2, "Entities=%d", EntityCount () + LightCount () + CarCount ());
RenderPrint (3, "Lights=%d", LightCount ());
RenderPrint (4, "Polys=%d", EntityPolyCount () + LightCount () + CarCount ());
RenderPrint (5, "Building=%1.2f", EntityProgress () * 100);
RenderPrint (2, "FPS=%d", current_fps);
RenderPrint (3, "Entities=%d", EntityCount () + LightCount () + CarCount ());
RenderPrint (4, "Lights=%d", LightCount ());
RenderPrint (5, "Polys=%d", EntityPolyCount () + LightCount () + CarCount ());
RenderPrint (6, "Building=%1.2f", EntityProgress () * 100);
RenderPrint (7, "%d", GetTickCount ());
}
//Show the help overlay
if (show_help)
do_help ();
glDepthMask (true);
frames++;
SwapBuffers (hDC);
}

672
Win.cpp
View File

@ -34,11 +34,14 @@
#include "visible.h"
#pragma comment (lib, "opengl32.lib")
#pragma comment (lib, "winmm.lib")
#pragma comment (lib, "glu32.lib")
#if SCREENSAVER
#pragma comment (lib, "scrnsave.lib")
#endif
static HWND hwnd;
static HINSTANCE module;
static int width;
@ -53,6 +56,8 @@ static POINT mouse_pos;
static bool quit;
static HINSTANCE instance;
LONG WINAPI ScreenSaverProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
@ -93,141 +98,6 @@ static void MoveCursor (int x, int y)
}
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
RECT r;
float delta_x, delta_y;
POINT p;
int param;
int key;
switch (message) {
case WM_SIZE:
param = wParam; // resizing flag
width = LOWORD(lParam); // width of client area
height = HIWORD(lParam); // height of client area
if (param == SIZE_RESTORED)
IniIntSet ("WindowMaximized", 0);
if (param == SIZE_MAXIMIZED) {
IniIntSet ("WindowMaximized", 1);
} else {
IniIntSet ("WindowWidth", width);
IniIntSet ("WindowHeight", height);
}
RenderResize ();
return 0;
case WM_MOVE:
GetClientRect (hwnd, &r);
height = r.bottom - r.top;
width = r.right - r.left;
IniIntSet ("WindowX", r.left);
IniIntSet ("WindowY", r.top);
IniIntSet ("WindowWidth", width);
IniIntSet ("WindowHeight", height);
half_width = width / 2;
half_height = height / 2;
break;
case WM_KEYDOWN:
key = (int) wParam;
if (key == 'R')
WorldReset ();
if (key == 'C')
CameraAutoToggle ();
if (key == 'W')
RenderWireframeToggle ();
if (key == 'E')
RenderEffectCycle ();
if (key == 'L')
RenderLetterboxToggle ();
if (key == 'F')
RenderFPSToggle ();
if (key == 'G')
RenderFogToggle ();
if (key == 'T')
RenderFlatToggle ();
if (key == VK_F1)
RenderHelpToggle ();
if (key == 'B')
CameraNextBehavior ();
if (key == VK_ESCAPE)
quit = true;
if (key == VK_F5)
CameraReset ();
return 0;
case WM_LBUTTONDOWN:
lmb = true;
SetCapture (hwnd);
break;
case WM_RBUTTONDOWN:
rmb = true;
SetCapture (hwnd);
break;
case WM_LBUTTONUP:
lmb = false;
if (!rmb) {
ReleaseCapture ();
MoveCursor (select_pos.x, select_pos.y);
}
break;
case WM_RBUTTONUP:
rmb = false;
if (!lmb) {
ReleaseCapture ();
MoveCursor (select_pos.x, select_pos.y);
}
break;
case WM_MOUSEMOVE:
p.x = LOWORD(lParam); // horizontal position of cursor
p.y = HIWORD(lParam); // vertical position of cursor
if (p.x < 0 || p.x > width)
break;
if (p.y < 0 || p.y > height)
break;
if (!mouse_forced && !lmb && !rmb) {
select_pos = p;
}
if (mouse_forced) {
mouse_forced = false;
} else if (rmb || lmb) {
CenterCursor ();
delta_x = (float)(mouse_pos.x - p.x) * MOUSE_MOVEMENT;
delta_y = (float)(mouse_pos.y - p.y) * MOUSE_MOVEMENT;
if (rmb && lmb) {
GLvector pos;
CameraPan (delta_x);
pos = CameraPosition ();
pos.y += delta_y;
CameraPositionSet (pos);
} else if (rmb) {
CameraPan (delta_x);
CameraForward (delta_y);
} else if (lmb) {
GLvector angle;
angle = CameraAngle ();
angle.y -= delta_x;
angle.x += delta_y;
CameraAngleSet (angle);
}
}
mouse_pos = p;
break;
case WM_CLOSE:
quit = true;
return 0;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
/*-----------------------------------------------------------------------------
n o t e
-----------------------------------------------------------------------------*/
@ -303,6 +173,296 @@ HWND WinHwnd (void)
}
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
void AppQuit ()
{
quit = true;
}
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
void AppUpdate ()
{
CameraUpdate ();
WorldUpdate ();
TextureUpdate ();
VisibleUpdate ();
CarUpdate ();
EntityUpdate ();
RenderUpdate ();
}
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
void CALLBACK Appx (HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
{
static int ii;
//for (int i = 0; i < 1000;i++)
AppUpdate ();
ii++;
if (ii > 1)
ii++;
//PostQuitMessage (1);
//exit (1);
}
static void do_timer ()
{
TIMECAPS tc;
int resolution;
if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) {
resolution = 0;
}
resolution = min(max(tc.wPeriodMin, 1), tc.wPeriodMax);
if (!timeSetEvent (1, resolution,(LPTIMECALLBACK)Appx, 123, TIME_PERIODIC | TIME_CALLBACK_FUNCTION ))
resolution = 0;
}
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
void AppInit (void)
{
RandomInit (time (NULL));
CameraInit ();
RenderInit ();
TextureInit ();
WorldInit ();
}
/*-----------------------------------------------------------------------------
W i n M a i n
-----------------------------------------------------------------------------*/
void AppTerm (void)
{
TextureTerm ();
WorldTerm ();
RenderTerm ();
CameraTerm ();
WinTerm ();
}
/*-----------------------------------------------------------------------------
W i n M a i n
-----------------------------------------------------------------------------*/
#if !SCREENSAVER
int PASCAL WinMain (HINSTANCE instance_in, HINSTANCE previous_instance,
LPSTR command_line, int show_style)
{
MSG msg;
instance = instance_in;
WinInit ();
AppInit ();
while (!quit) {
if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT)
quit = true;
else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} else
AppUpdate ();
}
AppTerm ();
return 0;
}
#else
BOOL WINAPI ScreenSaverConfigureDialog (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { return FALSE; }
BOOL WINAPI RegisterDialogClasses(HANDLE hInst) { return TRUE; }
#endif
LONG WINAPI ScreenSaverProc(HWND hwnd_in,UINT message,WPARAM wparam,LPARAM lparam)
{
RECT r;
int key;
float delta_x, delta_y;
POINT p;
// Handles screen saver messages
switch(message)
{
case WM_SIZE:
width = LOWORD(lparam); // width of client area
height = HIWORD(lparam); // height of client area
if (wparam == SIZE_MAXIMIZED) {
IniIntSet ("WindowMaximized", 1);
} else {
IniIntSet ("WindowWidth", width);
IniIntSet ("WindowHeight", height);
IniIntSet ("WindowMaximized", 0);
}
RenderResize ();
break;
case WM_KEYDOWN:
key = (int) wparam;
if (key == 'R')
WorldReset ();
else if (key == 'W')
RenderWireframeToggle ();
else if (key == 'E')
RenderEffectCycle ();
else if (key == 'L')
RenderLetterboxToggle ();
else if (key == 'F')
RenderFPSToggle ();
else if (key == 'G')
RenderFogToggle ();
else if (key == 'T')
RenderFlatToggle ();
else if (key == VK_F1)
RenderHelpToggle ();
else if (key == VK_ESCAPE)
break;
else if (!SCREENSAVER) {
//Dev mode keys
if (key == 'C')
CameraAutoToggle ();
if (key == 'B')
CameraNextBehavior ();
if (key == VK_F5)
CameraReset ();
if (key == VK_UP)
CameraMedial (1.0f);
if (key == VK_DOWN)
CameraMedial (-1.0f);
if (key == VK_LEFT)
CameraLateral (1.0f);
if (key == VK_RIGHT)
CameraLateral (-1.0f);
if (key == VK_PRIOR)
CameraVertical (1.0f);
if (key == VK_NEXT)
CameraVertical (-1.0f);
if (key == VK_F5)
CameraReset ();
return 0;
} else
break;
return 0;
case WM_MOVE:
GetClientRect (hwnd, &r);
height = r.bottom - r.top;
width = r.right - r.left;
IniIntSet ("WindowX", r.left);
IniIntSet ("WindowY", r.top);
IniIntSet ("WindowWidth", width);
IniIntSet ("WindowHeight", height);
half_width = width / 2;
half_height = height / 2;
return 0;
case WM_LBUTTONDOWN:
lmb = true;
SetCapture (hwnd);
break;
case WM_RBUTTONDOWN:
rmb = true;
SetCapture (hwnd);
break;
case WM_LBUTTONUP:
lmb = false;
if (!rmb) {
ReleaseCapture ();
MoveCursor (select_pos.x, select_pos.y);
}
break;
case WM_RBUTTONUP:
rmb = false;
if (!lmb) {
ReleaseCapture ();
MoveCursor (select_pos.x, select_pos.y);
}
break;
case WM_MOUSEMOVE:
p.x = LOWORD(lparam); // horizontal position of cursor
p.y = HIWORD(lparam); // vertical position of cursor
if (p.x < 0 || p.x > width)
break;
if (p.y < 0 || p.y > height)
break;
if (!mouse_forced && !lmb && !rmb) {
select_pos = p;
}
if (mouse_forced) {
mouse_forced = false;
} else if (rmb || lmb) {
CenterCursor ();
delta_x = (float)(mouse_pos.x - p.x) * MOUSE_MOVEMENT;
delta_y = (float)(mouse_pos.y - p.y) * MOUSE_MOVEMENT;
if (rmb && lmb) {
GLvector pos;
CameraPan (delta_x);
pos = CameraPosition ();
pos.y += delta_y;
CameraPositionSet (pos);
} else if (rmb) {
CameraPan (delta_x);
CameraForward (delta_y);
} else if (lmb) {
GLvector angle;
angle = CameraAngle ();
angle.y -= delta_x;
angle.x += delta_y;
CameraAngleSet (angle);
}
}
mouse_pos = p;
break;
case WM_CREATE:
hwnd = hwnd_in;
AppInit ();
SetTimer (hwnd, 1, 7, NULL);
return 0;
case WM_TIMER:
AppUpdate ();
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
#if SCREENSAVER
return DefScreenSaverProc(hwnd_in,message,wparam,lparam);
#else
return DefWindowProc (hwnd_in,message,wparam,lparam);
#endif
}
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
@ -317,7 +477,7 @@ bool WinInit (void)
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.lpfnWndProc = (WNDPROC)ScreenSaverProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = instance;
@ -355,243 +515,3 @@ bool WinInit (void)
return true;
}
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
void AppQuit ()
{
quit = true;
}
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
void AppInit (void)
{
RandomInit (time (NULL));
CameraInit ();
RenderInit ();
TextureInit ();
WorldInit ();
}
/*-----------------------------------------------------------------------------
-----------------------------------------------------------------------------*/
void AppUpdate ()
{
CameraUpdate ();
WorldUpdate ();
TextureUpdate ();
WorldUpdate ();
VisibleUpdate ();
CarUpdate ();
EntityUpdate ();
WorldUpdate ();
RenderUpdate ();
}
/*-----------------------------------------------------------------------------
W i n M a i n
-----------------------------------------------------------------------------*/
void AppTerm (void)
{
TextureTerm ();
WorldTerm ();
RenderTerm ();
CameraTerm ();
WinTerm ();
}
/*-----------------------------------------------------------------------------
W i n M a i n
-----------------------------------------------------------------------------*/
#if !SCREENSAVER
int PASCAL WinMain (HINSTANCE instance_in, HINSTANCE previous_instance,
LPSTR command_line, int show_style)
{
MSG msg;
instance = instance_in;
WinInit ();
AppInit ();
while (!quit) {
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
if (msg.message == WM_QUIT)
quit = true;
else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} else {
AppUpdate ();
}
}
AppTerm ();
return 0;
}
#else
static bool terminated;
LONG WINAPI ScreenSaverProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
RECT r;
float delta_x, delta_y;
POINT p;
int param;
int key;
if (terminated)
return DefScreenSaverProc (hWnd, msg, wParam, lParam);
switch (msg) {
case WM_CREATE:
hwnd = hWnd;
AppInit ();
return 0;
case WM_CLOSE:
case WM_DESTROY:
AppTerm ();
terminated = true;
return 0;
case WM_PAINT:
AppUpdate ();
return 0;
case WM_MOVE:
case WM_SIZE:
param = wParam; // resizing flag
width = LOWORD(lParam); // width of client area
height = HIWORD(lParam); // height of client area
if (param == SIZE_MAXIMIZED) {
IniIntSet ("WindowMaximized", 1);
} else {
IniIntSet ("WindowWidth", width);
IniIntSet ("WindowHeight", height);
}
RenderResize ();
return 0;
case WM_MOVE:
GetClientRect (hwnd, &r);
height = r.bottom - r.top;
width = r.right - r.left;
IniIntSet ("WindowX", r.left);
IniIntSet ("WindowY", r.top);
IniIntSet ("WindowWidth", width);
IniIntSet ("WindowHeight", height);
half_width = width / 2;
half_height = height / 2;
break;
case WM_KEYDOWN:
key = (int) wParam;
if (key == 'R')
WorldReset ();
else if (key == 'C')
CameraAutoToggle ();
else if (key == 'W')
RenderWireframeToggle ();
else if (key == 'E')
RenderEffectCycle ();
else if (key == 'L')
RenderLetterboxToggle ();
else if (key == 'F')
RenderFPSToggle ();
else if (key == 'G')
RenderFogToggle ();
else if (key == 'T')
RenderFlatToggle ();
else if (key == VK_F1)
RenderHelpToggle ();
else if (key == VK_ESCAPE)
break;
else if (key == VK_F5)
CameraReset ();
else
break;
return 0;
case WM_LBUTTONDOWN:
lmb = true;
SetCapture (hwnd);
break;
case WM_RBUTTONDOWN:
rmb = true;
SetCapture (hwnd);
break;
case WM_LBUTTONUP:
lmb = false;
if (!rmb) {
ReleaseCapture ();
MoveCursor (select_pos.x, select_pos.y);
}
break;
case WM_RBUTTONUP:
rmb = false;
if (!lmb) {
ReleaseCapture ();
MoveCursor (select_pos.x, select_pos.y);
}
break;
case WM_MOUSEMOVE:
p.x = LOWORD(lParam); // horizontal position of cursor
p.y = HIWORD(lParam); // vertical position of cursor
if (p.x < 0 || p.x > width)
break;
if (p.y < 0 || p.y > height)
break;
if (!mouse_forced && !lmb && !rmb) {
select_pos = p;
}
if (mouse_forced) {
mouse_forced = false;
} else if (rmb || lmb) {
CenterCursor ();
delta_x = (float)(mouse_pos.x - p.x) * MOUSE_MOVEMENT;
delta_y = (float)(mouse_pos.y - p.y) * MOUSE_MOVEMENT;
if (rmb && lmb) {
GLvector pos;
CameraPan (delta_x);
pos = CameraPosition ();
pos.y += delta_y;
CameraPositionSet (pos);
} else if (rmb) {
CameraPan (delta_x);
CameraForward (delta_y);
} else if (lmb) {
GLvector angle;
angle = CameraAngle ();
angle.y -= delta_x;
angle.x += delta_y;
CameraAngleSet (angle);
}
}
mouse_pos = p;
break;
}
return DefScreenSaverProc (hWnd, msg, wParam, lParam);
}
BOOL WINAPI ScreenSaverConfigureDialog (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) { return FALSE; }
BOOL WINAPI RegisterDialogClasses(HANDLE hInst) { return TRUE; }
#endif

4
Win.h
View File

@ -5,9 +5,9 @@
#define VERSION_MINOR 0
#define VERSION_REVISION 5
//Best to disable screensaver mode when working on the program.
#define SCREENSAVER 1
#define SCREENSAVER 0
//Controls the density of cars.
#define CARS 500
#define CARS 0
//The "dead zone" along the edge of the world, with super-low detail.
#define WORLD_EDGE 200
//How often to rebuild the city

View File

@ -110,8 +110,8 @@ static int blocky_count;
static bool reset_needed;
static int skyscrapers;
static GLbbox hot_zone;
static unsigned start_time;
static int logo_index;
static unsigned start_time;
/*-----------------------------------------------------------------------------
@ -271,8 +271,9 @@ void do_building (plot p)
if (p.width < 10 || p.depth < 10)
return;
//If the area is too big for one building, sub-divide it.
if (area > 600) {
if (p.width > p.depth) {
if (area > 1400) {
if (COIN_FLIP) {
p.width /= 2;
if (COIN_FLIP)
do_building (make_plot (p.x, p.z, p.width, p.depth));
@ -294,6 +295,7 @@ void do_building (plot p)
square = abs (p.width - p.depth) < 10;
//mark the land as used so other buildings don't appear here, even if we don't use it all.
claim (p.x, p.z, p.width, p.depth, CLAIM_BUILDING);
/*
//The roundy mod buildings look best on square plots.
if (square && p.width > 20) {
height = 45 + RandomVal (10);
@ -302,6 +304,16 @@ void do_building (plot p)
new CBuilding (BUILDING_MODERN, p.x, p.z, height, p.width, p.depth, seed, color);
return;
}
//Rectangular plots are a good place for Blocky style buildsing to sprawl blockily.
if (p.width > p.depth * 2 || p.depth > p.width * 2 && area > 800) {
height = 20 + RandomVal (10);
blocky_count++;
skyscrapers++;
new CBuilding (BUILDING_BLOCKY, p.x, p.z, height, p.width, p.depth, seed, color);
return;
}
*/
tower_count = -1;
//This spot isn't ideal for any particular building, but try to keep a good mix
if (tower_count < modern_count && tower_count < blocky_count) {
type = BUILDING_TOWER;
@ -408,7 +420,7 @@ static void do_reset (void)
bloom_color = get_light_color(0.5f + (float)RandomVal (10) / 20.0f, 0.75f);
light_color = glRgbaFromHsl (0.11f, 1.0f, 0.65f);
ZeroMemory (world, WORLD_SIZE * WORLD_SIZE);
for (y = WORLD_EDGE; y < WORLD_SIZE - WORLD_EDGE; y += RandomVal (30) + 20) {
for (y = WORLD_EDGE; y < WORLD_SIZE - WORLD_EDGE; y += RandomVal (25) + 25) {
if (!broadway_done && y > WORLD_HALF - 20) {
build_road (0, y, WORLD_SIZE, 19);
y += 20;
@ -424,7 +436,7 @@ static void do_reset (void)
}
broadway_done = false;
for (x = WORLD_EDGE; x < WORLD_SIZE - WORLD_EDGE; x += RandomVal (30) + 20) {
for (x = WORLD_EDGE; x < WORLD_SIZE - WORLD_EDGE; x += RandomVal (25) + 25) {
if (!broadway_done && x > WORLD_HALF - 20) {
build_road (x, 0, 19, WORLD_SIZE);
x += 20;
@ -485,6 +497,7 @@ static void do_reset (void)
}
}
//Scan over the center area of the map and place the big buildings
attempts = 0;
while (skyscrapers < 50 && attempts < 350) {
@ -496,6 +509,7 @@ static void do_reset (void)
}
attempts++;
}
//now blanket the rest of the world with lesser buildings
for (x = 0; x < WORLD_SIZE; x ++) {
for (y = 0; y < WORLD_SIZE; y ++) {