1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Winapi console and threading

Discussion in 'C' started by hobbyist, May 29, 2012.

  1. hobbyist

    hobbyist New Member

    Joined:
    Jan 7, 2012
    Messages:
    141
    Likes Received:
    0
    Trophy Points:
    0
    I've been toying around with game ideas while trying to figure out threading; I've got a simple program and was hoping to get an idea on any problems that occur before I move on. Right now, it just moves the "enemies" about.

    Code:
    // compiled using Code::Blocks 10.05
    // modified threading example
    // http://www.cs.rpi.edu/academics/courses/netprog/WindowsThreads.html
    // Win32 console app
    
    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define MAX_E 15 // number of "enemies"
    #define MAX_Y 20 // max rows
    #define MAX_X 79 // max cols
    
    HANDLE hcon;   // global handle to console window
    int sentinel;  // global loop control variable
    
    typedef struct {
    
        COORD old_c;
        COORD new_c;
        char shown;
        char blank;
    
        // structure for each "character"
    } test;
    
    typedef struct {
    
        test *enemies_list;
    
        // the thread function allows only one argument.  To pass a boat load
        // of data, use a struct as a "container" of other data
    } enemy_array;
    
    DWORD WINAPI ThreadRoutine(LPVOID lpArg) {
    
        enemy_array t = *(enemy_array *)lpArg;
    
        // lpArg needs to be cast to the appropriate data type
        // in this case, it's (enemy_array *).  To get to the data
        // we want, dereference *(cast_type *)lpArg
    
        for(; sentinel != 10; ) {
    
            // to exit out of the threading function,
            // set the sentinel value from within the main
            //     !! not sure if this is correct !!
    
            int i = 0;
            time_t t1 = time(0), t2;
    
            do{ t2 = time(0); } while(t2 < t1 + 1);
    
            // crude timer function; wait for ~1 second
    
            while(i < MAX_E) {
    
                SetConsoleCursorPosition(hcon, t.enemies_list[i].old_c);
                putchar(t.enemies_list[i].blank);
    
                // update each of the "enemies" by placing a space where it
                // was; there is NO collision detection at this time
    
                switch(rand() % 4) {
                    case 0 : if(t.enemies_list[i].new_c.Y - 1 > 0) // move up
                                --t.enemies_list[i].new_c.Y;
                             else if(t.enemies_list[i].new_c.Y == 0)
                                t.enemies_list[i].new_c.Y = MAX_Y;
                             break;
                    case 1 : if(t.enemies_list[i].new_c.X - 1 > 0) // move left
                                --t.enemies_list[i].new_c.X;
                             else if(t.enemies_list[i].new_c.X == 0)
                                t.enemies_list[i].new_c.X = MAX_X;
                             break;
                    case 2 : if(t.enemies_list[i].new_c.X + 1 < MAX_X) // move right
                                ++t.enemies_list[i].new_c.X;
                             else if(t.enemies_list[i].new_c.X == MAX_X)
                                t.enemies_list[i].new_c.X = 0;
                             break;
                    case 3 : if(t.enemies_list[i].new_c.Y + 1 < MAX_Y) // move down
                                ++t.enemies_list[i].new_c.Y;
                             else if(t.enemies_list[i].new_c.Y == MAX_Y)
                                t.enemies_list[i].new_c.Y = 0;
                             break;
                 }
    
                 SetConsoleCursorPosition(hcon, t.enemies_list[i].new_c);
                 putchar(t.enemies_list[i].shown);
    
                 t.enemies_list[i].old_c.X = t.enemies_list[i].new_c.X;
                 t.enemies_list[i].old_c.Y = t.enemies_list[i].new_c.Y;
    
                 // update the new coordinates of each "enemy"
    
                 ++i;
            }
        }
    
    	return NULL;
    }
    
    int main() {
    
    	int i;
    	HANDLE hHandles; // handle to thread
    	DWORD ThreadId;
    	CONSOLE_CURSOR_INFO cci; // structure for cursor
    
    	test player = { { 40, 10 }, { 40, 10 }, 'X', ' ' };
    	enemy_array ea;
    
    	ea.enemies_list = malloc(sizeof(test) * MAX_E); // allocate some enemies
    
    	if(ea.enemies_list) {
    	    int i=0;
    
    	    while(i < MAX_E) {
    	        ea.enemies_list[i].blank = ' ';
    	        ea.enemies_list[i].shown = "!@#$%^&*()_+"[rand() % 12];
    	        ea.enemies_list[i].new_c.X = ea.enemies_list[i].old_c.X = rand() % 80;
    	        ea.enemies_list[i].new_c.Y = ea.enemies_list[i].old_c.Y = rand() % 20;
    
    	        // set their coordinates and assign them a "random" display character
    	        ++i;
    	    }
    	} else {
    	    fprintf(stderr, "could not allocate space for enemies");
    	    return 1;
    	}
    
    	sentinel = 0; // controls the threading function runtime
    
        cci.dwSize = 1;
        cci.bVisible = 0; // hide the cursor
    
    	hcon = GetStdHandle(STD_OUTPUT_HANDLE);  // get handle to console window
    	SetConsoleCursorInfo(hcon, &cci);        // prepare display
    	hHandles = CreateThread(NULL, 0, ThreadRoutine, &ea, 0, &ThreadId);
    	// try to create the thread
    
    	if (hHandles == NULL) {
    	     fprintf(stderr,"Could not create Thread\n");
    		 exit(0);
    	}
    
    	SetConsoleCursorPosition(hcon, player.new_c);
    	putchar(player.shown);
    	// set the initial placement of the player's character
    
    	for(; getchar() != '\n';) {
    
    	    // main player loop
    
    	}
    
    	sentinel = 10;
    
    	// clean up and prepare for program termination
    
    	WaitForSingleObject(hHandles, INFINITE);
    
    	cci.dwSize = 1;
    	cci.bVisible = 1;
    	SetConsoleCursorInfo(hcon, &cci);
    	// restore cursor
    
    	free(ea.enemies_list);
    
    	return 0;
    }
    
    If anyone sees anything troublesome, please point it out.
     

Share This Page