diff --git a/rosapps/demos/maze/.cvsignore b/rosapps/demos/maze/.cvsignore new file mode 100644 index 00000000000..a33442cae49 --- /dev/null +++ b/rosapps/demos/maze/.cvsignore @@ -0,0 +1,7 @@ +maze.exe +maze.nostrip.exe +maze.sym +maze.coff +.*.d +*.o +*.map diff --git a/rosapps/demos/maze/Makefile b/rosapps/demos/maze/Makefile new file mode 100644 index 00000000000..daa885e2c77 --- /dev/null +++ b/rosapps/demos/maze/Makefile @@ -0,0 +1,25 @@ +# $Id: Makefile,v 1.1 2003/08/15 17:06:49 gvg Exp $ + +PATH_TO_TOP = ../../../reactos + +TARGET_TYPE = program + +TARGET_APPTYPE = windows + +TARGET_NAME = maze + +TARGET_SDKLIBS = kernel32.a gdi32.a + +TARGET_OBJECTS = maze.o + +TARGET_CFLAGS = -Wall -Werror + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# Automatic dependency tracking +DEP_OBJECTS := $(TARGET_OBJECTS) +include $(PATH_TO_TOP)/tools/depend.mk + +# EOF diff --git a/rosapps/demos/maze/maze.c b/rosapps/demos/maze/maze.c new file mode 100644 index 00000000000..31e561a0e17 --- /dev/null +++ b/rosapps/demos/maze/maze.c @@ -0,0 +1,907 @@ +/****************************************************************************** + * [ maze ] ... + * + * modified: [ 03-08-15 ] Ge van Geldorp + * ported to Reactos + * modified: [ 94-10-8 ] Ge van Geldorp + * ported to MS Windows + * modified: [ 3-7-93 ] Jamie Zawinski + * added the XRoger logo, cleaned up resources, made + * grid size a parameter. + * modified: [ 3-3-93 ] Jim Randell + * Added the colour stuff and integrated it with jwz's + * screenhack stuff. There's still some work that could + * be done on this, particularly allowing a resource to + * specify how big the squares are. + * modified: [ 10-4-88 ] Richard Hess ...!uunet!cimshop!rhess + * [ Revised primary execution loop within main()... + * [ Extended X event handler, check_events()... + * modified: [ 1-29-88 ] Dave Lemke lemke@sun.com + * [ Hacked for X11... + * [ Note the word "hacked" -- this is extremely ugly, but at + * [ least it does the job. NOT a good programming example + * [ for X. + * original: [ 6/21/85 ] Martin Weiss Sun Microsystems [ SunView ] + * + ****************************************************************************** + Copyright 1988 by Sun Microsystems, Inc. Mountain View, CA. + + All Rights Reserved + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, + provided that the above copyright notice appear in all copies and that + both that copyright notice and this permission notice appear in + supporting documentation, and that the names of Sun or MIT not be + used in advertising or publicity pertaining to distribution of the + software without specific prior written permission. Sun and M.I.T. + make no representations about the suitability of this software for + any purpose. It is provided "as is" without any express or implied warranty. + + SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. IN NO EVENT SHALL SUN BE LIABLE FOR ANY SPECIAL, INDIRECT + OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE + OR PERFORMANCE OF THIS SOFTWARE. + *****************************************************************************/ + +#define STRICT + +#include +#include +#include +#include /* required for all Windows applications */ + +#if !defined (APIENTRY) /* Windows NT defines APIENTRY, but 3.x doesn't */ +#define APIENTRY far pascal +#endif + +#if !defined(WIN32) /* Windows 3.x uses a FARPROC for dialogs */ +#define DLGPROC FARPROC +#endif + +static BOOL InitApplication(HINSTANCE hInstance); +static BOOL InitInstance(HINSTANCE hInstance, int nCmdShow); +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM uParam, + LPARAM lParam); + +HINSTANCE hInst; /* current instance */ +HWND hWnd; /* Main window handle.*/ +HBRUSH hBrushDead; +HBRUSH hBrushLiving; +HDC hDC; +static BOOL waiting; + + +char szAppName[] = "Maze"; /* The name of this application */ +char szTitle[] = "Maze"; /* The title bar text */ + +static int solve_delay, pre_solve_delay, post_solve_delay; + +#define MAX_MAZE_SIZE_X ((unsigned long) 250) +#define MAX_MAZE_SIZE_Y ((unsigned long) 250) + +#define MOVE_LIST_SIZE (MAX_MAZE_SIZE_X * MAX_MAZE_SIZE_Y) + +#define WALL_TOP 0x8000 +#define WALL_RIGHT 0x4000 +#define WALL_BOTTOM 0x2000 +#define WALL_LEFT 0x1000 + +#define DOOR_IN_TOP 0x800 +#define DOOR_IN_RIGHT 0x400 +#define DOOR_IN_BOTTOM 0x200 +#define DOOR_IN_LEFT 0x100 +#define DOOR_IN_ANY 0xF00 + +#define DOOR_OUT_TOP 0x80 +#define DOOR_OUT_RIGHT 0x40 +#define DOOR_OUT_BOTTOM 0x20 +#define DOOR_OUT_LEFT 0x10 + +#define START_SQUARE 0x2 +#define END_SQUARE 0x1 + +#define border_x (0) +#define border_y (0) + +#define get_random(x) (rand() % (x)) + +static unsigned short maze[MAX_MAZE_SIZE_X][MAX_MAZE_SIZE_Y]; + +static struct { + unsigned char x; + unsigned char y; + unsigned char dir; + unsigned char dummy; +} move_list[MOVE_LIST_SIZE], save_path[MOVE_LIST_SIZE], path[MOVE_LIST_SIZE]; + +static int maze_size_x, maze_size_y; +static long sqnum, path_length; +static int cur_sq_x, cur_sq_y; +static int start_x, start_y, start_dir, end_x, end_y, end_dir; +static int grid_width, grid_height; + +static int state = 1, pathi = 0; + +static void +set_maze_sizes (width, height) + int width, height; +{ + maze_size_x = width / grid_width; + maze_size_y = height / grid_height; +} + + +static void +initialize_maze() /* draw the surrounding wall and start/end squares */ +{ + register int i, j, wall; + + /* initialize all squares */ + for ( i=0; i> wall ); + maze[i][j] &= ~( WALL_TOP >> wall ); + cur_sq_x = i; + cur_sq_y = j; + start_x = i; + start_y = j; + start_dir = wall; + sqnum = 0; + + /* set end square */ + wall = (wall + 2)%4; + switch (wall) { + case 0: + i = get_random(maze_size_x); + j = 0; + break; + case 1: + i = maze_size_x - 1; + j = get_random(maze_size_y); + break; + case 2: + i = get_random(maze_size_x); + j = maze_size_y - 1; + break; + case 3: + i = 0; + j = get_random(maze_size_y); + break; + } + maze[i][j] |= END_SQUARE; + maze[i][j] |= ( DOOR_OUT_TOP >> wall ); + maze[i][j] &= ~( WALL_TOP >> wall ); + end_x = i; + end_y = j; + end_dir = wall; +} + +static int choose_door (); +static long backup (); +static void draw_wall (); +static void draw_solid_square(int, int, int, HDC, HBRUSH); +static void enter_square(int, HDC, HBRUSH); + +static void +create_maze() /* create a maze layout given the intiialized maze */ +{ + register int i, newdoor = 0; + HDC hDC; + + hDC = GetDC(hWnd); + do { + move_list[sqnum].x = cur_sq_x; + move_list[sqnum].y = cur_sq_y; + move_list[sqnum].dir = newdoor; + while ( ( newdoor = choose_door(hDC) ) == -1 ) { /* pick a door */ + if ( backup() == -1 ) { /* no more doors ... backup */ + ReleaseDC(hWnd, hDC); + return; /* done ... return */ + } + } + + /* mark the out door */ + maze[cur_sq_x][cur_sq_y] |= ( DOOR_OUT_TOP >> newdoor ); + + switch (newdoor) { + case 0: cur_sq_y--; + break; + case 1: cur_sq_x++; + break; + case 2: cur_sq_y++; + break; + case 3: cur_sq_x--; + break; + } + sqnum++; + + /* mark the in door */ + maze[cur_sq_x][cur_sq_y] |= ( DOOR_IN_TOP >> ((newdoor+2)%4) ); + + /* if end square set path length and save path */ + if ( maze[cur_sq_x][cur_sq_y] & END_SQUARE ) { + path_length = sqnum; + for ( i=0; ibmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pbmi->bmiHeader.biWidth = 8; + pbmi->bmiHeader.biHeight = 8; + pbmi->bmiHeader.biPlanes = 1; + pbmi->bmiHeader.biBitCount = 1; + pbmi->bmiHeader.biCompression = BI_RGB; + (void) memcpy(pbmi->bmiColors, argbq, sizeof(argbq)); + (void) memcpy(pbmi->bmiColors + 2, grayPattern, sizeof(grayPattern)); +#if 0 + /* FIXME Pattern brushes not yet implemented in ReactOS */ + hBrushDead = CreateDIBPatternBrushPt(pbmi, DIB_RGB_COLORS); +#else + hBrushDead = CreateSolidBrush(RGB(255, 0, 0)); +#endif +// hBrushDead = CreateHatchBrush(HS_DIAGCROSS, RGB(255, 0, 0)); + free(pbmi); + hBrushLiving = CreateSolidBrush(RGB(0, 255, 0)); + + /* plug up the surrounding wall */ + maze[start_x][start_y] |= (WALL_TOP >> start_dir); + maze[end_x][end_y] |= (WALL_TOP >> end_dir); + + /* initialize search path */ + pathi = 0; + path[pathi].x = end_x; + path[pathi].y = end_y; + path[pathi].dir = -1; +} + +static int +solve_maze() /* solve it with graphical feedback */ +{ + int ret; + int action_done; + + do { + action_done = 1; + if ( ++path[pathi].dir >= 4 ) { + pathi--; + draw_solid_square( (int)(path[pathi].x), (int)(path[pathi].y), + (int)(path[pathi].dir), hDC, hBrushDead); + ret = 0; + } + else if ( ! (maze[path[pathi].x][path[pathi].y] & + (WALL_TOP >> path[pathi].dir)) && + ( (pathi == 0) || ( (path[pathi].dir != + (int)(path[pathi-1].dir+2)%4) ) ) ) { + enter_square(pathi, hDC, hBrushLiving); + pathi++; + if ( maze[path[pathi].x][path[pathi].y] & START_SQUARE ) { + DeleteObject(hBrushLiving); + DeleteObject(hBrushDead); + ReleaseDC(hWnd, hDC); + ret = 1; + } else { + ret = 0; + } + } else { + action_done = 0; + } + } while (! action_done); + + return ret; +} + + +static void +enter_square(int n, HDC hDC, HBRUSH hBrush) /* move into a neighboring square */ +{ + draw_solid_square( (int)path[n].x, (int)path[n].y, + (int)path[n].dir, hDC, hBrush); + + path[n+1].dir = -1; + switch (path[n].dir) { + case 0: path[n+1].x = path[n].x; + path[n+1].y = path[n].y - 1; + break; + case 1: path[n+1].x = path[n].x + 1; + path[n+1].y = path[n].y; + break; + case 2: path[n+1].x = path[n].x; + path[n+1].y = path[n].y + 1; + break; + case 3: path[n+1].x = path[n].x - 1; + path[n+1].y = path[n].y; + break; + } +} + +static void +start_timer(HWND hWnd, int iTimeout) +{ + waiting = TRUE; + SetTimer(hWnd, 1, iTimeout, NULL); +} + +/**************************************************************************** + + FUNCTION: WinMain(HINSTANCE, HINSTANCE, LPSTR, int) + + PURPOSE: calls initialization function, processes message loop + + COMMENTS: + + Windows recognizes this function by name as the initial entry point + for the program. This function calls the application initialization + routine, if no other instance of the program is running, and always + calls the instance initialization routine. It then executes a message + retrieval and dispatch loop that is the top-level control structure + for the remainder of execution. The loop is terminated when a WM_QUIT + message is received, at which time this function exits the application + instance by returning the value passed by PostQuitMessage(). + + If this function must abort before entering the message loop, it + returns the conventional value NULL. + +****************************************************************************/ +int APIENTRY WinMain( + HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nCmdShow) +{ + MSG msg; + HDC hDC; + + if (!hPrevInstance) { /* Other instances of app running? */ + if (!InitApplication(hInstance)) { /* Initialize shared things */ + return (FALSE); /* Exits if unable to initialize */ + } + } + + /* Perform initializations that apply to a specific instance */ + + if (!InitInstance(hInstance, nCmdShow)) { + return (FALSE); + } + + waiting = FALSE; + state = 1; + + /* Acquire and dispatch messages until a WM_QUIT message is received. */ + + while (0 != state) { + if (waiting) { + (void) WaitMessage(); + } + while (0 != state && PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + if (WM_QUIT == msg.message) { + state = 0; + } else { + DispatchMessage(&msg); /* Dispatches message to window */ + } + } + switch (state) { + case 1: + initialize_maze(); + state = 2; + break; + case 2: + hDC = GetDC(hWnd); + SendMessage(hWnd, WM_ERASEBKGND, (WPARAM) hDC, (LPARAM) 0); + draw_maze_border(hWnd, hDC); + ReleaseDC(hWnd, hDC); + state = 3; + break; + case 3: + create_maze(); + state = 4; + break; + case 4: + start_timer(hWnd, pre_solve_delay); + state = 5; + break; + case 5: + if (! waiting) { + state = 6; + } + break; + case 6: + begin_solve_maze(); + if (0 != solve_delay) { + start_timer(hWnd, solve_delay); + state = 7; + } else { + state = 8; + } + break; + case 7: + if (! waiting) { + state = 8; + } + break; + case 8: + if (! solve_maze()) { + if (0 != solve_delay) { + start_timer(hWnd, solve_delay); + state = 7; + } + } else { + state = 9; + } + break; + case 9: + start_timer(hWnd, post_solve_delay); + state = 10; + break; + case 10: + if (! waiting) { + state = 11; + } + break; + case 11: + state = 1; + break; + } + } + + return (msg.wParam); /* Returns the value from PostQuitMessage */ +} + + +/**************************************************************************** + + FUNCTION: InitApplication(HINSTANCE) + + PURPOSE: Initializes window data and registers window class + + COMMENTS: + + This function is called at initialization time only if no other + instances of the application are running. This function performs + initialization tasks that can be done once for any number of running + instances. + + In this case, we initialize a window class by filling out a data + structure of type WNDCLASS and calling the Windows RegisterClass() + function. Since all instances of this application use the same window + class, we only need to do this when the first instance is initialized. + + +****************************************************************************/ + +static BOOL InitApplication(HINSTANCE hInstance) +{ + WNDCLASS wc; + + // Fill in window class structure with parameters that describe the + // main window. + + wc.style = CS_HREDRAW | CS_VREDRAW;// Class style(s). + wc.lpfnWndProc = (WNDPROC)WndProc; // Window Procedure + wc.cbClsExtra = 0; // No per-class extra data. + wc.cbWndExtra = 0; // No per-window extra data. + wc.hInstance = hInstance; // Owner of this class + wc.hIcon = LoadIcon (hInstance, szAppName); // Icon name from .RC + wc.hCursor = LoadCursor(NULL, (LPCTSTR) IDC_ARROW);// Cursor + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);// Default color + wc.lpszMenuName = NULL; // No menu + wc.lpszClassName = szAppName; // Name to register as + + // Register the window class and return success/failure code. + return (RegisterClass(&wc)); +} + + +/**************************************************************************** + + FUNCTION: InitInstance(HINSTANCE, int) + + PURPOSE: Saves instance handle and creates main window + + COMMENTS: + + This function is called at initialization time for every instance of + this application. This function performs initialization tasks that + cannot be shared by multiple instances. + + In this case, we save the instance handle in a static variable and + create and display the main program window. + +****************************************************************************/ + +static BOOL InitInstance( + HINSTANCE hInstance, + int nCmdShow) +{ + /* Save the instance handle in static variable, which will be used in + many subsequence calls from this application to Windows. */ + + hInst = hInstance; /* Store instance handle in our global variable */ + + /* Create a main window for this application instance. */ + + hWnd = CreateWindow( + szAppName, /* See RegisterClass() call. */ + szTitle, /* Text for window title bar. */ + WS_OVERLAPPEDWINDOW,/* Window style. */ + 0, 0, CW_USEDEFAULT, CW_USEDEFAULT, /* Use default positioning */ + NULL, /* Overlapped windows have no parent. */ + NULL, /* Use the window class menu. */ + hInstance, /* This instance owns this window. */ + NULL /* We don't use any data in our WM_CREATE */ + ); + + // If window could not be created, return "failure" + if (!hWnd) { + return (FALSE); + } + + // Make the window visible; update its client area; and return "success" + ShowWindow(hWnd, nCmdShow); // Show the window + UpdateWindow(hWnd); // Sends WM_PAINT message + + return (TRUE); // We succeeded... + +} + +static BOOL +OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct) +{ + RECT rc; + int size; + + srand((unsigned) time(NULL)); + +#if 0 + /* FIXME GetPrivateProfileInt not yet implemented in ReactOS */ + size = GetPrivateProfileInt("maze", "gridsize", 0, "maze.ini"); + pre_solve_delay = GetPrivateProfileInt("maze", "predelay", 5000, + "maze.ini"); + post_solve_delay = GetPrivateProfileInt("maze", "postdelay", 5000, + "maze.ini"); + solve_delay = GetPrivateProfileInt("maze", "solvedelay", 10, + "maze.ini"); +#else + size = 10; + pre_solve_delay = 5000; + post_solve_delay = 5000; + solve_delay = 20; +#endif + + if (size < 2) { + size = 7 + (rand() % 30); + } + grid_width = grid_height = size; + bw = (size > 6 ? 3 : (size-1)/2); + + GetClientRect(hWnd, &rc); + set_maze_sizes(rc.right - rc.left, rc.bottom - rc.top); + + return TRUE; +} + +void OnTimer(HWND hwnd, UINT id) +{ + waiting = FALSE; +} + +/**************************************************************************** + + FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM) + + PURPOSE: Processes messages + + MESSAGES: + + WM_DESTROY - destroy window + + COMMENTS: + +****************************************************************************/ + +LRESULT CALLBACK WndProc( + HWND hWnd, // window handle + UINT message, // type of message + WPARAM wParam, // additional information + LPARAM lParam) // additional information +{ + PAINTSTRUCT ps; + + switch (message) { + case WM_CREATE: + OnCreate(hWnd, (LPCREATESTRUCT) lParam); + break; + case WM_PAINT: + BeginPaint(hWnd, &ps); + state = 1; + EndPaint(hWnd, &ps); + case WM_TIMER: + OnTimer(hWnd, wParam); + break; + case WM_DESTROY: // message: window being destroyed + PostQuitMessage(0); + break; + + default: // Passes it on if unproccessed + return (DefWindowProc(hWnd, message, wParam, lParam)); + } + return (0); +} diff --git a/rosapps/demos/maze/maze.rc b/rosapps/demos/maze/maze.rc new file mode 100644 index 00000000000..67cab637c15 --- /dev/null +++ b/rosapps/demos/maze/maze.rc @@ -0,0 +1,60 @@ +//Microsoft App Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include +///////////////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + + +////////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + idsAppName "Screen Saver.Maze" +END + +#ifdef APSTUDIO_INVOKED +////////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include \0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +///////////////////////////////////////////////////////////////////////////////////// +#endif // APSTUDIO_INVOKED + + +#ifndef APSTUDIO_INVOKED +//////////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/rosapps/demos/maze/resource.h b/rosapps/demos/maze/resource.h new file mode 100644 index 00000000000..1efacbb0294 --- /dev/null +++ b/rosapps/demos/maze/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// App Studio generated include file. +// Used by MAZE.RC +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS + +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 101 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif