Thread: Accessing huge 2d array causes "general protection exception"

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Feb 2011
    Posts
    6

    Accessing huge 2d array causes "general protection exception"

    Hello,

    My system:
    Operating System: Windows98 Second Edition
    RAM: 152 Megabtes (160 MB - 8 MB for Video = 152 MB)
    Compiler/Linker: Borland C++ 3.1 for DOS and Windows 3.1

    I am using the DOS version of the compiler.

    Compiler Options:
    Memory Model: Huge
    Instruction Set: 80386

    My program successfully allocates 88,200 bytes of memory for a 2 dimensional array called
    (*map)[36][70] dynamically at runtime using the function farcalloc.

    The problem is when I initialize the elements of the array map, it causes a "general protection exception" which causes the program to terminate and the DOS Prompt to exit.

    The Windows Error Message window displays the following:
    Code:
    MS-DOS Prompt
    
    This program has performed an illegal operation and will be
    terminated.  Quit all programs, and then restart your computer.
    
    If the program consistently encounters problems, click the Start button, then select Help, Troubleshooting,
    and 'If you have trouble running MS-DOS programs'.
    
    --------     -------------
    |  OK  |     | Details>> |
    --------     -------------
    
    The program encountered a general protection exception.
    
    Fault location:         14A6:0418
    
    Interrupts in service:  None
    NOTE: The Fault location is at 6189:0418 when I run the program in Turbo Debugger.

    This occurs when initializing array element (*map)[26][52] in the init_map() function. The last element of the map array should be
    (*map)[35][69]. As you can see the error occurs well before the last element, so I did not go beyond the array's boundaries, that is to say I did not try to access memory beyond the last array element.

    Here is the output from the program before and after allocating the memory for the map array running by itself (without the Turbo Debugger):

    Code:
    nmemb = 2520 bytes (number of array elements for map array).
    sizeof(map_type) = 35 bytes (size of array elements of map array).
    nmemb * sizeof(map_type) = 88200 bytes (size of map array).
    farcoreleft() = 530432 bytes.
    coreleft() = 530432 bytes.
    
    88200 bytes of memory successfully allocated for map array!
    farcoreleft() = 442224 bytes.
    coreleft() = 442224 bytes.

    Here is the output from the program before and after allocating the memory for the map array while running inside the Turbo Debugger:

    Code:
    nmemb = 2520 bytes (number of array elements for map array).
    sizeof(map_type) = 35 bytes (size of array elements of map array).
    nmemb * sizeof(map_type) = 88200 bytes (size of map array).
    farcoreleft() = 216528 bytes.
    coreleft() = 216528 bytes.
    
    88200 bytes of memory successfully allocated for map array!
    farcoreleft() = 128320 bytes.
    coreleft() = 128320 bytes.
    Here is a part the program inside Turbo Debugger at function init_map():

    Code:
    +-[_]-Module: PAC_CH05 File: PAC_CH05.C_276---------------------------1-[][]-+
    ¦     printf(" of memory successfully allocated for map array!\n");            -
    ¦     printf("farcoreleft() = %lu bytes.\n", farcoreleft());                   _
    ¦     printf("coreleft() = %lu bytes.\n", coreleft());                         _
    ¦     getch();                                                                 _
    ¦                                                                              _
    ¦     for (y =  0; y < MAP_MAX_ROWS; y++)                                      _
    ¦     {                                                                        _
    ¦       for (x = 0; x < MAP_MAX_COLS; x++)                                    _
    ¦        {                                                                     _
    ¦           (*map)[y][x].accessible = FALSE;                                   _
    ¦           (*map)[y][x].dot = FALSE;                                          _
    ¦           (*map)[y][x].power_pill = FALSE;                                   _
    ¦           (*map)[y][x].go_left_x = -1;                                       _
    ¦           (*map)[y][x].go_left_y = -1;                                       _
    ¦           (*map)[y][x].go_right_x = -1;                                      ..
    +___________________________________________________________________________-+
    +-----Watches---------------------------------------------------------2--------+
    ¦(*map) struct  [9][70] {{{'\0','\0','\0',-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-¦
    ¦map                          struct  (far *)[9][70] 6F62:0004                 ¦
    ¦x                            unsigned long 70L (0x46)                         ¦
    ¦y                            unsigned long 26L (0x1A)                         ¦
    +------------------------------------------------------------------------------+
    F1-Help F2-Bkpt F3-Mod F4-Here F5-Zoom F6-Next F7-Trace F8-Step F9-Run F10-Menu
    I am not certain what I should be looking for in the Turbo Debugger, perhaps the DS and/or ES Registers (the Data and Extra Segment:Offset Registers).

    I am aware of the 640 Kilobyte limit of RAM Memory within the 1 Megabyte block of RAM when running in Real Mode in DOS. I have recently been playing with PMLITE versions 1.0 and 2.0 by SciTech Software that is suppose allow access to Extended Memory in Protected Mode via DPMI16 and DPMI32 DOS Extenders, but I have only been able to run their example C program in Real Mode.


    node101


    Here is my program:

    Code:
    #include <graphics.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <math.h>
    #include <string.h>
    #include <dos.h>
    #include <alloc.h>
    
    
    /* Macro Definitions */
    #define CLIP_ON 1
    #define TRUE 1
    #define FALSE 0
    #define CIRCLE_MIN_RADIUS 10
    #define MAX_ACTOR_FRAMES 8
    #define MAX_ACTOR_DEGREES 37
    #define UP_DIR 90
    #define DOWN_DIR 270
    #define LEFT_DIR 180
    #define RIGHT_DIR 0
    #define ACTOR_RADIUS_SIZE 10
    #define MAP_MAX_ROWS 36L
    #define MAP_MAX_COLS 70L
    
    
    /* Subroutines */
    void setup_graphics_screen(void);
    void init_map(void);
    void create_pacman(void);
    void draw_ghost_boxes(void);
    void draw_map_grid(void);
    void play_pacman(void);
    void display_polar_graph2(int back_color, int fore_color, int text_color);
    void free_pacman_mem(void);
    void pause(void);
    
    
    
    /* Variables */
    
    char *buff;
    float degrees_to_radians;
    
    typedef unsigned char BOOL;
    
    typedef struct {
       unsigned int width;
       int min_x;
       int max_x;
       int min_y;
       int max_y;
    } border_type;
    
    typedef struct {
       int left;
       int top;
       int right;
       int bottom;
       void far *image;
    } quad_type;
    
    typedef struct {
       int gerror;
       int gdriver;
       int gmode;
       int page;
       int x_max;
       int y_max;
       int x_center;
       int y_center;
       border_type border;
       quad_type q1;
       quad_type q2;
       quad_type q3;
       quad_type q4;
    } screen_type;
    
    screen_type screen;
    
    
    typedef struct {
       float x;
       float y;
    } coord_type;
    
    typedef struct {
       int max_revs;
       coord_type far *p;
    } coord_array_type;
    
    /*
    coord_array_type spiral;
    coord_array_type flower;
    */
    
    typedef struct {
       int duration;
       int frequency;
       int interval;
    } sound_type;
    
    typedef struct {
       int max_sounds;
       sound_type far *p;
    } sound_array_type;
    
    /*
    sound_array_type spin_spiral_sounds;
    */
    
    typedef struct {
       BOOL accessible;
       BOOL dot;
       BOOL power_pill;
       int go_left_x;
       int go_left_y;
       int go_right_x;
       int go_right_y;
       int go_up_x;
       int go_up_y;
       int go_down_x;
       int go_down_y;
       int pacman_left_heading;
       int pacman_right_heading;
       int pacman_up_heading;
       int pacman_down_heading;
       int ghost_left_heading;
       int ghost_right_heading;
       int ghost_up_heading;
       int ghost_down_heading;
    } map_type;
    
    
    map_type huge (*map)[MAP_MAX_ROWS][MAP_MAX_COLS];
    
    
    typedef struct {
       int x;
       int y;
       int old_x;
       int old_y;
       int heading;
       int old_heading;
       int frame;
       int old_frame;
       quad_type images[MAX_ACTOR_DEGREES][MAX_ACTOR_FRAMES];
    } actor_type;
    
    actor_type pacman;
    
    
    
    int main(void)
    {
       setup_graphics_screen();
       init_map();
    
       /* Erase the screen in WHITE */
       setbkcolor(WHITE);
       cleardevice();
       pause();
    
       setaspectratio(1, 1);
       setbkcolor(WHITE);
       cleardevice();
       create_pacman();
       pause();
       display_polar_graph2(WHITE, LIGHTGREEN, BLUE);
    
       draw_ghost_boxes();
       pause();
    
       draw_map_grid();
    
       play_pacman();
       pause();
    
       free_pacman_mem();
    
    
       if (map != NULL) farfree(map);
    
       closegraph();
       return(EXIT_SUCCESS);
    }
    
    
    
    
    
    void setup_graphics_screen(void)
    {
       screen.gdriver = VGA;
       screen.gmode = VGAMED; /* 640 x 350 resolution, 16 colors, 2 pages */
       initgraph(&screen.gdriver, &screen.gmode, "c:\\borlandc\\bgi");
       screen.gerror = graphresult();
       if (screen.gerror != grOk)
       {
         restorecrtmode();
         printf("\nAt function:  setup_graphics_screen().\n");
         printf("BGI error: %s\n", grapherrormsg(screen.gerror));
         printf("screen.gerror == %d\n\n", screen.gerror);
         printf("This error occurred after calling the initgraph() function.\n");
         printf("Press any key to end program. ");
         getch();
         exit(screen.gerror);
       }
       /* Initialize global screen variables */
       screen.page = 0;
       setactivepage(screen.page);
       setvisualpage(screen.page);
       screen.x_max = getmaxx();
       screen.y_max = getmaxy();
       screen.x_center = screen.x_max / 2;
       screen.y_center = screen.y_max / 2;
    
       /* Initialize global screen border variables */
       screen.border.width = 24;
       screen.border.min_x = screen.border.width;
       screen.border.max_x = screen.x_max - screen.border.width;
       screen.border.min_y = screen.border.width;
       screen.border.max_y = screen.y_max - screen.border.width;
    
       degrees_to_radians = M_PI / 180.0;
    }
    
    
    
    
    
    void init_map(void)
    {
       unsigned long x, y;
       unsigned long nmemb;
       unsigned long map_type_size;
       unsigned long map_size;
    
    
       nmemb = MAP_MAX_ROWS * MAP_MAX_COLS;
       map_type_size = sizeof(map_type);
       map_size = nmemb * map_type_size;
       restorecrtmode();
       printf("nmemb = %lu bytes", nmemb);
       printf(" (number of array elements for map array).\n");
       printf("sizeof(map_type) = %lu bytes", map_type_size);
       printf(" (size of array elements of map array).\n");
       printf("nmemb * sizeof(map_type) = %lu bytes", map_size);
       printf(" (size of map array).\n");
       printf("farcoreleft() = %lu bytes.\n", farcoreleft());
       printf("coreleft() = %lu bytes.\n", coreleft());
       getch();
    /*
       map = (map_type huge *) farcalloc(nmemb, map_type_size);
    */
       map = farcalloc(nmemb, map_type_size);
       if (map == NULL)
       {
          restorecrtmode();
          printf("\nAt function:  init_map().\n");
          printf("Not enough memory to allocate for map array.\n");
          printf("farcoreleft() = %lu bytes.\n", farcoreleft());
          printf("Press any key to end program. ");
          getch();
          exit(EXIT_FAILURE);
       }
    
       printf("\n%lu bytes", map_size);
       printf(" of memory successfully allocated for map array!\n");
       printf("farcoreleft() = %lu bytes.\n", farcoreleft());
       printf("coreleft() = %lu bytes.\n", coreleft());
       getch();
    
       for (y =  0; y < MAP_MAX_ROWS; y++)
       {
          for (x = 0; x < MAP_MAX_COLS; x++)
          {
    	 (*map)[y][x].accessible = FALSE;
    	 (*map)[y][x].dot = FALSE;
    	 (*map)[y][x].power_pill = FALSE;
    	 (*map)[y][x].go_left_x = -1;
    	 (*map)[y][x].go_left_y = -1;
    	 (*map)[y][x].go_right_x = -1;
    	 (*map)[y][x].go_right_y = -1;
    	 (*map)[y][x].go_up_x = -1;
    	 (*map)[y][x].go_up_y = -1;
    	 (*map)[y][x].go_down_x = -1;
    	 (*map)[y][x].go_down_y = -1;
    	 (*map)[y][x].pacman_left_heading = -1;
    	 (*map)[y][x].pacman_right_heading = -1;
    	 (*map)[y][x].pacman_up_heading = -1;
    	 (*map)[y][x].pacman_down_heading = -1;
    	 (*map)[y][x].ghost_left_heading = -1;
    	 (*map)[y][x].ghost_right_heading = -1;
    	 (*map)[y][x].ghost_up_heading = -1;
    	 (*map)[y][x].ghost_down_heading = -1;
    	 printf("(*map)[%lu][%lu].accessible = %d\n", y, x,
    		(*map)[y][x].accessible);
    	 printf("(*map)[%lu][%lu].dot = %d\n", y, x,
    		(*map)[y][x].dot);
    	 printf("(*map)[%lu][%lu].power_pill = %d\n", y, x,
    		(*map)[y][x].power_pill);
    	 printf("(*map)[%lu][%lu].go_left_x = %d\n", y, x,
    		(*map)[y][x].go_left_x);
    	 printf("(*map)[%lu][%lu].go_left_y = %d\n", y, x,
    		(*map)[y][x].go_left_y);
    	 printf("(*map)[%lu][%lu].go_right_x = %d\n", y, x,
    		(*map)[y][x].go_right_x);
    	 printf("(*map)[%lu][%lu].go_right_y = %d\n", y, x,
    		(*map)[y][x].go_right_y);
    	 printf("(*map)[%lu][%lu].go_up_x = %d\n", y, x,
    		(*map)[y][x].go_up_x);
    	 printf("(*map)[%lu][%lu].go_up_y = %d\n", y, x,
    		(*map)[y][x].go_up_y);
    	 printf("(*map)[%lu][%lu].go_down_x = %d\n", y, x,
    		(*map)[y][x].go_down_x);
    	 printf("(*map)[%lu][%lu].go_down_y = %d\n", y, x,
    		(*map)[y][x].go_down_y);
    	 printf("(*map)[%lu][%lu].pacman_left_heading = %d\n", y, x,
    		(*map)[y][x].pacman_left_heading);
    	 printf("(*map)[%lu][%lu].pacman_right_heading = %d\n", y, x,
    		(*map)[y][x].pacman_right_heading);
    	 printf("(*map)[%lu][%lu].pacman_up_heading = %d\n", y, x,
    		(*map)[y][x].pacman_up_heading);
    	 printf("(*map)[%lu][%lu].pacman_down_heading = %d\n", y, x,
    		(*map)[y][x].pacman_down_heading);
    	 printf("(*map)[%lu][%lu].ghost_left_heading = %d\n", y, x,
    		(*map)[y][x].ghost_left_heading);
    	 printf("(*map)[%lu][%lu].ghost_right_heading = %d\n", y, x,
    		(*map)[y][x].ghost_right_heading);
    	 printf("(*map)[%lu][%lu].ghost_up_heading = %d\n", y, x,
    		(*map)[y][x].ghost_up_heading);
    	 printf("(*map)[%lu][%lu].ghost_down_heading = %d\n", y, x,
    		(*map)[y][x].ghost_down_heading);
    	 if (y >= 26L) getch();
          } /* end for x */
       } /* end for y */
       getch();
       setgraphmode(getgraphmode());
    }
    
    
    
    
    
    void draw_map_grid(void)
    {
    
       int left, top, right, bottom;
    
       /* Draw 2 dimensional grid of rectangles in LIGHTRED */
       setcolor(LIGHTRED);
       setlinestyle(SOLID_LINE, 1, NORM_WIDTH);
       for (top = (screen.border.min_y - 3); top < screen.border.max_y;
       top = top + ((ACTOR_RADIUS_SIZE * 2) - 3))
       {
          bottom = top + ((ACTOR_RADIUS_SIZE * 2) - 3);
          for (left = screen.border.min_x - 2; left < screen.border.max_x;
    	   left = left + ((ACTOR_RADIUS_SIZE * 2) - 3))
          {
    	 right = left + ((ACTOR_RADIUS_SIZE * 2) - 3);
    	 rectangle(left, top, right, bottom);
          } /* end for left */
       } /* end for top */
       getch();
    
       /* Now draw the same 2 dimesional grid of rectangles in CYAN dashed */
       /* lines starting at the starting x coordinate plus the             */
       /* ACTOR_RADIUS_SIZE                                                */
       setcolor(CYAN);
       setlinestyle(DASHED_LINE, 1, NORM_WIDTH);
       for (top = (screen.border.min_y - 3); top < screen.border.max_y;
       top = top + ((ACTOR_RADIUS_SIZE * 2) -3))
       {
          bottom = top + ((ACTOR_RADIUS_SIZE * 2) - 3);
          for (left = (screen.border.min_x - 2) + ACTOR_RADIUS_SIZE;
    	   left < screen.border.max_x;
    	   left = left + ((ACTOR_RADIUS_SIZE * 2) - 3))
          {
    	 right = left + ((ACTOR_RADIUS_SIZE * 2) - 3);
    	 rectangle(left, top, right, bottom);
          } /* end for left */
       } /* end for top */
       getch();
    
       /* Draw a row of rectangles in MAGENTA dotted lines at the center */
       /* row of the screen to confirm that the grid just drawn lines up */
       /* to where it should be                                          */
       setcolor(MAGENTA);
       setlinestyle(DOTTED_LINE, 1, NORM_WIDTH);
       top = screen.y_center - ((ACTOR_RADIUS_SIZE * 2) - 3);
       bottom = top + ((ACTOR_RADIUS_SIZE * 2) - 3);
       for (left = (screen.border.min_x - 2) + ACTOR_RADIUS_SIZE;
    	left < screen.border.max_x;
    	left = left + ((ACTOR_RADIUS_SIZE * 2) - 3))
       {
          right = left + ((ACTOR_RADIUS_SIZE * 2) - 3);
          rectangle(left, top, right, bottom);
       } /* end for left */
       setlinestyle(SOLID_LINE, 1, NORM_WIDTH);
       getch();
    
       /* Draw the pacman image at the left column center row of the screen */
       /* within the 2 dimensional grid                                     */
       left = screen.border.min_x - 2;
       top = screen.y_center - ((ACTOR_RADIUS_SIZE * 2) - 3);
       pacman.frame = 5;
       pacman.x = left;
       pacman.y = top;
       putimage(pacman.x, pacman.y,
    	    pacman.images[RIGHT_DIR / 10][pacman.frame].image, XOR_PUT);
       getch();
    }
    
    
    
    
    
    void create_pacman(void)
    {
       int row, col, new_col;
       int col_cnt;
       int frame;
       int old_start_angle, old_end_angle;
       int start_angle, end_angle;
       int degree;
    
    
       setbkcolor(WHITE);
       cleardevice();
    
       /* Create a grid by drawing horizontal and vetical lines in red */
       setcolor(LIGHTRED);
       for (row = 0; row < 349; row = row + 20)
       {
          line(0, row, 639, row);
       }
       for (col = 0; col < 639; col = col + 20)
       {
          line (col, 0, col, 349);
       }
       line(0, 349, 639, 349); /* Draw horizontal bottom line */
       line(639, 0, 639, 349); /* Draw vertical line on the right side */
    
       /* Draw Pacman rotated from 0 degrees to 360 degrees at 10 degree      */
       /* intervals.                                                          */
       /* 8 frames, each frame with his mouth opened 10 degrees more than the */
       /* previous frame, starting at 0 degrees opened to 50 degrees opened,  */
       /* then his mouth closing 10 degrees more than the previous frame.     */
    
       /* First set of 17 rows rotating from 0 degrees to 160 degrees */
       setcolor(YELLOW);
       setfillstyle(SOLID_FILL, YELLOW);
    
       old_start_angle = 20;
       old_end_angle = 340;
       start_angle = old_start_angle;
       end_angle = old_end_angle;
    
       for (row = 10; row < 349; row = row + 20)
       {
          /* Draw Frame 0, a solid circle */
          setcolor(BLUE);
          circle(10, row, 8);
          floodfill(10, row, BLUE);
          setcolor(YELLOW);
          circle(10, row, 8);
    
          /* Draw the remaining 7 frames, Frames 1 through 7.           */
          /* Frames 1, 2, and 3 are duplicated for Frames 7, 6, and 5   */
          /* respectively.  Frame 4 is not duplicated, it is unique.    */
          col = 30;
          new_col = 150;
          for (frame = 1; frame < 5; frame++)
          {
    	 if (start_angle > end_angle)
    	 {
    	    pieslice(col, row, start_angle, 360, 8);
    	    pieslice(col, row, 0, end_angle, 8);
    	    if (frame < 4)
    	    {
    	       pieslice(new_col, row, start_angle, 360, 8);
    	       pieslice(new_col, row, 0, end_angle, 8);
    	    }
    	 }
    	 else
    	 {
    	    pieslice(col, row, start_angle, end_angle, 8);
    	    if (frame < 4)
    	    {
    	       pieslice(new_col, row, start_angle, end_angle, 8);
    	    }
    	 }
    	 start_angle += 10;
    	 end_angle -= 10;
    	 if (end_angle < 0) end_angle = 360 + end_angle;
    	 col += 20;
    	 new_col -= 20;
          } /* end for frame */
    
          old_start_angle += 10;
          old_end_angle += 10;
          if (old_end_angle > 360) old_end_angle = 0;
          start_angle = old_start_angle;
          end_angle = old_end_angle;
       } /* end for row */
    
       /* Second set of 17 rows rotating from 170 degrees to 330 degrees */
       setcolor(YELLOW);
       setfillstyle(SOLID_FILL, YELLOW);
    
       for (row = 10; row < 349; row = row + 20)
       {
          /* Draw Frame 0, a solid circle */
          setcolor(BLUE);
          circle(190, row, 8);
          floodfill(190, row, BLUE);
          setcolor(YELLOW);
          circle(190, row, 8);
    
          /* Draw the remaining 7 frames, Frames 1 through 7.           */
          /* Frames 1, 2, and 3 are duplicated for Frames 7, 6, and 5   */
          /* respectively.  Frame 4 is not duplicated, it is unique.    */
          col = 210;
          new_col = 330;
          for (frame = 1; frame < 5; frame++)
          {
    	 if (start_angle > end_angle)
    	 {
    	    pieslice(col, row, start_angle, 360, 8);
    	    pieslice(col, row, 0, end_angle, 8);
    	    if (frame < 4)
    	    {
    	       pieslice(new_col, row, start_angle, 360, 8);
    	       pieslice(new_col, row, 0, end_angle, 8);
    	    }
    	 }
    	 else
    	 {
    	    pieslice(col, row, start_angle, end_angle, 8);
    	    if (frame < 4)
    	    {
    	       pieslice(new_col, row, start_angle, end_angle, 8);
    	    }
    	 }
    	 start_angle += 10;
    	 end_angle -= 10;
    	 if (start_angle >= 360) start_angle -= 360;
    	 col += 20;
    	 new_col -= 20;
          } /* end for frame */
    
          old_start_angle += 10;
          old_end_angle += 10;
          if (old_start_angle > 360) old_start_angle -= 360;
          if (old_end_angle > 360) old_end_angle -= 360;
          start_angle = old_start_angle;
          end_angle = old_end_angle;
       } /* end for row */
    
       /* Third set of 17 rows rotating from 340 degrees to 360 degrees */
       setcolor(YELLOW);
       setfillstyle(SOLID_FILL, YELLOW);
    
       for (row = 10; row < 70; row = row + 20)
       {
          /* Draw Frame 0, a solid circle */
          setcolor(BLUE);
          circle(370, row, 8);
          floodfill(370, row, BLUE);
          setcolor(YELLOW);
          circle(370, row, 8);
    
          /* Draw the remaining 7 frames, Frames 1 through 7.           */
          /* Frames 1, 2, and 3 are duplicated for Frames 7, 6, and 5   */
          /* respectively.  Frame 4 is not duplicated, it is unique.    */
          col = 390;
          new_col = 510;
          if (start_angle >= 360) start_angle -= 360;
          for (frame = 1; frame < 5; frame++)
          {
    	 if (start_angle > end_angle)
    	 {
    	    pieslice(col, row, start_angle, 360, 8);
    	    pieslice(col, row, 0, end_angle, 8);
    	    if (frame < 4)
    	    {
    	       pieslice(new_col, row, start_angle, 360, 8);
    	       pieslice(new_col, row, 0, end_angle, 8);
    	    }
    	 }
    	 else
    	 {
    	    pieslice(col, row, start_angle, end_angle, 8);
    	    if (frame < 4)
    	    {
    	       pieslice(new_col, row, start_angle, end_angle, 8);
    	    }
    	 }
    	 start_angle += 10;
    	 end_angle -= 10;
    	 if (start_angle >= 360) start_angle -= 360;
    	 col += 20;
    	 new_col -= 20;
          } /* end for frame */
    
          old_start_angle += 10;
          old_end_angle += 10;
          if (old_start_angle > 360) old_start_angle -= 360;
          if (old_end_angle > 360) old_end_angle -= 360;
          start_angle = old_start_angle;
          end_angle = old_end_angle;
       } /* end for row */
    
       /* Get Pacman images from the video screen & store in an array of images */
       row = 1;
       col = 1;
       col_cnt = 1;
       new_col = 1;
       for (degree = 0; degree < MAX_ACTOR_DEGREES; degree++)
       {
          for (frame = 0; frame < MAX_ACTOR_FRAMES; frame++)
          {
    	 pacman.images[degree][frame].left = col;
    	 pacman.images[degree][frame].top = row;
    	 pacman.images[degree][frame].right = col + 18;
    	 pacman.images[degree][frame].bottom = row + 18;
    	 pacman.images[degree][frame].image =
    	    farmalloc(imagesize(pacman.images[degree][frame].left,
    				pacman.images[degree][frame].top,
    				pacman.images[degree][frame].right,
    				pacman.images[degree][frame].bottom));
    	 if (pacman.images[degree][frame].image == NULL)
    	 {
    	    restorecrtmode();
    	    printf("\nAt function:  create_pacman().\n");
    	    printf("\Not enough memory to allocate for ");
    	    printf("pacman.images[%d][%d].image.\n", degree, frame);
    	    printf("Press any key to end program. ");
    	    getch();
    	    exit(EXIT_FAILURE);
    	 }
    
    	 /* Draw a blue frame around the pacman image */
    /*
    	 setcolor(BLUE);
    	 rectangle(pacman.images[degree][frame].left,
    		   pacman.images[degree][frame].top,
    		   pacman.images[degree][frame].right,
    		   pacman.images[degree][frame].bottom);
    */
    
    	 getimage(pacman.images[degree][frame].left,
    		  pacman.images[degree][frame].top,
    		  pacman.images[degree][frame].right,
    		  pacman.images[degree][frame].bottom,
    		  pacman.images[degree][frame].image);
    	 col += 20;
          } /* end for frame */
    
          row += 20;
          if (row > 339)
          {
    	 row = 1;
    	 col_cnt++;
    	 if (col_cnt == 2)
    	 {
    	    col = 181;
    	    new_col = 181;
    	 }
    	 else if (col_cnt == 3)
    	 {
    	    col = 361;
    	    new_col = 361;
    	 }
          }
          col = new_col;
       } /* end for degree */
       getch();
    
       /* Clear the screen and display the array of pacman images */
       cleardevice();
       for (degree = 0; degree < MAX_ACTOR_DEGREES; degree++)
       {
          for (frame = 0; frame < MAX_ACTOR_FRAMES; frame++)
          {
    	 putimage(pacman.images[degree][frame].left,
    		  pacman.images[degree][frame].top,
    		  pacman.images[degree][frame].image, COPY_PUT);
          } /* end for frame */
       } /* end for degree */
       getch();
    }
    
    
    
    
    
    void draw_ghost_boxes(void)
    {
       /* Draw box on the left side of the screen half way down the screen */
       setcolor(BLUE);
       rectangle(2, screen.y_center - (ACTOR_RADIUS_SIZE * 4),
    	     (ACTOR_RADIUS_SIZE * 2) + 4,
    	     screen.y_center + (ACTOR_RADIUS_SIZE * 4));
    
       /* Draw a yellow line to represent the doorway */
       setcolor(YELLOW);
       line((ACTOR_RADIUS_SIZE * 2) + 4,
    	screen.y_center - (ACTOR_RADIUS_SIZE * 2),
    	(ACTOR_RADIUS_SIZE * 2) + 4,
    	screen.y_center + (ACTOR_RADIUS_SIZE * 2));
    
       /* Draw Pacman inside left side box */
       pacman.frame = 5;
       pacman.x = 5;
       pacman.y = (screen.y_center - ACTOR_RADIUS_SIZE) + 3;
       putimage(pacman.x, pacman.y,
    	    pacman.images[RIGHT_DIR / 10][pacman.frame].image, XOR_PUT);
    
       /* Draw box on the right side of the screen half way down the screen */
       setcolor(BLUE);
       rectangle((screen.x_max - (ACTOR_RADIUS_SIZE * 2)) - 4,
    	     screen.y_center - (ACTOR_RADIUS_SIZE * 4),
    	     screen.x_max - 2,
    	     screen.y_center + (ACTOR_RADIUS_SIZE * 4));
    
       /* Draw a yellow line to represent the doorway */
       setcolor(YELLOW);
       line((screen.x_max - (ACTOR_RADIUS_SIZE * 2)) - 4,
    	screen.y_center - (ACTOR_RADIUS_SIZE * 2),
    	(screen.x_max - (ACTOR_RADIUS_SIZE * 2)) - 4,
    	screen.y_center + (ACTOR_RADIUS_SIZE * 2));
    
       /* Draw Pacman inside right side box */
       pacman.frame = 5;
       pacman.x = (screen.x_max - (ACTOR_RADIUS_SIZE * 2) - 3);
       pacman.y = (screen.y_center - ACTOR_RADIUS_SIZE) + 3;
    
       putimage(pacman.x, pacman.y,
    	    pacman.images[LEFT_DIR / 10][pacman.frame].image, XOR_PUT);
    
       /* Draw box on the top of the screen half way across the screen */
       setcolor(BLUE);
       rectangle(screen.x_center - (ACTOR_RADIUS_SIZE * 4), 3,
    	     screen.x_center + (ACTOR_RADIUS_SIZE * 4),
    	     (ACTOR_RADIUS_SIZE * 2) + 4);
    
       /* Draw a yellow line to represent the doorway */
       setcolor(YELLOW);
       line(screen.x_center - (ACTOR_RADIUS_SIZE * 2),
    	(ACTOR_RADIUS_SIZE * 2) + 4,
    	screen.x_center + (ACTOR_RADIUS_SIZE * 2),
    	(ACTOR_RADIUS_SIZE * 2) + 4);
    
       /* Draw Pacman inside top box */
       pacman.frame = 5;
       pacman.x = (screen.x_center - ACTOR_RADIUS_SIZE) + 2;
       pacman.y = 5;
       putimage(pacman.x, pacman.y,
    	    pacman.images[DOWN_DIR / 10][pacman.frame].image, XOR_PUT);
    
       /* Draw box on the bottom of the screen half way across the screen */
       setcolor(BLUE);
       rectangle(screen.x_center - (ACTOR_RADIUS_SIZE * 4),
    	     (screen.y_max - (ACTOR_RADIUS_SIZE * 2)) - 4,
    	     screen.x_center + (ACTOR_RADIUS_SIZE * 4), screen.y_max - 3);
    
       /* Draw a yellow line to represent the doorway */
       setcolor(YELLOW);
       line(screen.x_center - (ACTOR_RADIUS_SIZE * 2),
    	(screen.y_max - (ACTOR_RADIUS_SIZE * 2)) - 4,
    	screen.x_center + (ACTOR_RADIUS_SIZE * 2),
    	(screen.y_max - (ACTOR_RADIUS_SIZE * 2)) - 4);
    
       /* Draw Pacman inside bottom box */
       pacman.frame = 5;
       pacman.x = (screen.x_center - ACTOR_RADIUS_SIZE) + 2;
       pacman.y = screen.y_max - ((ACTOR_RADIUS_SIZE * 2) + 3);
       putimage(pacman.x, pacman.y,
    	    pacman.images[UP_DIR / 10][pacman.frame].image, XOR_PUT);
    
    /* Test that the box on the left matches the box on the right */
    /*
       setcolor(LIGHTRED);
       line(2, screen.y_center - (ACTOR_RADIUS_SIZE * 4),
    	screen.x_max - 2, screen.y_center - (ACTOR_RADIUS_SIZE * 4));
       line(2, screen.y_center + (ACTOR_RADIUS_SIZE * 4),
    	screen.x_max - 2, screen.y_center + (ACTOR_RADIUS_SIZE * 4));
    */
    /* Test that the box on the top matches the box on the bottom */
    /*
       line(screen.x_center - (ACTOR_RADIUS_SIZE * 4), 3,
    	screen.x_center - (ACTOR_RADIUS_SIZE * 4),
    	screen.y_max - 3);
       line(screen.x_center + (ACTOR_RADIUS_SIZE * 4), 3,
    	screen.x_center + (ACTOR_RADIUS_SIZE * 4), screen.y_max - 3);
    */
    }
    
    
    
    
    
    void play_pacman()
    {
       /* Draw Pacman at the center of the screen using Exclusive OR */
       pacman.frame = 5;
       pacman.x = screen.x_center - ACTOR_RADIUS_SIZE;
       pacman.y = screen.y_center - ((ACTOR_RADIUS_SIZE * 2) - 3);
       putimage(pacman.x, pacman.y,
    	    pacman.images[LEFT_DIR / 10][pacman.frame].image, XOR_PUT);
       getch();
    
       /* Redraw Pacman at the center of the screen using Exclusive OR, which */
       /* will erase him from the screen but restore the background as it was */
       putimage(pacman.x, pacman.y,
    	    pacman.images[LEFT_DIR / 10][pacman.frame].image, XOR_PUT);
       getch();
    }
    
    
    
    
    
    void display_polar_graph2(int back_color, int fore_color, int text_color)
    {
       int old_x_center, old_y_center;
       int angle;
       int radius;
       float x, y;
    
    
       /* Erase the screen in background color */
       setbkcolor(back_color);
       cleardevice();
    
       /* Draw screen border */
    
       setcolor(text_color); /* Delete this line later. */
    
       setcolor(fore_color);
       rectangle(screen.border.min_x, screen.border.min_y, screen.border.max_x,
    	     screen.border.max_y);
    
       /* Redefine the screen boundaries to "screen.border.width" pixels from */
       /* the screen edge to allow text at the top and bottom of the screen   */
       /* and to allow degree labels at the top, bottom, left side and right  */
       /* side of the screen.                                                 */
       old_x_center = screen.x_center;
       old_y_center = screen.y_center;
       screen.x_center = ((screen.border.max_x - screen.border.min_x) + 1) / 2;
       screen.y_center = ((screen.border.max_y - screen.border.min_y) + 1) / 2;
       setviewport(screen.border.min_x, screen.border.min_y, screen.border.max_x,
    	       screen.border.max_y, CLIP_ON);
    
       /* Draw concentric circles within the new screen boundaries */
       setcolor(fore_color);
       for (radius = CIRCLE_MIN_RADIUS + 45; radius < screen.x_center; radius += 45)
          circle(screen.x_center, screen.y_center, radius);
    /* end for */
    
       /* Draw lines from the center of the screen to the edge of the new */
       /* screen boundaries from 0 degrees to 360 degrees                 */
       radius = sqrt(((double) screen.x_center * (double) screen.x_center)
    		   + ((double) screen.y_center * (double) screen.y_center));
       for (angle = 360; angle > 0; angle -= 90)
       {
          /* Move to a point on the inner most circle */
          x = (CIRCLE_MIN_RADIUS * cos(angle * degrees_to_radians)) + 0.5;
          y = (CIRCLE_MIN_RADIUS * sin(angle * degrees_to_radians)) + 0.5;
          x += screen.x_center;
          y += screen.y_center;
          moveto(x, y);
    
          /* Move from the inner most circle to the edge of the new screen */
          /* boundaries                                                    */
          x = (radius * cos(angle * degrees_to_radians)) + 0.5;
          y = (radius * sin(angle * degrees_to_radians)) + 0.5;
          x += screen.x_center;
          y += screen.y_center;
          lineto(x, y);
       } /* end for */
    
       for (angle = 45; angle < 360; angle += 90)
       {
          /* Move to a point on the second inner most circle */
          x = ((CIRCLE_MIN_RADIUS + 45) * cos(angle * degrees_to_radians)) + 0.5;
          y = ((CIRCLE_MIN_RADIUS + 45) * sin(angle * degrees_to_radians)) + 0.5;
          x += screen.x_center;
          y += screen.y_center;
          moveto(x, y);
    
          /* Move from the inner most circle to the edge of the new screen */
          /* boundaries                                                    */
          x = (radius * cos(angle * degrees_to_radians)) + 0.5;
          y = (radius * sin(angle * degrees_to_radians)) + 0.5;
          x += screen.x_center;
          y += screen.y_center;
          lineto(x, y);
       } /* end for */
    
       /* Draw cross-hair at the center of the screen */
       moveto(screen.x_center, screen.y_center - 10);
       lineto(screen.x_center, screen.y_center + 10);
       moveto(screen.x_center - 10, screen.y_center);
       lineto(screen.x_center + 10, screen.y_center);
    
       /* Reset the screen back to normal dimensions */
       setviewport(0, 0, screen.x_max, screen.y_max, CLIP_ON);
       screen.x_center = old_x_center;
       screen.y_center = old_y_center;
    }
    
    
    
    
    void free_pacman_mem(void)
    {
       int frame;
       int degree;
    
    
       /* Free the array of images of Pacman */
       for (degree = 0; degree < MAX_ACTOR_DEGREES; degree++)
       {
          for (frame = 0; frame < MAX_ACTOR_FRAMES; frame++)
          {
    	 if (pacman.images[degree][frame].image != NULL)
    	    farfree(pacman.images[degree][frame].image);
          } /* end for frame */
       } /* end for degree */
    }
    
    
    
    
    
    void pause(void)
    {
       int old_color;
    
       old_color = getcolor();
       setcolor(BLUE);
       settextstyle(SMALL_FONT, HORIZ_DIR, 0);
       outtextxy(8, getmaxy() - 12, "Press any key to continue.");
       getch();
       setcolor(old_color);
    }
    Last edited by node101; 02-25-2011 at 12:27 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with mallocing a 2d array please?
    By Gatt9 in forum C Programming
    Replies: 5
    Last Post: 10-10-2008, 03:45 AM
  2. Replies: 2
    Last Post: 07-11-2008, 07:39 AM
  3. question about multidimensional arrays
    By richdb in forum C Programming
    Replies: 22
    Last Post: 02-26-2006, 09:51 AM
  4. Copying from one 2d array to another....with a twist
    By Zildjian in forum C++ Programming
    Replies: 2
    Last Post: 10-24-2004, 07:39 PM
  5. Struct *** initialization
    By Saravanan in forum C Programming
    Replies: 20
    Last Post: 10-09-2003, 12:04 PM