home *** CD-ROM | disk | FTP | other *** search
- // GPDUMB1.CPP - Game Engine Part I
-
- // INCLUDES ///////////////////////////////////////////////
-
- #define WIN32_LEAN_AND_MEAN
-
- #include <windows.h> // include important windows stuff
- #include <windowsx.h>
- #include <mmsystem.h>
- #include <iostream.h> // include important C/C++ stuff
- #include <conio.h>
- #include <stdlib.h>
- #include <malloc.h>
- #include <memory.h>
- #include <string.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include <math.h>
- #include <io.h>
- #include <fcntl.h>
-
- #include <ddraw.h> // directX includes
- #include "gpdumb1.h"
-
- // DEFINES ////////////////////////////////////////////////
-
- // TYPES //////////////////////////////////////////////////
-
- // PROTOTYPES /////////////////////////////////////////////
-
- // EXTERNALS /////////////////////////////////////////////
-
- extern HWND main_window_handle; // save the window handle
- extern HINSTANCE main_instance; // save the instance
-
- // GLOBALS ////////////////////////////////////////////////
-
- FILE *fp_error = NULL; // general error file
- LPDIRECTDRAW7 lpdd = NULL; // dd object
- LPDIRECTDRAWSURFACE7 lpddsprimary = NULL; // dd primary surface
- LPDIRECTDRAWSURFACE7 lpddsback = NULL; // dd back surface
- LPDIRECTDRAWPALETTE lpddpal = NULL; // a pointer to the created dd palette
- LPDIRECTDRAWCLIPPER lpddclipper = NULL; // dd clipper
- PALETTEENTRY palette[256]; // color palette
- PALETTEENTRY save_palette[256]; // used to save palettes
- DDSURFACEDESC2 ddsd; // a direct draw surface description struct
- DDBLTFX ddbltfx; // used to fill
- DDSCAPS2 ddscaps; // a direct draw surface capabilities struct
- HRESULT ddrval; // result back from dd calls
- UCHAR *primary_buffer = NULL; // primary video buffer
- UCHAR *back_buffer = NULL; // secondary back buffer
- int primary_lpitch = 0; // memory line pitch
- int back_lpitch = 0; // memory line pitch
- BITMAP_FILE bitmap16bit; // a 16 bit bitmap file
- BITMAP_FILE bitmap8bit; // a 8 bit bitmap file
-
- DWORD start_clock_count = 0; // used for timing
-
- // these defined the general clipping rectangle
- int min_clip_x = 0, // clipping rectangle
- max_clip_x = SCREEN_WIDTH-1,
- min_clip_y = 0,
- max_clip_y = SCREEN_HEIGHT-1;
-
- // these are overwritten globally by DD_Init()
- int screen_width = SCREEN_WIDTH, // width of screen
- screen_height = SCREEN_HEIGHT, // height of screen
- screen_bpp = SCREEN_BPP; // bits per pixel
-
- // FUNCTIONS //////////////////////////////////////////////
-
- // the BOB engine, note that 90% of the BOB functions have
- // the exact same code for the 8 and 16 bit versions, however
- // I decided that it was just easier using all 8 or 16 bit
- // versions syntactically, plus you might want to add some
- // more functionality to the 16 bit versions, so having separate
- // functions makes that easier --
-
- ///////////////////////////////////////////////////////////
-
- int Create_BOB(BOB_PTR bob, // the bob to create
- float x, float y, // initial posiiton
- int width, int height, // size of bob
- int num_frames, // number of frames
- int attr, // attrs
- int mem_flags) // memory flag
- {
- // Create the BOB object, note that all BOBs
- // are created as offscreen surfaces in VRAM as the
- // default, if you want to use system memory then
- // set flags equal to DDSCAPS_SYSTEMMEMORY
-
- DDSURFACEDESC2 ddsd; // used to create surface
- int index; // looping var
-
- // set state and attributes of BOB
- bob->state = BOB_STATE_ALIVE;
- bob->attr = attr;
- bob->anim_state = 0;
- bob->counter_1 = 0;
- bob->counter_2 = 0;
- bob->max_count_1 = 0;
- bob->max_count_2 = 0;
-
- bob->curr_frame = 0;
- bob->num_frames = num_frames;
- bob->curr_animation = 0;
- bob->anim_counter = 0;
- bob->anim_index = 0;
- bob->anim_count_max = 0;
- bob->x = x;
- bob->y = y;
- bob->xv = 0;
- bob->yv = 0;
-
- // set dimensions of the new bitmap surface
- bob->width = width;
- bob->height = height;
- bob->bpp = 8;
-
- // set all images to null
- for (index=0; index < MAX_BOB_FRAMES; index++)
- bob->images[index] = NULL;
-
- // set all animations to null
- for (index=0; index < MAX_BOB_ANIMATIONS; index++)
- bob->animations[index] = NULL;
-
- // make sure width is a multiple of 8
- bob->width_fill = ((width%8!=0) ? (8-width%8) : 0);
- Write_Error("\nCreate BOB %d",bob->width_fill);
-
- // now create each surface
- for (index=0; index<bob->num_frames; index++)
- {
- // set to access caps, width, and height
- memset(&ddsd,0,sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
-
- ddsd.dwWidth = bob->width + bob->width_fill;
- ddsd.dwHeight = bob->height;
-
- // set surface to offscreen plain
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | mem_flags;
-
- // create the surfaces
- if (lpdd->CreateSurface(&ddsd,&(bob->images[index]),NULL)!=DD_OK)
- return(0);
-
- // set color key to color 0
- DDCOLORKEY color_key; // used to set color key
- color_key.dwColorSpaceLowValue = 0;
- color_key.dwColorSpaceHighValue = 0;
-
- // now set the color key for source blitting
- (bob->images[index])->SetColorKey(DDCKEY_SRCBLT, &color_key);
- } // end for index
-
- // return success
- return(1);
-
- } // end Create_BOB
-
- ///////////////////////////////////////////////////////////
-
- int Create_BOB16(BOB_PTR bob, // the bob to create
- float x, float y, // initial posiiton
- int width, int height, // size of bob
- int num_frames, // number of frames
- int attr, // attrs
- int mem_flags) // memory flag
- {
- // Create the 16-bit BOB object, note that all BOBs
- // are created as offscreen surfaces in VRAM as the
- // default, if you want to use system memory then
- // set flags equal to DDSCAPS_SYSTEMMEMORY
-
- DDSURFACEDESC2 ddsd; // used to create surface
- int index; // looping var
-
- // set state and attributes of BOB
- bob->state = BOB_STATE_ALIVE;
- bob->attr = attr;
- bob->anim_state = 0;
- bob->counter_1 = 0;
- bob->counter_2 = 0;
- bob->max_count_1 = 0;
- bob->max_count_2 = 0;
-
- bob->curr_frame = 0;
- bob->num_frames = num_frames;
- bob->curr_animation = 0;
- bob->anim_counter = 0;
- bob->anim_index = 0;
- bob->anim_count_max = 0;
- bob->x = x;
- bob->y = y;
- bob->xv = 0;
- bob->yv = 0;
-
- // set dimensions of the new bitmap surface
- bob->width = width;
- bob->height = height;
- bob->bpp = 16;
-
- // set all images to null
- for (index=0; index < MAX_BOB_FRAMES; index++)
- bob->images[index] = NULL;
-
- // set all animations to null
- for (index=0; index < MAX_BOB_ANIMATIONS; index++)
- bob->animations[index] = NULL;
-
- // make sure width is a multiple of 8
- bob->width_fill = ((width%8!=0) ? (8-width%8) : 0);
- Write_Error("\nCreate BOB %d",bob->width_fill);
-
- // now create each surface
- for (index=0; index<bob->num_frames; index++)
- {
- // set to access caps, width, and height
- memset(&ddsd,0,sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
-
- ddsd.dwWidth = bob->width + bob->width_fill;
- ddsd.dwHeight = bob->height;
-
- // set surface to offscreen plain
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | mem_flags;
-
- // create the surfaces
- if (lpdd->CreateSurface(&ddsd,&(bob->images[index]),NULL)!=DD_OK)
- return(0);
-
- // set color key to RGB (0,0,0) color 0
- DDCOLORKEY color_key; // used to set color key
- color_key.dwColorSpaceLowValue = _RGB16BIT565(0,0,0);
- color_key.dwColorSpaceHighValue = _RGB16BIT565(0,0,0);
-
- // now set the color key for source blitting
- (bob->images[index])->SetColorKey(DDCKEY_SRCBLT, &color_key);
- } // end for index
-
- // return success
- return(1);
-
- } // end Create_BOB16
-
- ///////////////////////////////////////////////////////////
-
- int Destroy_BOB(BOB_PTR bob)
- {
- // destroy the BOB, simply release the surface
-
- int index; // looping var
-
- // is this bob valid
- if (!bob)
- return(0);
-
- // destroy each bitmap surface
- for (index=0; index < MAX_BOB_FRAMES; index++)
- if (bob->images[index])
- (bob->images[index])->Release();
-
- // release memory for animation sequences
- for (index=0; index < MAX_BOB_ANIMATIONS; index++)
- if (bob->animations[index])
- free(bob->animations[index]);
-
- // return success
- return(1);
-
- } // end Destroy_BOB
-
- ///////////////////////////////////////////////////////////
-
- int Destroy_BOB16(BOB_PTR bob)
- {
- // destroy the BOB, simply release the surface
-
- int index; // looping var
-
- // is this bob valid
- if (!bob)
- return(0);
-
- // destroy each bitmap surface
- for (index=0; index < MAX_BOB_FRAMES; index++)
- if (bob->images[index])
- (bob->images[index])->Release();
-
- // release memory for animation sequences
- for (index=0; index < MAX_BOB_ANIMATIONS; index++)
- if (bob->animations[index])
- free(bob->animations[index]);
-
- // return success
- return(1);
-
- } // end Destroy_BOB16
-
- ///////////////////////////////////////////////////////////
-
- int Draw_BOB(BOB_PTR bob, // bob to draw
- LPDIRECTDRAWSURFACE7 dest) // surface to draw the bob on
- {
- // draw a bob at the x,y defined in the BOB
- // on the destination surface defined in dest
-
- RECT dest_rect, // the destination rectangle
- source_rect; // the source rectangle
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // is bob visible
- if (!(bob->attr & BOB_ATTR_VISIBLE))
- return(1);
-
- // fill in the destination rect
- dest_rect.left = bob->x;
- dest_rect.top = bob->y;
- dest_rect.right = bob->x+bob->width;
- dest_rect.bottom = bob->y+bob->height;
-
- // fill in the source rect
- source_rect.left = 0;
- source_rect.top = 0;
- source_rect.right = bob->width;
- source_rect.bottom = bob->height;
-
- // blt to destination surface
- if (dest->Blt(&dest_rect, bob->images[bob->curr_frame],
- &source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
- NULL)!=DD_OK)
- return(0);
-
- // return success
- return(1);
- } // end Draw_BOB
-
- ///////////////////////////////////////////////////////////
-
- int Draw_BOB16(BOB_PTR bob, // bob to draw
- LPDIRECTDRAWSURFACE7 dest) // surface to draw the bob on
- {
- // draw a bob at the x,y defined in the BOB
- // on the destination surface defined in dest
-
- RECT dest_rect, // the destination rectangle
- source_rect; // the source rectangle
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // is bob visible
- if (!(bob->attr & BOB_ATTR_VISIBLE))
- return(1);
-
- // fill in the destination rect
- dest_rect.left = bob->x;
- dest_rect.top = bob->y;
- dest_rect.right = bob->x+bob->width;
- dest_rect.bottom = bob->y+bob->height;
-
- // fill in the source rect
- source_rect.left = 0;
- source_rect.top = 0;
- source_rect.right = bob->width;
- source_rect.bottom = bob->height;
-
- // blt to destination surface
- if (dest->Blt(&dest_rect, bob->images[bob->curr_frame],
- &source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
- NULL)!=DD_OK)
- return(0);
-
- // return success
- return(1);
- } // end Draw_BOB16
-
- ///////////////////////////////////////////////////////////
-
- int Draw_Scaled_BOB(BOB_PTR bob, int swidth, int sheight, // bob and new dimensions
- LPDIRECTDRAWSURFACE7 dest) // surface to draw the bob on)
- {
- // this function draws a scaled bob to the size swidth, sheight
-
- RECT dest_rect, // the destination rectangle
- source_rect; // the source rectangle
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // is bob visible
- if (!(bob->attr & BOB_ATTR_VISIBLE))
- return(1);
-
- // fill in the destination rect
- dest_rect.left = bob->x;
- dest_rect.top = bob->y;
- dest_rect.right = bob->x+swidth;
- dest_rect.bottom = bob->y+sheight;
-
- // fill in the source rect
- source_rect.left = 0;
- source_rect.top = 0;
- source_rect.right = bob->width;
- source_rect.bottom = bob->height;
-
- // blt to destination surface
- if (dest->Blt(&dest_rect, bob->images[bob->curr_frame],
- &source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
- NULL)!=DD_OK)
- return(0);
-
- // return success
- return(1);
- } // end Draw_Scaled_BOB
-
- ///////////////////////////////////////////////////////////
-
- int Draw_Scaled_BOB16(BOB_PTR bob, int swidth, int sheight, // bob and new dimensions
- LPDIRECTDRAWSURFACE7 dest) // surface to draw the bob on)
- {
- // this function draws a scaled bob to the size swidth, sheight
-
- RECT dest_rect, // the destination rectangle
- source_rect; // the source rectangle
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // is bob visible
- if (!(bob->attr & BOB_ATTR_VISIBLE))
- return(1);
-
- // fill in the destination rect
- dest_rect.left = bob->x;
- dest_rect.top = bob->y;
- dest_rect.right = bob->x+swidth;
- dest_rect.bottom = bob->y+sheight;
-
- // fill in the source rect
- source_rect.left = 0;
- source_rect.top = 0;
- source_rect.right = bob->width;
- source_rect.bottom = bob->height;
-
- // blt to destination surface
- if (dest->Blt(&dest_rect, bob->images[bob->curr_frame],
- &source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
- NULL)!=DD_OK)
- return(0);
-
- // return success
- return(1);
-
- } // end Draw_Scaled_BOB16
-
- ///////////////////////////////////////////////////////////
-
- int Load_Frame_BOB(BOB_PTR bob, // bob to load with data
- BITMAP_FILE_PTR bitmap, // bitmap to scan image data from
- int frame, // frame to load
- int cx,int cy, // cell or absolute pos. to scan image from
- int mode) // if 0 then cx,cy is cell position, else
- // cx,cy are absolute coords
- {
- // this function extracts a bitmap out of a bitmap file
-
- UCHAR *source_ptr, // working pointers
- *dest_ptr;
-
- DDSURFACEDESC2 ddsd; // direct draw surface description
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // test the mode of extraction, cell based or absolute
- if (mode==BITMAP_EXTRACT_MODE_CELL)
- {
- // re-compute x,y
- cx = cx*(bob->width+1) + 1;
- cy = cy*(bob->height+1) + 1;
- } // end if
-
- // extract bitmap data
- source_ptr = bitmap->buffer + cy*bitmap->bitmapinfoheader.biWidth+cx;
-
- // get the addr to destination surface memory
-
- // set size of the structure
- ddsd.dwSize = sizeof(ddsd);
-
- // lock the display surface
- (bob->images[frame])->Lock(NULL,
- &ddsd,
- DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
- NULL);
-
- // assign a pointer to the memory surface for manipulation
- dest_ptr = (UCHAR *)ddsd.lpSurface;
-
- // iterate thru each scanline and copy bitmap
- for (int index_y=0; index_y<bob->height; index_y++)
- {
- // copy next line of data to destination
- memcpy(dest_ptr, source_ptr,bob->width);
-
- // advance pointers
- dest_ptr += (bob->width+bob->width_fill);
- source_ptr += bitmap->bitmapinfoheader.biWidth;
- } // end for index_y
-
- // unlock the surface
- (bob->images[frame])->Unlock(NULL);
-
- // set state to loaded
- bob->attr |= BOB_ATTR_LOADED;
-
- // return success
- return(1);
-
- } // end Load_Frame_BOB
-
- ///////////////////////////////////////////////////////////
-
- int Load_Frame_BOB16(BOB_PTR bob, // bob to load with data
- BITMAP_FILE_PTR bitmap, // bitmap to scan image data from
- int frame, // frame to load
- int cx,int cy, // cell or absolute pos. to scan image from
- int mode) // if 0 then cx,cy is cell position, else
- // cx,cy are absolute coords
- {
- // this function extracts a bitmap out of a bitmap file
-
- USHORT *source_ptr, // working pointers
- *dest_ptr;
-
- DDSURFACEDESC2 ddsd; // direct draw surface description
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // test the mode of extraction, cell based or absolute
- if (mode==BITMAP_EXTRACT_MODE_CELL)
- {
- // re-compute x,y
- cx = cx*(bob->width+1) + 1;
- cy = cy*(bob->height+1) + 1;
- } // end if
-
- // extract bitmap data
- source_ptr = (USHORT *)bitmap->buffer + cy*bitmap->bitmapinfoheader.biWidth+cx;
-
- // get the addr to destination surface memory
-
- // set size of the structure
- ddsd.dwSize = sizeof(ddsd);
-
- // lock the display surface
- (bob->images[frame])->Lock(NULL,
- &ddsd,
- DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
- NULL);
-
- // assign a pointer to the memory surface for manipulation
- dest_ptr = (USHORT *)ddsd.lpSurface;
-
- // iterate thru each scanline and copy bitmap
- for (int index_y=0; index_y<bob->height; index_y++)
- {
- // copy next line of data to destination
- memcpy(dest_ptr, source_ptr,(bob->width*2));
-
- // advance pointers
- dest_ptr += (ddsd.lPitch >> 1);
- source_ptr += bitmap->bitmapinfoheader.biWidth;
- } // end for index_y
-
- // unlock the surface
- (bob->images[frame])->Unlock(NULL);
-
- // set state to loaded
- bob->attr |= BOB_ATTR_LOADED;
-
- // return success
- return(1);
-
- } // end Load_Frame_BOB16
-
- ///////////////////////////////////////////////////////////
-
- int Animate_BOB(BOB_PTR bob)
- {
- // this function animates a bob, basically it takes a look at
- // the attributes of the bob and determines if the bob is
- // a single frame, multiframe, or multi animation, updates
- // the counters and frames appropriately
-
- #if 0
- int curr_frame; // current animation frame
- int num_frames; // total number of animation frames
- int curr_animation; // index of current animation
- int anim_counter; // used to time animation transitions
- int anim_index; // animation element index
- int anim_count_max; // number of cycles before animation
- int *animations[MAX_BOB_ANIMATIONS]; // animation sequences
-
- LPDIRECTDRAWSURFACE7 images[MAX_BOB_FRAMES]; // the bitmap images DD surfaces
- #endif
-
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // test the level of animation
- if (bob->attr & BOB_ATTR_SINGLE_FRAME)
- {
- // current frame always = 0
- bob->curr_frame = 0;
- return(1);
- } // end if
- else
- if (bob->attr & BOB_ATTR_MULTI_FRAME)
- {
- // update the counter and test if its time to increment frame
- if (++bob->anim_counter >= bob->anim_count_max)
- {
- // reset counter
- bob->anim_counter = 0;
-
- // move to next frame
- if (++bob->curr_frame >= bob->num_frames)
- bob->curr_frame = 0;
-
- } // end if
-
- } // end elseif
- else
- if (bob->attr & BOB_ATTR_MULTI_ANIM)
- {
- // this is the most complex of the animations it must look up the
- // next frame in the animation sequence
-
- // first test if its time to animate
- if (++bob->anim_counter >= bob->anim_count_max)
- {
- // reset counter
- bob->anim_counter = 0;
-
- // increment the animation frame index
- bob->anim_index++;
-
- // extract the next frame from animation list
- bob->curr_frame = bob->animations[bob->curr_animation][bob->anim_index];
-
- // is this and end sequence flag -1
- if (bob->curr_frame == -1)
- {
- // test if this is a single shot animation
- if (bob->attr & BOB_ATTR_ANIM_ONE_SHOT)
- {
- // set animation state message to done
- bob->anim_state = BOB_STATE_ANIM_DONE;
-
- // reset frame back one
- bob->anim_index--;
-
- // extract animation frame
- bob->curr_frame = bob->animations[bob->curr_animation][bob->anim_index];
-
- } // end if
- else
- {
- // reset animation index
- bob->anim_index = 0;
-
- // extract first animation frame
- bob->curr_frame = bob->animations[bob->curr_animation][bob->anim_index];
- } // end else
-
- } // end if
-
- } // end if
-
- } // end elseif
-
- // return success
- return(1);
-
- } // end Animate_BOB
-
- ////////////////////////////////////////////////////////////////
-
- int Animate_BOB16(BOB_PTR bob)
- {
- // this function animates a bob, basically it takes a look at
- // the attributes of the bob and determines if the bob is
- // a single frame, multiframe, or multi animation, updates
- // the counters and frames appropriately
-
- #if 0
- int curr_frame; // current animation frame
- int num_frames; // total number of animation frames
- int curr_animation; // index of current animation
- int anim_counter; // used to time animation transitions
- int anim_index; // animation element index
- int anim_count_max; // number of cycles before animation
- int *animations[MAX_BOB_ANIMATIONS]; // animation sequences
-
- LPDIRECTDRAWSURFACE7 images[MAX_BOB_FRAMES]; // the bitmap images DD surfaces
- #endif
-
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // test the level of animation
- if (bob->attr & BOB_ATTR_SINGLE_FRAME)
- {
- // current frame always = 0
- bob->curr_frame = 0;
- return(1);
- } // end if
- else
- if (bob->attr & BOB_ATTR_MULTI_FRAME)
- {
- // update the counter and test if its time to increment frame
- if (++bob->anim_counter >= bob->anim_count_max)
- {
- // reset counter
- bob->anim_counter = 0;
-
- // move to next frame
- if (++bob->curr_frame >= bob->num_frames)
- bob->curr_frame = 0;
-
- } // end if
-
- } // end elseif
- else
- if (bob->attr & BOB_ATTR_MULTI_ANIM)
- {
- // this is the most complex of the animations it must look up the
- // next frame in the animation sequence
-
- // first test if its time to animate
- if (++bob->anim_counter >= bob->anim_count_max)
- {
- // reset counter
- bob->anim_counter = 0;
-
- // increment the animation frame index
- bob->anim_index++;
-
- // extract the next frame from animation list
- bob->curr_frame = bob->animations[bob->curr_animation][bob->anim_index];
-
- // is this and end sequence flag -1
- if (bob->curr_frame == -1)
- {
- // test if this is a single shot animation
- if (bob->attr & BOB_ATTR_ANIM_ONE_SHOT)
- {
- // set animation state message to done
- bob->anim_state = BOB_STATE_ANIM_DONE;
-
- // reset frame back one
- bob->anim_index--;
-
- // extract animation frame
- bob->curr_frame = bob->animations[bob->curr_animation][bob->anim_index];
-
- } // end if
- else
- {
- // reset animation index
- bob->anim_index = 0;
-
- // extract first animation frame
- bob->curr_frame = bob->animations[bob->curr_animation][bob->anim_index];
- } // end else
-
- } // end if
-
- } // end if
-
- } // end elseif
-
- // return success
- return(1);
-
- } // end Animate_BOB16
-
- ///////////////////////////////////////////////////////////
-
- int Scroll_BOB(void)
- {
- // this function scrolls a bob
- // not implemented
-
- // return success
- return(1);
- } // end Scroll_BOB
-
- ///////////////////////////////////////////////////////////
-
- int Move_BOB(BOB_PTR bob)
- {
- // this function moves the bob based on its current velocity
- // also, the function test for various motion attributes of the'
- // bob and takes the appropriate actions
-
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // translate the bob
- bob->x+=bob->xv;
- bob->y+=bob->yv;
-
- // test for wrap around
- if (bob->attr & BOB_ATTR_WRAPAROUND)
- {
- // test x extents first
- if (bob->x > max_clip_x)
- bob->x = min_clip_x - bob->width;
- else
- if (bob->x < min_clip_x-bob->width)
- bob->x = max_clip_x;
-
- // now y extents
- if (bob->y > max_clip_y)
- bob->y = min_clip_y - bob->height;
- else
- if (bob->y < min_clip_y-bob->height)
- bob->y = max_clip_y;
-
- } // end if
- else
- // test for bounce
- if (bob->attr & BOB_ATTR_BOUNCE)
- {
- // test x extents first
- if ((bob->x > max_clip_x - bob->width) || (bob->x < min_clip_x) )
- bob->xv = -bob->xv;
-
- // now y extents
- if ((bob->y > max_clip_y - bob->height) || (bob->y < min_clip_y) )
- bob->yv = -bob->yv;
-
- } // end if
-
- // return success
- return(1);
- } // end Move_BOB
-
- ///////////////////////////////////////////////////////////
-
- int Move_BOB16(BOB_PTR bob)
- {
- // this function moves the bob based on its current velocity
- // also, the function test for various motion attributes of the'
- // bob and takes the appropriate actions
-
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // translate the bob
- bob->x+=bob->xv;
- bob->y+=bob->yv;
-
- // test for wrap around
- if (bob->attr & BOB_ATTR_WRAPAROUND)
- {
- // test x extents first
- if (bob->x > max_clip_x)
- bob->x = min_clip_x - bob->width;
- else
- if (bob->x < min_clip_x-bob->width)
- bob->x = max_clip_x;
-
- // now y extents
- if (bob->y > max_clip_y)
- bob->y = min_clip_y - bob->height;
- else
- if (bob->y < min_clip_y-bob->height)
- bob->y = max_clip_y;
-
- } // end if
- else
- // test for bounce
- if (bob->attr & BOB_ATTR_BOUNCE)
- {
- // test x extents first
- if ((bob->x > max_clip_x - bob->width) || (bob->x < min_clip_x) )
- bob->xv = -bob->xv;
-
- // now y extents
- if ((bob->y > max_clip_y - bob->height) || (bob->y < min_clip_y) )
- bob->yv = -bob->yv;
-
- } // end if
-
- // return success
- return(1);
- } // end Move_BOB16
-
- ///////////////////////////////////////////////////////////
-
- int Load_Animation_BOB(BOB_PTR bob,
- int anim_index,
- int num_frames,
- int *sequence)
- {
- // this function load an animation sequence for a bob
- // the sequence consists of frame indices, the function
- // will append a -1 to the end of the list so the display
- // software knows when to restart the animation sequence
-
- // is this bob valid
- if (!bob)
- return(0);
-
- // allocate memory for bob animation
- if (!(bob->animations[anim_index] = (int *)malloc((num_frames+1)*sizeof(int))))
- return(0);
-
- // load data into
- for (int index=0; index<num_frames; index++)
- bob->animations[anim_index][index] = sequence[index];
-
- // set the end of the list to a -1
- bob->animations[anim_index][index] = -1;
-
- // return success
- return(1);
-
- } // end Load_Animation_BOB
-
- ///////////////////////////////////////////////////////////
-
- int Load_Animation_BOB16(BOB_PTR bob,
- int anim_index,
- int num_frames,
- int *sequence)
- {
- // this function load an animation sequence for a bob
- // the sequence consists of frame indices, the function
- // will append a -1 to the end of the list so the display
- // software knows when to restart the animation sequence
-
- // is this bob valid
- if (!bob)
- return(0);
-
- // allocate memory for bob animation
- if (!(bob->animations[anim_index] = (int *)malloc((num_frames+1)*sizeof(int))))
- return(0);
-
- // load data into
- for (int index=0; index<num_frames; index++)
- bob->animations[anim_index][index] = sequence[index];
-
- // set the end of the list to a -1
- bob->animations[anim_index][index] = -1;
-
- // return success
- return(1);
-
- } // end Load_Animation_BOB16
-
- ///////////////////////////////////////////////////////////
-
- int Set_Pos_BOB(BOB_PTR bob, int x, int y)
- {
- // this functions sets the postion of a bob
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // set positin
- bob->x = x;
- bob->y = y;
-
- // return success
- return(1);
- } // end Set_Pos_BOB
-
- ///////////////////////////////////////////////////////////
-
- int Set_Pos_BOB16(BOB_PTR bob, int x, int y)
- {
- // this functions sets the postion of a bob
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // set positin
- bob->x = x;
- bob->y = y;
-
- // return success
- return(1);
- } // end Set_Pos_BOB16
-
- ///////////////////////////////////////////////////////////
-
- int Set_Anim_Speed_BOB(BOB_PTR bob,int speed)
- {
- // this function simply sets the animation speed of a bob
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // set speed
- bob->anim_count_max = speed;
-
- // return success
- return(1);
-
- } // end Set_Anim_Speed
-
- ///////////////////////////////////////////////////////////
-
- int Set_Anim_Speed_BOB16(BOB_PTR bob,int speed)
- {
- // this function simply sets the animation speed of a bob
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // set speed
- bob->anim_count_max = speed;
-
- // return success
- return(1);
-
- } // end Set_Anim_Speed16
-
- ///////////////////////////////////////////////////////////
-
- int Set_Animation_BOB(BOB_PTR bob, int anim_index)
- {
- // this function sets the animation to play
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // set the animation index
- bob->curr_animation = anim_index;
-
- // reset animation
- bob->anim_index = 0;
-
- // return success
- return(1);
-
- } // end Set_Animation_BOB
-
- ///////////////////////////////////////////////////////////
-
- int Set_Animation_BOB16(BOB_PTR bob, int anim_index)
- {
- // this function sets the animation to play
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // set the animation index
- bob->curr_animation = anim_index;
-
- // reset animation
- bob->anim_index = 0;
-
- // return success
- return(1);
-
- } // end Set_Animation_BOB16
-
- ///////////////////////////////////////////////////////////
-
- int Set_Vel_BOB(BOB_PTR bob,int xv, int yv)
- {
- // this function sets the velocity of a bob
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // set velocity
- bob->xv = xv;
- bob->yv = yv;
-
- // return success
- return(1);
- } // end Set_Vel_BOB
-
- ///////////////////////////////////////////////////////////
-
- int Set_Vel_BOB16(BOB_PTR bob,int xv, int yv)
- {
- // this function sets the velocity of a bob
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // set velocity
- bob->xv = xv;
- bob->yv = yv;
-
- // return success
- return(1);
- } // end Set_Vel_BOB16
-
- ///////////////////////////////////////////////////////////
-
- int Hide_BOB(BOB_PTR bob)
- {
- // this functions hides bob
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // reset the visibility bit
- RESET_BIT(bob->attr, BOB_ATTR_VISIBLE);
-
- // return success
- return(1);
- } // end Hide_BOB
-
- ///////////////////////////////////////////////////////////
-
- int Hide_BOB16(BOB_PTR bob)
- {
- // this functions hides bob
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // reset the visibility bit
- RESET_BIT(bob->attr, BOB_ATTR_VISIBLE);
-
- // return success
- return(1);
- } // end Hide_BOB16
-
- ///////////////////////////////////////////////////////////
-
- int Show_BOB(BOB_PTR bob)
- {
- // this function shows a bob
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // set the visibility bit
- SET_BIT(bob->attr, BOB_ATTR_VISIBLE);
-
- // return success
- return(1);
- } // end Show_BOB
-
- ///////////////////////////////////////////////////////////
-
- int Show_BOB16(BOB_PTR bob)
- {
- // this function shows a bob
-
- // is this a valid bob
- if (!bob)
- return(0);
-
- // set the visibility bit
- SET_BIT(bob->attr, BOB_ATTR_VISIBLE);
-
- // return success
- return(1);
- } // end Show_BOB16
-
- ///////////////////////////////////////////////////////////
-
- int Collision_BOBS(BOB_PTR bob1, BOB_PTR bob2)
- {
- // are these a valid bobs
- if (!bob1 || !bob2)
- return(0);
-
- // get the radi of each rect
- int width1 = (bob1->width>>1) - (bob1->width>>3);
- int height1 = (bob1->height>>1) - (bob1->height>>3);
-
- int width2 = (bob2->width>>1) - (bob2->width>>3);
- int height2 = (bob2->height>>1) - (bob2->height>>3);
-
- // compute center of each rect
- int cx1 = bob1->x + width1;
- int cy1 = bob1->y + height1;
-
- int cx2 = bob2->x + width2;
- int cy2 = bob2->y + height2;
-
- // compute deltas
- int dx = abs(cx2 - cx1);
- int dy = abs(cy2 - cy1);
-
- // test if rects overlap
- if (dx < (width1+width2) && dy < (height1+height2))
- return(1);
- else
- // else no collision
- return(0);
-
- } // end Collision_BOBS
-
-
- ///////////////////////////////////////////////////////////
-
- int Collision_BOBS16(BOB_PTR bob1, BOB_PTR bob2)
- {
- // are these a valid bobs
- if (!bob1 || !bob2)
- return(0);
-
- // get the radi of each rect
- int width1 = (bob1->width>>1) - (bob1->width>>3);
- int height1 = (bob1->height>>1) - (bob1->height>>3);
-
- int width2 = (bob2->width>>1) - (bob2->width>>3);
- int height2 = (bob2->height>>1) - (bob2->height>>3);
-
- // compute center of each rect
- int cx1 = bob1->x + width1;
- int cy1 = bob1->y + height1;
-
- int cx2 = bob2->x + width2;
- int cy2 = bob2->y + height2;
-
- // compute deltas
- int dx = abs(cx2 - cx1);
- int dy = abs(cy2 - cy1);
-
- // test if rects overlap
- if (dx < (width1+width2) && dy < (height1+height2))
- return(1);
- else
- // else no collision
- return(0);
-
- } // end Collision_BOBS16
-
- ///////////////////////////////////////////////////////////
-
- int DD_Init(int width, int height, int bpp)
- {
- // this function initializes directdraw
- int index; // looping variable
- // create object and test for error
- if (DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)!=DD_OK)
- return(0);
-
- // set cooperation level to windowed mode normal
- if (lpdd->SetCooperativeLevel(main_window_handle,
- DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN |
- DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)!=DD_OK)
- return(0);
-
- // set the display mode
- if (lpdd->SetDisplayMode(width,height,bpp,0,0)!=DD_OK)
- return(0);
-
- // set globals
- screen_height = height;
- screen_width = width;
- screen_bpp = bpp;
-
- // Create the primary surface
- memset(&ddsd,0,sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
-
- // we need to let dd know that we want a complex
- // flippable surface structure, set flags for that
- ddsd.ddsCaps.dwCaps =
- DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
-
- // set the backbuffer count to 1
- ddsd.dwBackBufferCount = 1;
-
- // create the primary surface
- lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL);
-
- // query for the backbuffer i.e the secondary surface
- ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
- lpddsprimary->GetAttachedSurface(&ddscaps,&lpddsback);
-
- // create and attach palette for 8-bit modes
-
- if (screen_bpp==8)
- {
- // create palette data
- // clear all entries defensive programming
- memset(palette,0,256*sizeof(PALETTEENTRY));
-
- // create a R,G,B,GR gradient palette
- for (index=0; index < 256; index++)
- {
- // set each entry
- if (index < 64)
- palette[index].peRed = index*4;
- else // shades of green
- if (index >= 64 && index < 128)
- palette[index].peGreen = (index-64)*4;
- else // shades of blue
- if (index >= 128 && index < 192)
- palette[index].peBlue = (index-128)*4;
- else // shades of grey
- if (index >= 192 && index < 256)
- palette[index].peRed = palette[index].peGreen =
- palette[index].peBlue = (index-192)*4;
-
- // set flags
- palette[index].peFlags = PC_NOCOLLAPSE;
- } // end for index
-
- // now create the palette object
- if (lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE | DDPCAPS_ALLOW256,
- palette,&lpddpal,NULL)!=DD_OK)
- return(0);
-
- // attach the palette to the primary
- if (lpddsprimary->SetPalette(lpddpal)!=DD_OK)
- return(0);
-
- } // end if palette
-
- // clear out both primary and secondary surfaces
- DD_Fill_Surface(lpddsprimary,0);
- DD_Fill_Surface(lpddsback,0);
-
- // return success
- return(1);
- } // end DD_Init
-
- ///////////////////////////////////////////////////////////
-
- int DD_Shutdown(void)
- {
- // this function release all the resources directdraw
- // allocated, mainly to com objects
-
- // release the clipper first
- if (lpddclipper)
- lpddclipper->Release();
-
- // release the palette
- if (lpddpal)
- lpddpal->Release();
-
- // release the secondary surface
- if (lpddsback)
- lpddsback->Release();
-
- // release the primary surface
- if (lpddsprimary)
- lpddsprimary->Release();
-
- // finally, the main dd object
- if (lpdd)
- lpdd->Release();
-
- // return success
- return(1);
- } // end DD_Shutdown
-
- ///////////////////////////////////////////////////////////
-
- LPDIRECTDRAWCLIPPER DD_Attach_Clipper(LPDIRECTDRAWSURFACE7 lpdds,
- int num_rects,
- LPRECT clip_list)
-
- {
- // this function creates a clipper from the sent clip list and attaches
- // it to the sent surface
-
- int index; // looping var
- LPDIRECTDRAWCLIPPER lpddclipper; // pointer to the newly created dd clipper
- LPRGNDATA region_data; // pointer to the region data that contains
- // the header and clip list
-
- // first create the direct draw clipper
- if ((lpdd->CreateClipper(0,&lpddclipper,NULL))!=DD_OK)
- return(NULL);
-
- // now create the clip list from the sent data
-
- // first allocate memory for region data
- region_data = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+num_rects*sizeof(RECT));
-
- // now copy the rects into region data
- memcpy(region_data->Buffer, clip_list, sizeof(RECT)*num_rects);
-
- // set up fields of header
- region_data->rdh.dwSize = sizeof(RGNDATAHEADER);
- region_data->rdh.iType = RDH_RECTANGLES;
- region_data->rdh.nCount = num_rects;
- region_data->rdh.nRgnSize = num_rects*sizeof(RECT);
-
- region_data->rdh.rcBound.left = 64000;
- region_data->rdh.rcBound.top = 64000;
- region_data->rdh.rcBound.right = -64000;
- region_data->rdh.rcBound.bottom = -64000;
-
- // find bounds of all clipping regions
- for (index=0; index<num_rects; index++)
- {
- // test if the next rectangle unioned with the current bound is larger
- if (clip_list[index].left < region_data->rdh.rcBound.left)
- region_data->rdh.rcBound.left = clip_list[index].left;
-
- if (clip_list[index].right > region_data->rdh.rcBound.right)
- region_data->rdh.rcBound.right = clip_list[index].right;
-
- if (clip_list[index].top < region_data->rdh.rcBound.top)
- region_data->rdh.rcBound.top = clip_list[index].top;
-
- if (clip_list[index].bottom > region_data->rdh.rcBound.bottom)
- region_data->rdh.rcBound.bottom = clip_list[index].bottom;
-
- } // end for index
-
- // now we have computed the bounding rectangle region and set up the data
- // now let's set the clipping list
-
- if ((lpddclipper->SetClipList(region_data, 0))!=DD_OK)
- {
- // release memory and return error
- free(region_data);
- return(NULL);
- } // end if
-
- // now attach the clipper to the surface
- if ((lpdds->SetClipper(lpddclipper))!=DD_OK)
- {
- // release memory and return error
- free(region_data);
- return(NULL);
- } // end if
-
- // all is well, so release memory and send back the pointer to the new clipper
- free(region_data);
- return(lpddclipper);
-
- } // end DD_Attach_Clipper
-
- ///////////////////////////////////////////////////////////
-
- LPDIRECTDRAWSURFACE7 DD_Create_Surface(int width, int height, int mem_flags)
- {
- // this function creates an offscreen plain surface
-
- DDSURFACEDESC2 ddsd; // working description
- LPDIRECTDRAWSURFACE7 lpdds; // temporary surface
-
- // set to access caps, width, and height
- memset(&ddsd,0,sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
-
- // set dimensions of the new bitmap surface
- ddsd.dwWidth = width;
- ddsd.dwHeight = height;
-
- // set surface to offscreen plain
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | mem_flags;
-
- // create the surface
- if (lpdd->CreateSurface(&ddsd,&lpdds,NULL)!=DD_OK)
- return(NULL);
-
- // set color key to 0 which is index 0 and 0,0,0 rgb
- DDCOLORKEY color_key; // used to set color key
- color_key.dwColorSpaceLowValue = 0;
- color_key.dwColorSpaceHighValue = 0;
-
- // now set the color key for source blitting
- lpdds->SetColorKey(DDCKEY_SRCBLT, &color_key);
-
- // return surface
- return(lpdds);
- } // end DD_Create_Surface
-
- ///////////////////////////////////////////////////////////
-
- int DD_Flip(void)
- {
- // this function flip the primary surface with the secondary surface
-
- // test if either of the buffers are locked
- if (primary_buffer || back_buffer)
- return(0);
-
- // flip pages
- while(lpddsprimary->Flip(NULL, DDFLIP_WAIT)!=DD_OK);
-
- // flip the surface
-
- // return success
- return(1);
-
- } // end DD_Flip
-
- ///////////////////////////////////////////////////////////
-
- int DD_Wait_For_Vsync(void)
- {
- // this function waits for a vertical blank to begin
-
- lpdd->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN,0);
-
- // return success
- return(1);
- } // end DD_Wait_For_Vsync
-
- ///////////////////////////////////////////////////////////
-
- int DD_Fill_Surface(LPDIRECTDRAWSURFACE7 lpdds, int color)
- {
- DDBLTFX ddbltfx; // this contains the DDBLTFX structure
-
- // clear out the structure and set the size field
- DD_INIT_STRUCT(ddbltfx);
-
- // set the dwfillcolor field to the desired color
- ddbltfx.dwFillColor = color;
-
- // ready to blt to surface
- lpdds->Blt(NULL, // ptr to dest rectangle
- NULL, // ptr to source surface, NA
- NULL, // ptr to source rectangle, NA
- DDBLT_COLORFILL | DDBLT_WAIT, // fill and wait
- &ddbltfx); // ptr to DDBLTFX structure
-
- // return success
- return(1);
- } // end DD_Fill_Surface
-
- ///////////////////////////////////////////////////////////
-
- UCHAR *DD_Lock_Surface(LPDIRECTDRAWSURFACE7 lpdds,int *lpitch)
- {
- // this function locks the sent surface and returns a pointer to it
-
- // is this surface valid
- if (!lpdds)
- return(NULL);
-
- // lock the surface
- DD_INIT_STRUCT(ddsd);
- lpdds->Lock(NULL,&ddsd,DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,NULL);
-
- // set the memory pitch
- if (lpitch)
- *lpitch = ddsd.lPitch;
-
- // return pointer to surface
- return((UCHAR *)ddsd.lpSurface);
-
- } // end DD_Lock_Surface
-
- ///////////////////////////////////////////////////////////
-
- int DD_Unlock_Surface(LPDIRECTDRAWSURFACE7 lpdds, UCHAR *surface_buffer)
- {
- // this unlocks a general surface
-
- // is this surface valid
- if (!lpdds)
- return(0);
-
- // unlock the surface memory
- lpdds->Unlock(NULL);
-
- // return success
- return(1);
- } // end DD_Unlock_Surface
-
- ///////////////////////////////////////////////////////////
-
- UCHAR *DD_Lock_Primary_Surface(void)
- {
- // this function locks the priamary surface and returns a pointer to it
- // and updates the global variables primary_buffer, and primary_lpitch
-
- // is this surface already locked
- if (primary_buffer)
- {
- // return to current lock
- return(primary_buffer);
- } // end if
-
- // lock the primary surface
- DD_INIT_STRUCT(ddsd);
- lpddsprimary->Lock(NULL,&ddsd,DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,NULL);
-
- // set globals
- primary_buffer = (UCHAR *)ddsd.lpSurface;
- primary_lpitch = ddsd.lPitch;
-
- // return pointer to surface
- return(primary_buffer);
-
- } // end DD_Lock_Primary_Surface
-
- ///////////////////////////////////////////////////////////
-
- int DD_Unlock_Primary_Surface(void)
- {
- // this unlocks the primary
-
- // is this surface valid
- if (!primary_buffer)
- return(0);
-
- // unlock the primary surface
- lpddsprimary->Unlock(NULL);
-
- // reset the primary surface
- primary_buffer = NULL;
- primary_lpitch = 0;
-
- // return success
- return(1);
- } // end DD_Unlock_Primary_Surface
-
- //////////////////////////////////////////////////////////
-
- UCHAR *DD_Lock_Back_Surface(void)
- {
- // this function locks the secondary back surface and returns a pointer to it
- // and updates the global variables secondary buffer, and back_lpitch
-
- // is this surface already locked
- if (back_buffer)
- {
- // return to current lock
- return(back_buffer);
- } // end if
-
- // lock the primary surface
- DD_INIT_STRUCT(ddsd);
- lpddsback->Lock(NULL,&ddsd,DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,NULL);
-
- // set globals
- back_buffer = (UCHAR *)ddsd.lpSurface;
- back_lpitch = ddsd.lPitch;
-
- // return pointer to surface
- return(back_buffer);
-
- } // end DD_Lock_Back_Surface
-
- ///////////////////////////////////////////////////////////
-
- int DD_Unlock_Back_Surface(void)
- {
- // this unlocks the secondary
-
- // is this surface valid
- if (!back_buffer)
- return(0);
-
- // unlock the secondary surface
- lpddsback->Unlock(NULL);
-
- // reset the secondary surface
- back_buffer = NULL;
- back_lpitch = 0;
-
- // return success
- return(1);
- } // end DD_Unlock_Back_Surface
-
- ///////////////////////////////////////////////////////////
-
- DWORD Get_Clock(void)
- {
- // this function returns the current tick count
-
- // return time
- return(GetTickCount());
-
- } // end Get_Clock
-
- ///////////////////////////////////////////////////////////
-
- DWORD Start_Clock(void)
- {
- // this function starts the clock, that is, saves the current
- // count, use in conjunction with Wait_Clock()
-
- return(start_clock_count = Get_Clock());
-
- } // end Start_Clock
-
- ////////////////////////////////////////////////////////////
-
- DWORD Wait_Clock(DWORD count)
- {
- // this function is used to wait for a specific number of clicks
- // since the call to Start_Clock
-
- while((Get_Clock() - start_clock_count) < count);
- return(Get_Clock());
-
- } // end Wait_Clock
-
- ///////////////////////////////////////////////////////////
-
- int Draw_Clip_Line(int x0,int y0, int x1, int y1,USHORT color,
- UCHAR *dest_buffer, int lpitch)
- {
- // this function draws a wireframe triangle
-
- int cxs, cys,
- cxe, cye;
-
- // clip and draw each line
- cxs = x0;
- cys = y0;
- cxe = x1;
- cye = y1;
-
- // clip the line
- if (Clip_Line(cxs,cys,cxe,cye))
- Draw_Line(cxs, cys, cxe,cye,color,dest_buffer,lpitch);
-
- // return success
- return(1);
-
- } // end Draw_Clip_Line
-
-
- ///////////////////////////////////////////////////////////
-
- int Draw_Clip_Line16(int x0,int y0, int x1, int y1,USHORT color,
- UCHAR *dest_buffer, int lpitch)
- {
- // this function draws a wireframe triangle
-
- int cxs, cys,
- cxe, cye;
-
- // clip and draw each line
- cxs = x0;
- cys = y0;
- cxe = x1;
- cye = y1;
-
- // clip the line
- if (Clip_Line(cxs,cys,cxe,cye))
- Draw_Line16(cxs, cys, cxe,cye,color,dest_buffer,lpitch);
-
- // return success
- return(1);
-
- } // end Draw_Clip_Line16
-
- ///////////////////////////////////////////////////////////
-
- int Clip_Line(int &x1,int &y1,int &x2, int &y2)
- {
- // this function clips the sent line using the globally defined clipping
- // region
-
- // internal clipping codes
- #define CLIP_CODE_C 0x0000
- #define CLIP_CODE_N 0x0008
- #define CLIP_CODE_S 0x0004
- #define CLIP_CODE_E 0x0002
- #define CLIP_CODE_W 0x0001
-
- #define CLIP_CODE_NE 0x000a
- #define CLIP_CODE_SE 0x0006
- #define CLIP_CODE_NW 0x0009
- #define CLIP_CODE_SW 0x0005
-
- int xc1=x1,
- yc1=y1,
- xc2=x2,
- yc2=y2;
-
- int p1_code=0,
- p2_code=0;
-
- // determine codes for p1 and p2
- if (y1 < min_clip_y)
- p1_code|=CLIP_CODE_N;
- else
- if (y1 > max_clip_y)
- p1_code|=CLIP_CODE_S;
-
- if (x1 < min_clip_x)
- p1_code|=CLIP_CODE_W;
- else
- if (x1 > max_clip_x)
- p1_code|=CLIP_CODE_E;
-
- if (y2 < min_clip_y)
- p2_code|=CLIP_CODE_N;
- else
- if (y2 > max_clip_y)
- p2_code|=CLIP_CODE_S;
-
- if (x2 < min_clip_x)
- p2_code|=CLIP_CODE_W;
- else
- if (x2 > max_clip_x)
- p2_code|=CLIP_CODE_E;
-
- // try and trivially reject
- if ((p1_code & p2_code))
- return(0);
-
- // test for totally visible, if so leave points untouched
- if (p1_code==0 && p2_code==0)
- return(1);
-
- // determine end clip point for p1
- switch(p1_code)
- {
- case CLIP_CODE_C: break;
-
- case CLIP_CODE_N:
- {
- yc1 = min_clip_y;
- xc1 = x1 + 0.5+(min_clip_y-y1)*(x2-x1)/(y2-y1);
- } break;
- case CLIP_CODE_S:
- {
- yc1 = max_clip_y;
- xc1 = x1 + 0.5+(max_clip_y-y1)*(x2-x1)/(y2-y1);
- } break;
-
- case CLIP_CODE_W:
- {
- xc1 = min_clip_x;
- yc1 = y1 + 0.5+(min_clip_x-x1)*(y2-y1)/(x2-x1);
- } break;
-
- case CLIP_CODE_E:
- {
- xc1 = max_clip_x;
- yc1 = y1 + 0.5+(max_clip_x-x1)*(y2-y1)/(x2-x1);
- } break;
-
- // these cases are more complex, must compute 2 intersections
- case CLIP_CODE_NE:
- {
- // north hline intersection
- yc1 = min_clip_y;
- xc1 = x1 + 0.5+(min_clip_y-y1)*(x2-x1)/(y2-y1);
-
- // test if intersection is valid, of so then done, else compute next
- if (xc1 < min_clip_x || xc1 > max_clip_x)
- {
- // east vline intersection
- xc1 = max_clip_x;
- yc1 = y1 + 0.5+(max_clip_x-x1)*(y2-y1)/(x2-x1);
- } // end if
-
- } break;
-
- case CLIP_CODE_SE:
- {
- // south hline intersection
- yc1 = max_clip_y;
- xc1 = x1 + 0.5+(max_clip_y-y1)*(x2-x1)/(y2-y1);
-
- // test if intersection is valid, of so then done, else compute next
- if (xc1 < min_clip_x || xc1 > max_clip_x)
- {
- // east vline intersection
- xc1 = max_clip_x;
- yc1 = y1 + 0.5+(max_clip_x-x1)*(y2-y1)/(x2-x1);
- } // end if
-
- } break;
-
- case CLIP_CODE_NW:
- {
- // north hline intersection
- yc1 = min_clip_y;
- xc1 = x1 + 0.5+(min_clip_y-y1)*(x2-x1)/(y2-y1);
-
- // test if intersection is valid, of so then done, else compute next
- if (xc1 < min_clip_x || xc1 > max_clip_x)
- {
- xc1 = min_clip_x;
- yc1 = y1 + 0.5+(min_clip_x-x1)*(y2-y1)/(x2-x1);
- } // end if
-
- } break;
-
- case CLIP_CODE_SW:
- {
- // south hline intersection
- yc1 = max_clip_y;
- xc1 = x1 + 0.5+(max_clip_y-y1)*(x2-x1)/(y2-y1);
-
- // test if intersection is valid, of so then done, else compute next
- if (xc1 < min_clip_x || xc1 > max_clip_x)
- {
- xc1 = min_clip_x;
- yc1 = y1 + 0.5+(min_clip_x-x1)*(y2-y1)/(x2-x1);
- } // end if
-
- } break;
-
- default:break;
-
- } // end switch
-
- // determine clip point for p2
- switch(p2_code)
- {
- case CLIP_CODE_C: break;
-
- case CLIP_CODE_N:
- {
- yc2 = min_clip_y;
- xc2 = x2 + (min_clip_y-y2)*(x1-x2)/(y1-y2);
- } break;
-
- case CLIP_CODE_S:
- {
- yc2 = max_clip_y;
- xc2 = x2 + (max_clip_y-y2)*(x1-x2)/(y1-y2);
- } break;
-
- case CLIP_CODE_W:
- {
- xc2 = min_clip_x;
- yc2 = y2 + (min_clip_x-x2)*(y1-y2)/(x1-x2);
- } break;
-
- case CLIP_CODE_E:
- {
- xc2 = max_clip_x;
- yc2 = y2 + (max_clip_x-x2)*(y1-y2)/(x1-x2);
- } break;
-
- // these cases are more complex, must compute 2 intersections
- case CLIP_CODE_NE:
- {
- // north hline intersection
- yc2 = min_clip_y;
- xc2 = x2 + 0.5+(min_clip_y-y2)*(x1-x2)/(y1-y2);
-
- // test if intersection is valid, of so then done, else compute next
- if (xc2 < min_clip_x || xc2 > max_clip_x)
- {
- // east vline intersection
- xc2 = max_clip_x;
- yc2 = y2 + 0.5+(max_clip_x-x2)*(y1-y2)/(x1-x2);
- } // end if
-
- } break;
-
- case CLIP_CODE_SE:
- {
- // south hline intersection
- yc2 = max_clip_y;
- xc2 = x2 + 0.5+(max_clip_y-y2)*(x1-x2)/(y1-y2);
-
- // test if intersection is valid, of so then done, else compute next
- if (xc2 < min_clip_x || xc2 > max_clip_x)
- {
- // east vline intersection
- xc2 = max_clip_x;
- yc2 = y2 + 0.5+(max_clip_x-x2)*(y1-y2)/(x1-x2);
- } // end if
-
- } break;
-
- case CLIP_CODE_NW:
- {
- // north hline intersection
- yc2 = min_clip_y;
- xc2 = x2 + 0.5+(min_clip_y-y2)*(x1-x2)/(y1-y2);
-
- // test if intersection is valid, of so then done, else compute next
- if (xc2 < min_clip_x || xc2 > max_clip_x)
- {
- xc2 = min_clip_x;
- yc2 = y2 + 0.5+(min_clip_x-x2)*(y1-y2)/(x1-x2);
- } // end if
-
- } break;
-
- case CLIP_CODE_SW:
- {
- // south hline intersection
- yc2 = max_clip_y;
- xc2 = x2 + 0.5+(max_clip_y-y2)*(x1-x2)/(y1-y2);
-
- // test if intersection is valid, of so then done, else compute next
- if (xc2 < min_clip_x || xc2 > max_clip_x)
- {
- xc2 = min_clip_x;
- yc2 = y2 + 0.5+(min_clip_x-x2)*(y1-y2)/(x1-x2);
- } // end if
-
- } break;
-
- default:break;
-
- } // end switch
-
- // do bounds check
- if ((xc1 < min_clip_x) || (xc1 > max_clip_x) ||
- (yc1 < min_clip_y) || (yc1 > max_clip_y) ||
- (xc2 < min_clip_x) || (xc2 > max_clip_x) ||
- (yc2 < min_clip_y) || (yc2 > max_clip_y) )
- {
- return(0);
- } // end if
-
- // store vars back
- x1 = xc1;
- y1 = yc1;
- x2 = xc2;
- y2 = yc2;
-
- return(1);
-
- } // end Clip_Line
-
- ///////////////////////////////////////////////////////////
-
- int Draw_Line(int xo, int yo, int x1,int y1, USHORT color,
- UCHAR *vb_start,int lpitch)
- {
- // this function draws a line from xo,yo to x1,y1 using differential error
- // terms (based on Bresenahams work)
-
- int dx, // difference in x's
- dy, // difference in y's
- x_inc, // amount in pixel space to move during drawing
- y_inc, // amount in pixel space to move during drawing
- error=0, // the discriminant i.e. error i.e. decision variable
- index; // used for looping
-
- // pre-compute first pixel address in video buffer
- vb_start = vb_start + xo + yo*lpitch;
-
- // compute horizontal and vertical deltas
- dx = x1-xo;
- dy = y1-yo;
-
- // test which direction the line is going in i.e. slope angle
- if (dx>=0)
- {
- x_inc = 1;
-
- } // end if line is moving right
- else
- {
- x_inc = -1;
- dx = -dx; // need absolute value
-
- } // end else moving left
-
- // test y component of slope
-
- if (dy>=0)
- {
- y_inc = lpitch;
- } // end if line is moving down
- else
- {
- y_inc = -lpitch;
- dy = -dy; // need absolute value
-
- } // end else moving up
-
- // now based on which delta is greater we can draw the line
- if (dx>dy)
- {
- // draw the line
- for (index=0; index<=dx; index++)
- {
- // set the pixel
- *vb_start = (UCHAR)color;
-
- // adjust the error term
- error+=dy;
-
- // test if error has overflowed
- if (error>dx)
- {
- error-=dx;
-
- // move to next line
- vb_start+=y_inc;
-
-
- } // end if error overflowed
-
- // move to the next pixel
- vb_start+=x_inc;
-
- } // end for
-
- } // end if |slope| <= 1
- else
- {
- // draw the line
- for (index=0; index<=dy; index++)
- {
- // set the pixel
- *vb_start = (UCHAR)color;
-
- // adjust the error term
- error+=dx;
-
- // test if error overflowed
- if (error>0)
- {
- error-=dy;
-
- // move to next line
- vb_start+=x_inc;
-
- } // end if error overflowed
-
- // move to the next pixel
- vb_start+=y_inc;
-
- } // end for
-
- } // end else |slope| > 1
-
- // return success
- return(1);
-
- } // end Draw_Line
-
- ///////////////////////////////////////////////////////////
-
- int Draw_Line16(int xo, int yo, int x1,int y1, USHORT color,
- UCHAR *vb_start,int lpitch)
- {
- // this function draws a line from xo,yo to x1,y1 using differential error
- // terms (based on Bresenahams work)
-
- int dx, // difference in x's
- dy, // difference in y's
- x_inc, // amount in pixel space to move during drawing
- y_inc, // amount in pixel space to move during drawing
- error=0, // the discriminant i.e. error i.e. decision variable
- index; // used for looping
-
- // pre-compute first pixel address in video buffer
- USHORT *vb_start16 = (USHORT *)vb_start + xo + yo*(lpitch >> 1);
-
- // compute horizontal and vertical deltas
- dx = x1-xo;
- dy = y1-yo;
-
- // test which direction the line is going in i.e. slope angle
- if (dx>=0)
- {
- x_inc = 1;
-
- } // end if line is moving right
- else
- {
- x_inc = -1;
- dx = -dx; // need absolute value
-
- } // end else moving left
-
- // test y component of slope
-
- if (dy>=0)
- {
- y_inc = (lpitch >> 1);
- } // end if line is moving down
- else
- {
- y_inc = -(lpitch >> 1);
- dy = -dy; // need absolute value
-
- } // end else moving up
-
- // now based on which delta is greater we can draw the line
- if (dx>dy)
- {
- // draw the line
- for (index=0; index<=dx; index++)
- {
- // set the pixel
- *vb_start16 = color;
-
- // adjust the error term
- error+=dy;
-
- // test if error has overflowed
- if (error>dx)
- {
- error-=dx;
-
- // move to next line
- vb_start16+=y_inc;
-
-
- } // end if error overflowed
-
- // move to the next pixel
- vb_start16+=x_inc;
-
- } // end for
-
- } // end if |slope| <= 1
- else
- {
- // draw the line
- for (index=0; index<=dy; index++)
- {
- // set the pixel
- *vb_start16 = color;
-
- // adjust the error term
- error+=dx;
-
- // test if error overflowed
- if (error>0)
- {
- error-=dy;
-
- // move to next line
- vb_start16+=x_inc;
-
- } // end if error overflowed
-
- // move to the next pixel
- vb_start16+=y_inc;
-
- } // end for
-
- } // end else |slope| > 1
-
- // return success
- return(1);
-
- } // end Draw_Line16
-
-
- ///////////////////////////////////////////////////////////
-
- int Draw_Pixel(int x, int y,int color,
- UCHAR *video_buffer, int lpitch)
- {
- // this function plots a single pixel at x,y with color
-
- video_buffer[x + y*lpitch] = color;
-
- // return success
- return(1);
-
- } // end Draw_Pixel
-
-
- ///////////////////////////////////////////////////////////
-
- int Draw_Pixel16(int x, int y,int color,
- UCHAR *video_buffer, int lpitch)
- {
- // this function plots a single pixel at x,y with color
-
- ((USHORT *)video_buffer)[x + y*(lpitch>>1)] = color;
-
- // return success
- return(1);
-
- } // end Draw_Pixel16
-
- ///////////////////////////////////////////////////////////
-
- int Draw_Rectangle(int x1, int y1, int x2, int y2, int color,
- LPDIRECTDRAWSURFACE7 lpdds)
- {
- // this function uses directdraw to draw a filled rectangle
-
- DDBLTFX ddbltfx; // this contains the DDBLTFX structure
- RECT fill_area; // this contains the destination rectangle
-
- // clear out the structure and set the size field
- DD_INIT_STRUCT(ddbltfx);
-
- // set the dwfillcolor field to the desired color
- ddbltfx.dwFillColor = color;
-
- // fill in the destination rectangle data (your data)
- fill_area.top = y1;
- fill_area.left = x1;
- fill_area.bottom = y2;
- fill_area.right = x2;
-
- // ready to blt to surface, in this case blt to primary
- lpdds->Blt(&fill_area, // ptr to dest rectangle
- NULL, // ptr to source surface, NA
- NULL, // ptr to source rectangle, NA
- DDBLT_COLORFILL | DDBLT_WAIT, // fill and wait
- &ddbltfx); // ptr to DDBLTFX structure
-
- // return success
- return(1);
-
- } // end Draw_Rectangle
-
- ///////////////////////////////////////////////////////////
-
- int Set_Palette_Entry(int color_index, LPPALETTEENTRY color)
- {
- // this function sets a palette color in the palette
- lpddpal->SetEntries(0,color_index,1,color);
-
- // set data in shadow palette
- memcpy(&palette[color_index],color,sizeof(PALETTEENTRY));
-
- // return success
- return(1);
- } // end Set_Palette_Entry
-
- ///////////////////////////////////////////////////////////
-
- int Get_Palette_Entry(int color_index,LPPALETTEENTRY color)
- {
- // this function retrieves a palette entry from the color
- // palette
-
- // copy data out from shadow palette
- memcpy(color, &palette[color_index],sizeof(PALETTEENTRY));
-
- // return success
- return(1);
- } // end Get_Palette_Entry
-
- ///////////////////////////////////////////////////////////
-
- int Load_Palette_From_File(char *filename, LPPALETTEENTRY palette)
- {
- // this function loads a palette from disk into a palette
- // structure, but does not set the pallette
-
- FILE *fp_file; // working file
-
- // try and open file
- if ((fp_file = fopen(filename,"r"))==NULL)
- return(0);
-
- // read in all 256 colors RGBF
- for (int index=0; index<256; index++)
- {
- // read the next entry in
- fscanf(fp_file,"%d %d %d %d",&palette[index].peRed,
- &palette[index].peGreen,
- &palette[index].peBlue,
- &palette[index].peFlags);
- } // end for index
-
- // close the file
- fclose(fp_file);
-
- // return success
- return(1);
- } // end Load_Palette_From_Disk
-
- ///////////////////////////////////////////////////////////
-
- int Save_Palette_To_File(char *filename, LPPALETTEENTRY palette)
- {
- // this function saves a palette to disk
-
- FILE *fp_file; // working file
-
- // try and open file
- if ((fp_file = fopen(filename,"w"))==NULL)
- return(0);
-
- // write in all 256 colors RGBF
- for (int index=0; index<256; index++)
- {
- // read the next entry in
- fprintf(fp_file,"\n%d %d %d %d",palette[index].peRed,
- palette[index].peGreen,
- palette[index].peBlue,
- palette[index].peFlags);
- } // end for index
-
- // close the file
- fclose(fp_file);
-
- // return success
- return(1);
-
- } // end Save_Palette_To_Disk
-
- ///////////////////////////////////////////////////////////
-
- int Save_Palette(LPPALETTEENTRY sav_palette)
- {
- // this function saves the current palette
-
- memcpy(sav_palette, palette,256*sizeof(PALETTEENTRY));
-
- // return success
- return(1);
- } // end Save_Palette
-
- ///////////////////////////////////////////////////////////
-
- int Set_Palette(LPPALETTEENTRY set_palette)
- {
- // this function writes the sent palette
-
- // first save the new palette in shadow
- memcpy(palette, set_palette,256*sizeof(PALETTEENTRY));
-
- // now set the new palette
- lpddpal->SetEntries(0,0,256,palette);
-
- // return success
- return(1);
- } // end Set_Palette
-
- ///////////////////////////////////////////////////////////
-
- int Rotate_Colors(int start_index, int colors)
- {
- // this function rotates the color between start and end
-
- PALETTEENTRY work_pal[256]; // working palette
-
- // get the color palette
- lpddpal->GetEntries(0,start_index,colors,work_pal);
-
- // shift the colors
- lpddpal->SetEntries(0,start_index+1,colors-1,work_pal);
-
- // fix up the last color
- lpddpal->SetEntries(0,start_index,1,&work_pal[colors - 1]);
-
- // update shadow palette
- lpddpal->GetEntries(0,0,256,palette);
-
- // return sucess
- return(1);
-
- } // end Rotate_Colors
-
- ///////////////////////////////////////////////////////////
-
- int Blink_Colors(void)
- {
- // this funciton blinks a set of lights
- // not implemented
-
- // return success
- return(1);
- } // end Blink_Colors
-
- ///////////////////////////////////////////////////////////
-
- int Screen_Transition(void)
- {
- // this function performs a screen transition on the sent
- // video buffer
- // not implemented
-
-
- // return success
- return(1);
- } // end Screen_Transition
-
- ///////////////////////////////////////////////////////////
-
- int Draw_Text_GDI(char *text, int x,int y,COLORREF color, LPDIRECTDRAWSURFACE7 lpdds)
- {
- // this function draws the sent text on the sent surface
- // using color index as the color in the palette
-
- HDC xdc; // the working dc
-
- // get the dc from surface
- if (lpdds->GetDC(&xdc)!=DD_OK)
- return(0);
-
- // set the colors for the text up
- SetTextColor(xdc,color);
-
- // set background mode to transparent so black isn't copied
- SetBkMode(xdc, TRANSPARENT);
-
- // draw the text a
- TextOut(xdc,x,y,text,strlen(text));
-
- // release the dc
- lpdds->ReleaseDC(xdc);
-
- // return success
- return(1);
- } // end Draw_Text_GDI
-
- ///////////////////////////////////////////////////////////
-
- int Draw_Text_GDI(char *text, int x,int y,int color, LPDIRECTDRAWSURFACE7 lpdds)
- {
- // this function draws the sent text on the sent surface
- // using color index as the color in the palette
-
- HDC xdc; // the working dc
-
- // get the dc from surface
- if (lpdds->GetDC(&xdc)!=DD_OK)
- return(0);
-
- // set the colors for the text up
- SetTextColor(xdc,RGB(palette[color].peRed,palette[color].peGreen,palette[color].peBlue) );
-
- // set background mode to transparent so black isn't copied
- SetBkMode(xdc, TRANSPARENT);
-
- // draw the text a
- TextOut(xdc,x,y,text,strlen(text));
-
- // release the dc
- lpdds->ReleaseDC(xdc);
-
- // return success
- return(1);
- } // end Draw_Text_GDI
-
- ///////////////////////////////////////////////////////////
-
- int Open_Error_File(char *filename)
- {
- // this function opens the output error file
-
- FILE *fp_temp; // temporary file
-
- // test if this file is valid
- if ((fp_temp = fopen(filename,"w"))==NULL)
- return(0);
-
- // close old file if there was one
- if (fp_error)
- Close_Error_File();
-
- // assign new file
-
- fp_error = fp_temp;
-
- // write out header
- Write_Error("\nOpening Error Output File (%s):\n",filename);
-
- // return success
- return(1);
-
- } // end Open_Error_File
-
- ///////////////////////////////////////////////////////////
-
- int Close_Error_File(void)
- {
- // this function closes the error file
-
- if (fp_error)
- {
- // write close file string
- Write_Error("\nClosing Error Output File.");
-
- // close the file handle
- fclose(fp_error);
- fp_error = NULL;
-
- // return success
- return(1);
- } // end if
- else
- return(0);
-
- } // end Close_Error_File
-
- ///////////////////////////////////////////////////////////
-
- int Write_Error(char *string, ...)
- {
- // this function prints out the error string to the error file
-
- char buffer[80]; // working buffer
-
- va_list arglist; // variable argument list
-
- // make sure both the error file and string are valid
- if (!string || !fp_error)
- return(0);
-
- // print out the string using the variable number of arguments on stack
- va_start(arglist,string);
- vsprintf(buffer,string,arglist);
- va_end(arglist);
-
- // write string to file
- fprintf(fp_error,buffer);
-
- // return success
- return(1);
- } // end Write_Error
-
- ///////////////////////////////////////////////////////////////////////////////
-
- int Create_Bitmap(BITMAP_IMAGE_PTR image, int x, int y, int width, int height)
- {
- // this function is used to intialize a bitmap
-
- // allocate the memory
- if (!(image->buffer = (UCHAR *)malloc(width*height)))
- return(0);
-
- // initialize variables
- image->state = BITMAP_STATE_ALIVE;
- image->attr = 0;
- image->width = width;
- image->height = height;
- image->bpp = 8;
- image->x = x;
- image->y = y;
- image->num_bytes = width*height;
-
- // clear memory out
- memset(image->buffer,0,width*height);
-
- // return success
- return(1);
-
- } // end Create_Bitmap
- ///////////////////////////////////////////////////////////////////////////////
-
- int Create_Bitmap16(BITMAP_IMAGE_PTR image, int x, int y, int width, int height)
- {
- // this function is used to intialize a bitmap
-
- // allocate the memory
- if (!(image->buffer = (UCHAR *)malloc(width*height*2)))
- return(0);
-
- // initialize variables
- image->state = BITMAP_STATE_ALIVE;
- image->attr = 0;
- image->width = width;
- image->height = height;
- image->bpp = 16;
- image->x = x;
- image->y = y;
- image->num_bytes = width*height*2;
-
- // clear memory out
- memset(image->buffer,0,width*height*2);
-
- // return success
- return(1);
-
- } // end Create_Bitmap16
-
- ///////////////////////////////////////////////////////////////////////////////
-
- int Destroy_Bitmap(BITMAP_IMAGE_PTR image)
- {
- // this function releases the memory associated with a bitmap
-
- if (image && image->buffer)
- {
- // free memory and reset vars
- free(image->buffer);
-
- // set all vars in structure to 0
- memset(image,0,sizeof(BITMAP_IMAGE));
-
- // return success
- return(1);
-
- } // end if
- else // invalid entry pointer of the object wasn't initialized
- return(0);
-
- } // end Destroy_Bitmap
-
- ///////////////////////////////////////////////////////////////////////////////
-
- int Destroy_Bitmap16(BITMAP_IMAGE_PTR image)
- {
- // this function releases the memory associated with a bitmap
-
- if (image && image->buffer)
- {
- // free memory and reset vars
- free(image->buffer);
-
- // set all vars in structure to 0
- memset(image,0,sizeof(BITMAP_IMAGE));
-
- // return success
- return(1);
-
- } // end if
- else // invalid entry pointer of the object wasn't initialized
- return(0);
-
- } // end Destroy_Bitmap16
-
- ///////////////////////////////////////////////////////////
-
- int Draw_Bitmap(BITMAP_IMAGE_PTR source_bitmap,UCHAR *dest_buffer, int lpitch, int transparent)
- {
- // this function draws the bitmap onto the destination memory surface
- // if transparent is 1 then color 0 will be transparent
- // note this function does NOT clip, so be carefull!!!
-
- UCHAR *dest_addr, // starting address of bitmap in destination
- *source_addr; // starting adddress of bitmap data in source
-
- UCHAR pixel; // used to hold pixel value
-
- int index, // looping vars
- pixel_x;
-
- // test if this bitmap is loaded
-
- if (source_bitmap->attr & BITMAP_ATTR_LOADED)
- {
- // compute starting destination address
- dest_addr = dest_buffer + (int)source_bitmap->y*lpitch + (int)source_bitmap->x;
-
- // compute the starting source address
- source_addr = source_bitmap->buffer;
-
- // is this bitmap transparent
- if (transparent)
- {
- // copy each line of bitmap into destination with transparency
- for (index=0; index<source_bitmap->height; index++)
- {
- // copy the memory
- for (pixel_x=0; pixel_x<source_bitmap->width; pixel_x++)
- {
- if ((pixel = source_addr[pixel_x])!=0)
- dest_addr[pixel_x] = pixel;
-
- } // end if
-
- // advance all the pointers
- dest_addr += lpitch;
- source_addr += source_bitmap->width;
-
- } // end for index
- } // end if
- else
- {
- // non-transparent version
- // copy each line of bitmap into destination
-
- for (index=0; index<source_bitmap->height; index++)
- {
- // copy the memory
- memcpy(dest_addr, source_addr, source_bitmap->width);
-
- // advance all the pointers
- dest_addr += lpitch;
- source_addr += source_bitmap->width;
-
- } // end for index
-
- } // end else
-
- // return success
- return(1);
-
- } // end if
- else
- return(0);
-
- } // end Draw_Bitmap
-
- ///////////////////////////////////////////////////////////
-
- int Draw_Bitmap16(BITMAP_IMAGE_PTR source_bitmap,UCHAR *dest_buffer, int lpitch, int transparent)
- {
- // this function draws the bitmap onto the destination memory surface
- // if transparent is 1 then color 0 will be transparent
- // note this function does NOT clip, so be carefull!!!
-
- USHORT *dest_addr, // starting address of bitmap in destination
- *source_addr; // starting adddress of bitmap data in source
-
- USHORT pixel; // used to hold pixel value
-
- int index, // looping vars
- pixel_x;
-
- // test if this bitmap is loaded
-
- if (source_bitmap->attr & BITMAP_ATTR_LOADED)
- {
- // compute starting destination address
- dest_addr = (USHORT *)dest_buffer + (int)source_bitmap->y*(lpitch >> 1) + (int)source_bitmap->x;
-
- // compute the starting source address
- source_addr = (USHORT *)source_bitmap->buffer;
-
- // is this bitmap transparent
- if (transparent)
- {
- // copy each line of bitmap into destination with transparency
- for (index=0; index<source_bitmap->height; index++)
- {
- // copy the memory
- for (pixel_x=0; pixel_x < source_bitmap->width; pixel_x++)
- {
- if ((pixel = source_addr[pixel_x])!=0)
- dest_addr[pixel_x] = pixel;
-
- } // end if
-
- // advance all the pointers
- dest_addr += (lpitch >> 1);
- source_addr += source_bitmap->width;
-
- } // end for index
- } // end if
- else
- {
- // non-transparent version
- // copy each line of bitmap into destination
-
- for (index=0; index<source_bitmap->height; index++)
- {
- // copy the memory
- memcpy(dest_addr, source_addr, source_bitmap->width*2);
-
- // advance all the pointers
- dest_addr += (lpitch >> 1);
- source_addr += source_bitmap->width;
-
- } // end for index
-
- } // end else
-
- // return success
- return(1);
-
- } // end if
- else
- return(0);
-
- } // end Draw_Bitmap16
-
- ///////////////////////////////////////////////////////////////////////////////
-
-
- int Load_Image_Bitmap(BITMAP_IMAGE_PTR image, // bitmap image to load with data
- BITMAP_FILE_PTR bitmap, // bitmap to scan image data from
- int cx,int cy, // cell or absolute pos. to scan image from
- int mode) // if 0 then cx,cy is cell position, else
- // cx,cy are absolute coords
- {
- // this function extracts a bitmap out of a bitmap file
-
- UCHAR *source_ptr, // working pointers
- *dest_ptr;
-
- // is this a valid bob
- if (!image)
- return(0);
-
- // test the mode of extraction, cell based or absolute
- if (mode==BITMAP_EXTRACT_MODE_CELL)
- {
- // re-compute x,y
- cx = cx*(image->width+1) + 1;
- cy = cy*(image->height+1) + 1;
- } // end if
-
- // extract bitmap data
- source_ptr = bitmap->buffer +
- cy*bitmap->bitmapinfoheader.biWidth+cx;
-
- // assign a pointer to the bimap image
- dest_ptr = (UCHAR *)image->buffer;
-
- // iterate thru each scanline and copy bitmap
- for (int index_y=0; index_y < image->height; index_y++)
- {
- // copy next line of data to destination
- memcpy(dest_ptr, source_ptr,image->width);
-
- // advance pointers
- dest_ptr += image->width;
- source_ptr += bitmap->bitmapinfoheader.biWidth;
- } // end for index_y
-
- // set state to loaded
- image->attr |= BITMAP_ATTR_LOADED;
-
- // return success
- return(1);
-
- } // end Load_Image_Bitmap
-
- //////////////////////////////////////////////////////////////////
-
- int Load_Image_Bitmap16(BITMAP_IMAGE_PTR image, // bitmap image to load with data
- BITMAP_FILE_PTR bitmap, // bitmap to scan image data from
- int cx,int cy, // cell or absolute pos. to scan image from
- int mode) // if 0 then cx,cy is cell position, else
- // cx,cy are absolute coords
- {
- // this function extracts a bitmap out of a bitmap file
-
- USHORT *source_ptr, // working pointers
- *dest_ptr;
-
- // is this a valid bob
- if (!image)
- return(0);
-
- // test the mode of extraction, cell based or absolute
- if (mode==BITMAP_EXTRACT_MODE_CELL)
- {
- // re-compute x,y
- cx = cx*(image->width+1) + 1;
- cy = cy*(image->height+1) + 1;
- } // end if
-
- // extract bitmap data
- source_ptr = (USHORT *)bitmap->buffer + cy*bitmap->bitmapinfoheader.biWidth+cx;
-
- // assign a pointer to the bimap image
- dest_ptr = (USHORT *)image->buffer;
-
- // iterate thru each scanline and copy bitmap
- for (int index_y=0; index_y < image->height; index_y++)
- {
- // copy next line of data to destination
- memcpy(dest_ptr, source_ptr,image->width*2);
-
- // advance pointers
- dest_ptr += image->width;
- source_ptr += bitmap->bitmapinfoheader.biWidth;
- } // end for index_y
-
- // set state to loaded
- image->attr |= BITMAP_ATTR_LOADED;
-
- // return success
- return(1);
-
- } // end Load_Image_Bitmap16
-
- ///////////////////////////////////////////////////////////
-
- int Scroll_Bitmap(void)
- {
- // this function scrolls a bitmap
- // not implemented
-
- // return success
- return(1);
- } // end Scroll_Bitmap
- ///////////////////////////////////////////////////////////
-
- int Copy_Bitmap(void)
- {
- // this function copies a bitmap from one source to another
- // not implemented
-
-
- // return success
- return(1);
- } // end Copy_Bitmap
-
- ///////////////////////////////////////////////////////////
-
- int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename)
- {
- // this function opens a bitmap file and loads the data into bitmap
-
- int file_handle, // the file handle
- index; // looping index
-
- UCHAR *temp_buffer = NULL; // used to convert 24 bit images to 16 bit
- OFSTRUCT file_data; // the file data information
-
- // open the file if it exists
- if ((file_handle = OpenFile(filename,&file_data,OF_READ))==-1)
- return(0);
-
- // now load the bitmap file header
- _lread(file_handle, &bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));
-
- // test if this is a bitmap file
- if (bitmap->bitmapfileheader.bfType!=BITMAP_ID)
- {
- // close the file
- _lclose(file_handle);
-
- // return error
- return(0);
- } // end if
-
- // now we know this is a bitmap, so read in all the sections
-
- // first the bitmap infoheader
-
- // now load the bitmap file header
- _lread(file_handle, &bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER));
-
- // now load the color palette if there is one
- if (bitmap->bitmapinfoheader.biBitCount == 8)
- {
- _lread(file_handle, &bitmap->palette,256*sizeof(PALETTEENTRY));
-
- // now set all the flags in the palette correctly and fix the reversed
- // BGR RGBQUAD data format
- for (index=0; index < 256; index++)
- {
- // reverse the red and green fields
- int temp_color = bitmap->palette[index].peRed;
- bitmap->palette[index].peRed = bitmap->palette[index].peBlue;
- bitmap->palette[index].peBlue = temp_color;
-
- // always set the flags word to this
- bitmap->palette[index].peFlags = PC_NOCOLLAPSE;
- } // end for index
-
- } // end if
-
- // finally the image data itself
- _lseek(file_handle,-(int)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END);
-
- // now read in the image, if the image is 8 or 16 bit then simply read it
- // but if its 24 bit then read it into a temporary area and then convert
- // it to a 16 bit image
-
- if (bitmap->bitmapinfoheader.biBitCount==8 || bitmap->bitmapinfoheader.biBitCount==16)
- {
- // delete the last image if there was one
- if (bitmap->buffer)
- free(bitmap->buffer);
-
- // allocate the memory for the image
- if (!(bitmap->buffer = (UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage)))
- {
- // close the file
- _lclose(file_handle);
-
- // return error
- return(0);
- } // end if
-
- // now read it in
- _lread(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage);
-
- } // end if
- else
- {
- // this must be a 24 bit image, load it in and convert it to 16 bit
- // printf("\nconverting 24 bit image...");
-
- // allocate temporary buffer
- if (!(temp_buffer = (UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage)))
- {
- // close the file
- _lclose(file_handle);
-
- // return error
- return(0);
- } // end if
-
- // allocate final 16 bit storage buffer
- if (!(bitmap->buffer=(UCHAR *)malloc(2*bitmap->bitmapinfoheader.biWidth*bitmap->bitmapinfoheader.biHeight)))
- {
- // close the file
- _lclose(file_handle);
-
- // release working buffer
- free(temp_buffer);
-
- // return error
- return(0);
- } // end if
-
- // now read it in
- _lread(file_handle,temp_buffer,bitmap->bitmapinfoheader.biSizeImage);
-
- // now convert each 24 bit RGB value into a 16 bit value
- for (index=0; index<bitmap->bitmapinfoheader.biWidth*bitmap->bitmapinfoheader.biHeight; index++)
- {
- // extract RGB components (note they are in memory BGR)
- // also, assume 5.6.5 format, so scale appropriately
- UCHAR red = (temp_buffer[index*3 + 2] >> 3), // 5 bits
- green = (temp_buffer[index*3 + 1] >> 2), // 6 bits, change to 3 for 5 bits
- blue = (temp_buffer[index*3 + 0] >> 3); // 5 bits
-
- // build up 16 bit color word assume 5.6.5 format
- USHORT color = _RGB16BIT565(red,green,blue);
-
- // write color to buffer
- ((USHORT *)bitmap->buffer)[index] = color;
-
- } // end for index
-
- // finally write out the correct number of bits
- bitmap->bitmapinfoheader.biBitCount=16;
-
- } // end if
-
- #if 0
- // write the file info out
- printf("\nfilename:%s \nsize=%d \nwidth=%d \nheight=%d \nbitsperpixel=%d \ncolors=%d \nimpcolors=%d",
- filename,
- bitmap->bitmapinfoheader.biSizeImage,
- bitmap->bitmapinfoheader.biWidth,
- bitmap->bitmapinfoheader.biHeight,
- bitmap->bitmapinfoheader.biBitCount,
- bitmap->bitmapinfoheader.biClrUsed,
- bitmap->bitmapinfoheader.biClrImportant);
- #endif
-
- // close the file
- _lclose(file_handle);
-
- // flip the bitmap
- Flip_Bitmap(bitmap->buffer,
- bitmap->bitmapinfoheader.biWidth*(bitmap->bitmapinfoheader.biBitCount/8),
- bitmap->bitmapinfoheader.biHeight);
-
- // return success
- return(1);
-
- } // end Load_Bitmap_File
-
- ///////////////////////////////////////////////////////////
-
- int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap)
- {
- // this function releases all memory associated with "bitmap"
- if (bitmap->buffer)
- {
- // release memory
- free(bitmap->buffer);
-
- // reset pointer
- bitmap->buffer = NULL;
-
- } // end if
-
- // return success
- return(1);
-
- } // end Unload_Bitmap_File
-
- ///////////////////////////////////////////////////////////
-
- int Flip_Bitmap(UCHAR *image, int bytes_per_line, int height)
- {
- // this function is used to flip upside down .BMP images
-
- UCHAR *buffer; // used to perform the image processing
- int index; // looping index
-
- // allocate the temporary buffer
- if (!(buffer = (UCHAR *)malloc(bytes_per_line*height)))
- return(0);
-
- // copy image to work area
- memcpy(buffer,image,bytes_per_line*height);
-
- // flip vertically
- for (index=0; index < height; index++)
- memcpy(&image[((height-1) - index)*bytes_per_line],
- &buffer[index*bytes_per_line], bytes_per_line);
-
- // release the memory
- free(buffer);
-
- // return success
- return(1);
-
- } // end Flip_Bitmap
-
- ///////////////////////////////////////////////////////////
-
-