t3dlib1.cpp
资源名称:Source.rar [点击查看]
上传用户:husern
上传日期:2018-01-20
资源大小:42486k
文件大小:175k
源码类别:
游戏
开发平台:
Visual C++
- // T3DLIB1.CPP - Game Engine Part I
- // INCLUDES ///////////////////////////////////////////////
- #define WIN32_LEAN_AND_MEAN
- // has the GUID library been included?
- //#ifndef INITGUID
- //#define INITGUID
- //#endif
- #define DEBUG_ON
- #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 <sys/timeb.h>
- #include <time.h>
- #include <ddraw.h> // directX includes
- #include "T3DLIB1.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
- char error_filename[80]; // error file name
- // notice that interface 7.0 is used on a number of interfaces
- 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 for back surface
- LPDIRECTDRAWCLIPPER lpddclipperwin = NULL; // dd clipper for window
- PALETTEENTRY palette[MAX_COLORS_PALETTE]; // color palette
- PALETTEENTRY save_palette[MAX_COLORS_PALETTE]; // 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 for primary buffer
- int back_lpitch = 0; // memory line pitch for back buffer
- BITMAP_FILE bitmap8bit; // a 8 bit bitmap file
- BITMAP_FILE bitmap16bit; // a 16 bit bitmap file
- BITMAP_FILE bitmap24bit; // a 24 bit bitmap file
- DWORD start_clock_count = 0; // used for timing
- int windowed_mode = FALSE; // tracks if dd is windowed or not
- // 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 DDraw_Init()
- int screen_width = SCREEN_WIDTH, // width of screen
- screen_height = SCREEN_HEIGHT, // height of screen
- screen_bpp = SCREEN_BPP, // bits per pixel
- screen_windowed = 0; // is this a windowed app?
- int dd_pixel_format = DD_PIXEL_FORMAT565; // default pixel format
- int window_client_x0 = 0; // used to track the starting (x,y) client area for
- int window_client_y0 = 0; // for windowed mode directdraw operations
- // storage for our lookup tables
- float cos_look[361]; // 1 extra element so we can store 0-360 inclusive
- float sin_look[361];
- // function ptr to RGB16 builder
- USHORT (*RGB16Bit)(int r, int g, int b) = NULL;
- // conditionally compilation for engine stats
- int debug_total_polys_per_frame = 0;
- int debug_polys_lit_per_frame = 0;
- int debug_polys_clipped_per_frame = 0;
- int debug_polys_rendered_per_frame = 0;
- int debug_backfaces_removed_per_frame = 0;
- int debug_objects_removed_per_frame = 0;
- int debug_total_transformations_per_frame = 0;
- // FUNCTIONS //////////////////////////////////////////////
- USHORT RGB16Bit565(int r, int g, int b)
- {
- // this function simply builds a 5.6.5 format 16 bit pixel
- // assumes input is RGB 0-255 each channel
- r>>=3; g>>=2; b>>=3;
- return(_RGB16BIT565((r),(g),(b)));
- } // end RGB16Bit565
- //////////////////////////////////////////////////////////
- USHORT RGB16Bit555(int r, int g, int b)
- {
- // this function simply builds a 5.5.5 format 16 bit pixel
- // assumes input is RGB 0-255 each channel
- r>>=3; g>>=3; b>>=3;
- return(_RGB16BIT555((r),(g),(b)));
- } // end RGB16Bit555
- //////////////////////////////////////////////////////////
- #if 0
- inline void Mem_Set_WORD(void *dest, USHORT data, int count)
- {
- // this function fills or sets unsigned 16-bit aligned memory
- // count is number of words
- //Write_Error("{");
- _asm
- {
- mov edi, dest ; edi points to destination memory
- mov ecx, count ; number of 16-bit words to move
- mov ax, data ; 16-bit data
- rep stosw ; move data
- } // end asm
- //Write_Error("}");
- } // end Mem_Set_WORD
- ///////////////////////////////////////////////////////////
- inline void Mem_Set_QUAD(void *dest, UINT data, int count)
- {
- // this function fills or sets unsigned 32-bit aligned memory
- // count is number of quads
- _asm
- {
- mov edi, dest ; edi points to destination memory
- mov ecx, count ; number of 32-bit words to move
- mov eax, data ; 32-bit data
- rep stosd ; move data
- } // end asm
- } // end Mem_Set_QUAD
- #endif
- //////////////////////////////////////////////////////////
- int Create_BOB(BOB_PTR bob, // the bob to create
- int x, int y, // initial posiiton
- int width, int height, // size of bob
- int num_frames, // number of frames
- int attr, // attrs
- int mem_flags, // memory flags in DD format
- USHORT color_key_value, // default color key
- int bpp) // bits per pixel
- {
- // 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
- // for video memory you can create either local VRAM surfaces or AGP
- // surfaces via the second set of constants shown below in the regular expression
- // DDSCAPS_VIDEOMEMORY | (DDSCAPS_NONLOCALVIDMEM | DDSCAPS_LOCALVIDMEM )
- 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->bpp = bpp;
- 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;
- // 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;
- #if 0
- // make sure surface width is a multiple of 8, some old version of dd like that
- // now, it's unneeded...
- bob->width_fill = ((width%8!=0) ? (8-width%8) : 0);
- Write_Error("nCreate BOB: width_fill=%d",bob->width_fill);
- #endif
- // 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, return failure if problem
- if (FAILED(lpdd->CreateSurface(&ddsd,&(bob->images[index]),NULL)))
- return(0);
- // set color key to default color 000
- // note that if this is a 8bit bob then palette index 0 will be
- // transparent by default
- // note that if this is a 16bit bob then RGB value 000 will be
- // transparent
- DDCOLORKEY color_key; // used to set color key
- color_key.dwColorSpaceLowValue = color_key_value;
- color_key.dwColorSpaceHighValue = color_key_value;
- // 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 Clone_BOB(BOB_PTR source, BOB_PTR dest)
- {
- // this function clones a BOB and updates the attr var to reflect that
- // the BOB is a clone and not real, this is used later in the destroy
- // function so a clone doesn't destroy the memory of a real bob
- if ((source && dest) && (source!=dest))
- {
- // copy the bob data
- memcpy(dest,source, sizeof(BOB));
- // set the clone attribute
- dest->attr |= BOB_ATTR_CLONE;
- } // end if
- else
- return(0);
- // return success
- return(1);
- } // end Clone_BOB
- ///////////////////////////////////////////////////////////
- int Destroy_BOB(BOB_PTR bob)
- {
- // destroy the BOB, tests if this is a real bob or a clone
- // if real then release all the memory, otherwise, just resets
- // the pointers to null
- int index; // looping var
- // is this bob valid
- if (!bob)
- return(0);
- // test if this is a clone
- if ((bob->attr & BOB_ATTR_CLONE))
- {
- // null link all surfaces
- for (index=0; index<MAX_BOB_FRAMES; index++)
- if (bob->images[index])
- bob->images[index]=NULL;
- // release memory for animation sequences
- for (index=0; index<MAX_BOB_ANIMATIONS; index++)
- if (bob->animations[index])
- bob->animations[index]=NULL;
- } // end if
- else
- {
- // 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]);
- } // end else not clone
- // return success
- return(1);
- } // end Destroy_BOB
- ///////////////////////////////////////////////////////////
- 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 (FAILED(dest->Blt(&dest_rect, bob->images[bob->curr_frame],
- &source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
- NULL)))
- return(0);
- // return success
- return(1);
- } // end Draw_BOB
- ///////////////////////////////////////////////////////////
- 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 (FAILED(dest->Blt(&dest_rect, bob->images[bob->curr_frame],
- &source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
- NULL)))
- return(0);
- // return success
- return(1);
- } // end Draw_Scaled_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 (FAILED(dest->Blt(&dest_rect, bob->images[bob->curr_frame],
- &source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
- NULL)))
- return(0);
- // return success
- return(1);
- } // end Draw_BOB16
- ///////////////////////////////////////////////////////////
- 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 (FAILED(dest->Blt(&dest_rect, bob->images[bob->curr_frame],
- &source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
- NULL)))
- 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
- DDSURFACEDESC2 ddsd; // direct draw surface description
- // is this a valid bob
- if (!bob)
- return(0);
- UCHAR *source_ptr, // working pointers
- *dest_ptr;
- // 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 += (ddsd.lPitch); // (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 16-bit bitmap out of a 16-bit bitmap file
- DDSURFACEDESC2 ddsd; // direct draw surface description
- // is this a valid bob
- if (!bob)
- return(0);
- USHORT *source_ptr, // working pointers
- *dest_ptr;
- // 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
- // 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 Amimate_BOB
- ///////////////////////////////////////////////////////////
- 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->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;
- } // 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 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 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_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_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_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 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 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 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 DDraw_Init(int width, int height, int bpp, int windowed)
- {
- // this function initializes directdraw
- int index; // looping variable
- // create IDirectDraw interface 7.0 object and test for error
- if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL)))
- return(0);
- // based on windowed or fullscreen set coorperation level
- if (windowed)
- {
- // set cooperation level to windowed mode
- if (FAILED(lpdd->SetCooperativeLevel(main_window_handle,DDSCL_NORMAL)))
- return(0);
- } // end if
- else
- {
- // set cooperation level to fullscreen mode
- if (FAILED(lpdd->SetCooperativeLevel(main_window_handle,
- DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN |
- DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT | DDSCL_MULTITHREADED )))
- return(0);
- // set the display mode
- if (FAILED(lpdd->SetDisplayMode(width,height,bpp,0,0)))
- return(0);
- } // end else
- // set globals
- screen_height = height;
- screen_width = width;
- screen_bpp = bpp;
- screen_windowed = windowed;
- // Create the primary surface
- memset(&ddsd,0,sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- // we need to let dd know that we want a complex
- // flippable surface structure, set flags for that
- if (!screen_windowed)
- {
- // fullscreen mode
- ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
- // set the backbuffer count to 0 for windowed mode
- // 1 for fullscreen mode, 2 for triple buffering
- ddsd.dwBackBufferCount = 1;
- } // end if
- else
- {
- // windowed mode
- ddsd.dwFlags = DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
- // set the backbuffer count to 0 for windowed mode
- // 1 for fullscreen mode, 2 for triple buffering
- ddsd.dwBackBufferCount = 0;
- } // end else
- // create the primary surface
- lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL);
- // get the pixel format of the primary surface
- DDPIXELFORMAT ddpf; // used to get pixel format
- // initialize structure
- DDRAW_INIT_STRUCT(ddpf);
- // query the format from primary surface
- lpddsprimary->GetPixelFormat(&ddpf);
- // based on masks determine if system is 5.6.5 or 5.5.5
- //RGB Masks for 5.6.5 mode
- //DDPF_RGB 16 R: 0x0000F800
- // G: 0x000007E0
- // B: 0x0000001F
- //RGB Masks for 5.5.5 mode
- //DDPF_RGB 16 R: 0x00007C00
- // G: 0x000003E0
- // B: 0x0000001F
- // test for 6 bit green mask)
- //if (ddpf.dwGBitMask == 0x000007E0)
- // dd_pixel_format = DD_PIXEL_FORMAT565;
- // use number of bits, better method
- dd_pixel_format = ddpf.dwRGBBitCount;
- Write_Error("npixel format = %d",dd_pixel_format);
- // set up conversion macros, so you don't have to test which one to use
- if (dd_pixel_format == DD_PIXEL_FORMAT555)
- {
- RGB16Bit = RGB16Bit555;
- Write_Error("npixel format = 5.5.5");
- } // end if
- else
- {
- RGB16Bit = RGB16Bit565;
- Write_Error("npixel format = 5.6.5");
- } // end else
- // only need a backbuffer for fullscreen modes
- if (!screen_windowed)
- {
- // query for the backbuffer i.e the secondary surface
- ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
- if (FAILED(lpddsprimary->GetAttachedSurface(&ddscaps,&lpddsback)))
- return(0);
- } // end if
- else
- {
- // must be windowed, so create a double buffer that will be blitted
- // rather than flipped as in full screen mode
- lpddsback = DDraw_Create_Surface(width, height, DDSCAPS_SYSTEMMEMORY); // int mem_flags, USHORT color_key_flag);
- } // end else
- // create a palette only if 8bit mode
- if (screen_bpp==DD_PIXEL_FORMAT8)
- {
- // create and attach palette
- // clear all entries, defensive programming
- memset(palette,0,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));
- // load a pre-made "good" palette off disk
- Load_Palette_From_File(DEFAULT_PALETTE_FILE, palette);
- // load and attach the palette, test for windowed mode
- if (screen_windowed)
- {
- // in windowed mode, so the first 10 and last 10 entries have
- // to be slightly modified as does the call to createpalette
- // reset the peFlags bit to PC_EXPLICIT for the "windows" colors
- for (index=0; index < 10; index++)
- palette[index].peFlags = palette[index+246].peFlags = PC_EXPLICIT;
- // now create the palette object, but disable access to all 256 entries
- if (FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE,
- palette,&lpddpal,NULL)))
- return(0);
- } // end
- else
- {
- // in fullscreen mode, so simple create the palette with the default palette
- // and fill in all 256 entries
- if (FAILED(lpdd->CreatePalette(DDPCAPS_8BIT | DDPCAPS_INITIALIZE | DDPCAPS_ALLOW256,
- palette,&lpddpal,NULL)))
- return(0);
- } // end if
- // now attach the palette to the primary surface
- if (FAILED(lpddsprimary->SetPalette(lpddpal)))
- return(0);
- } // end if attach palette for 8bit mode
- // clear out both primary and secondary surfaces
- if (screen_windowed)
- {
- // only clear backbuffer
- DDraw_Fill_Surface(lpddsback,0);
- } // end if
- else
- {
- // fullscreen, simply clear everything
- DDraw_Fill_Surface(lpddsprimary,0);
- DDraw_Fill_Surface(lpddsback,0);
- } // end else
- // set software algorithmic clipping region
- min_clip_x = 0;
- max_clip_x = screen_width - 1;
- min_clip_y = 0;
- max_clip_y = screen_height - 1;
- // setup backbuffer clipper always
- RECT screen_rect = {0,0,screen_width,screen_height};
- lpddclipper = DDraw_Attach_Clipper(lpddsback,1,&screen_rect);
- // set up windowed mode clipper
- if (screen_windowed)
- {
- // set windowed clipper
- if (FAILED(lpdd->CreateClipper(0,&lpddclipperwin,NULL)))
- return(0);
- if (FAILED(lpddclipperwin->SetHWnd(0, main_window_handle)))
- return(0);
- if (FAILED(lpddsprimary->SetClipper(lpddclipperwin)))
- return(0);
- } // end if screen windowed
- // return success
- return(1);
- } // end DDraw_Init
- ///////////////////////////////////////////////////////////
- int DDraw_Shutdown(void)
- {
- // this function release all the resources directdraw
- // allocated, mainly to com objects
- // release the clippers first
- if (lpddclipper)
- lpddclipper->Release();
- if (lpddclipperwin)
- lpddclipperwin->Release();
- // release the palette if there is one
- 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 DDraw_Shutdown
- ///////////////////////////////////////////////////////////
- LPDIRECTDRAWCLIPPER DDraw_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 (FAILED(lpdd->CreateClipper(0,&lpddclipper,NULL)))
- 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 (FAILED(lpddclipper->SetClipList(region_data, 0)))
- {
- // release memory and return error
- free(region_data);
- return(NULL);
- } // end if
- // now attach the clipper to the surface
- if (FAILED(lpdds->SetClipper(lpddclipper)))
- {
- // 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 DDraw_Attach_Clipper
- ///////////////////////////////////////////////////////////
- LPDIRECTDRAWSURFACE7 DDraw_Create_Surface(int width,
- int height,
- int mem_flags,
- USHORT color_key_value)
- {
- // 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 (FAILED(lpdd->CreateSurface(&ddsd,&lpdds,NULL)))
- return(NULL);
- // set color key to default color 000
- // note that if this is a 8bit bob then palette index 0 will be
- // transparent by default
- // note that if this is a 16bit bob then RGB value 000 will be
- // transparent
- DDCOLORKEY color_key; // used to set color key
- color_key.dwColorSpaceLowValue = color_key_value;
- color_key.dwColorSpaceHighValue = color_key_value;
- // now set the color key for source blitting
- lpdds->SetColorKey(DDCKEY_SRCBLT, &color_key);
- // return surface
- return(lpdds);
- } // end DDraw_Create_Surface
- ///////////////////////////////////////////////////////////
- int DDraw_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
- if (!screen_windowed)
- while(FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT)));
- else
- {
- RECT dest_rect; // used to compute destination rectangle
- // get the window's rectangle in screen coordinates
- GetWindowRect(main_window_handle, &dest_rect);
- // compute the destination rectangle
- dest_rect.left +=window_client_x0;
- dest_rect.top +=window_client_y0;
- dest_rect.right =dest_rect.left+screen_width-1;
- dest_rect.bottom =dest_rect.top +screen_height-1;
- // clip the screen coords
- // blit the entire back surface to the primary
- if (FAILED(lpddsprimary->Blt(&dest_rect, lpddsback,NULL,DDBLT_WAIT,NULL)))
- return(0);
- } // end if
- // return success
- return(1);
- } // end DDraw_Flip
- ///////////////////////////////////////////////////////////
- int DDraw_Wait_For_Vsync(void)
- {
- // this function waits for a vertical blank to begin
- lpdd->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN,0);
- // return success
- return(1);
- } // end DDraw_Wait_For_Vsync
- ///////////////////////////////////////////////////////////
- int DDraw_Fill_Surface(LPDIRECTDRAWSURFACE7 lpdds, USHORT color, RECT *client)
- {
- DDBLTFX ddbltfx; // this contains the DDBLTFX structure
- // clear out the structure and set the size field
- DDRAW_INIT_STRUCT(ddbltfx);
- // set the dwfillcolor field to the desired color
- ddbltfx.dwFillColor = color;
- // ready to blt to surface
- lpdds->Blt(client, // 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 DDraw_Fill_Surface
- ///////////////////////////////////////////////////////////
- UCHAR *DDraw_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
- DDRAW_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 DDraw_Lock_Surface
- ///////////////////////////////////////////////////////////
- int DDraw_Unlock_Surface(LPDIRECTDRAWSURFACE7 lpdds)
- {
- // 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 DDraw_Unlock_Surface
- ///////////////////////////////////////////////////////////
- UCHAR *DDraw_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
- DDRAW_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 DDraw_Lock_Primary_Surface
- ///////////////////////////////////////////////////////////
- int DDraw_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 DDraw_Unlock_Primary_Surface
- //////////////////////////////////////////////////////////
- UCHAR *DDraw_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
- DDRAW_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 DDraw_Lock_Back_Surface
- ///////////////////////////////////////////////////////////
- int DDraw_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 DDraw_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_Line16(int x0,int y0, int x1, int y1, int color,
- UCHAR *dest_buffer, int lpitch)
- {
- // this function draws a clipped line
- 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 Draw_Clip_Line(int x0,int y0, int x1, int y1, int 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 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 x0, int y0, // starting position
- int x1, int y1, // ending position
- int color, // color index
- UCHAR *vb_start, int lpitch) // video buffer and memory pitch
- {
- // 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
- dx2, // dx,dy * 2
- dy2,
- x_inc, // amount in pixel space to move during drawing
- y_inc, // amount in pixel space to move during drawing
- error, // 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 + x0 + y0*lpitch;
- // compute horizontal and vertical deltas
- dx = x1-x0;
- dy = y1-y0;
- // 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
- // compute (dx,dy) * 2
- dx2 = dx << 1;
- dy2 = dy << 1;
- // now based on which delta is greater we can draw the line
- if (dx > dy)
- {
- // initialize error term
- error = dy2 - dx;
- // draw the line
- for (index=0; index <= dx; index++)
- {
- // set the pixel
- *vb_start = color;
- // test if error has overflowed
- if (error >= 0)
- {
- error-=dx2;
- // move to next line
- vb_start+=y_inc;
- } // end if error overflowed
- // adjust the error term
- error+=dy2;
- // move to the next pixel
- vb_start+=x_inc;
- } // end for
- } // end if |slope| <= 1
- else
- {
- // initialize error term
- error = dx2 - dy;
- // draw the line
- for (index=0; index <= dy; index++)
- {
- // set the pixel
- *vb_start = color;
- // test if error overflowed
- if (error >= 0)
- {
- error-=dy2;
- // move to next line
- vb_start+=x_inc;
- } // end if error overflowed
- // adjust the error term
- error+=dx2;
- // 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 x0, int y0, // starting position
- int x1, int y1, // ending position
- int color, // color index
- UCHAR *vb_start, int lpitch) // video buffer and memory pitch
- {
- // 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
- dx2, // dx,dy * 2
- dy2,
- x_inc, // amount in pixel space to move during drawing
- y_inc, // amount in pixel space to move during drawing
- error, // the discriminant i.e. error i.e. decision variable
- index; // used for looping
- int lpitch_2 = lpitch >> 1; // USHORT strided lpitch
- // pre-compute first pixel address in video buffer based on 16bit data
- USHORT *vb_start2 = (USHORT *)vb_start + x0 + y0*lpitch_2;
- // compute horizontal and vertical deltas
- dx = x1-x0;
- dy = y1-y0;
- // 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_2;
- } // end if line is moving down
- else
- {
- y_inc = -lpitch_2;
- dy = -dy; // need absolute value
- } // end else moving up
- // compute (dx,dy) * 2
- dx2 = dx << 1;
- dy2 = dy << 1;
- // now based on which delta is greater we can draw the line
- if (dx > dy)
- {
- // initialize error term
- error = dy2 - dx;
- // draw the line
- for (index=0; index <= dx; index++)
- {
- // set the pixel
- *vb_start2 = (USHORT)color;
- // test if error has overflowed
- if (error >= 0)
- {
- error-=dx2;
- // move to next line
- vb_start2+=y_inc;
- } // end if error overflowed
- // adjust the error term
- error+=dy2;
- // move to the next pixel
- vb_start2+=x_inc;
- } // end for
- } // end if |slope| <= 1
- else
- {
- // initialize error term
- error = dx2 - dy;
- // draw the line
- for (index=0; index <= dy; index++)
- {
- // set the pixel
- *vb_start2 = (USHORT)color;
- // test if error overflowed
- if (error >= 0)
- {
- error-=dy2;
- // move to next line
- vb_start2+=x_inc;
- } // end if error overflowed
- // adjust the error term
- error+=dx2;
- // move to the next pixel
- vb_start2+=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
- DDRAW_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<MAX_COLORS_PALETTE; 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<MAX_COLORS_PALETTE; 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,MAX_COLORS_PALETTE*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,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));
- // now set the new palette
- lpddpal->SetEntries(0,0,MAX_COLORS_PALETTE,palette);
- // return success
- return(1);
- } // end Set_Palette
- ///////////////////////////////////////////////////////////
- int Rotate_Colors(int start_index, int end_index)
- {
- // this function rotates the color between start and end
- int colors = end_index - start_index + 1;
- PALETTEENTRY work_pal[MAX_COLORS_PALETTE]; // 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,MAX_COLORS_PALETTE,palette);
- // return success
- return(1);
- } // end Rotate_Colors
- ///////////////////////////////////////////////////////////
- int Blink_Colors(int command, BLINKER_PTR new_light, int id)
- {
- // this function blinks a set of lights
- static BLINKER lights[256]; // supports up to 256 blinking lights
- static int initialized = 0; // tracks if function has initialized
- // test if this is the first time function has ran
- if (!initialized)
- {
- // set initialized
- initialized = 1;
- // clear out all structures
- memset((void *)lights,0, sizeof(lights));
- } // end if
- // now test what command user is sending
- switch (command)
- {
- case BLINKER_ADD: // add a light to the database
- {
- // run thru database and find an open light
- for (int index=0; index < 256; index++)
- {
- // is this light available?
- if (lights[index].state == 0)
- {
- // set light up
- lights[index] = *new_light;
- // set internal fields up
- lights[index].counter = 0;
- lights[index].state = -1; // off
- // update palette entry
- lpddpal->SetEntries(0,lights[index].color_index,1,&lights[index].off_color);
- // return id to caller
- return(index);
- } // end if
- } // end for index
- } break;
- case BLINKER_DELETE: // delete the light indicated by id
- {
- // delete the light sent in id
- if (lights[id].state != 0)
- {
- // kill the light
- memset((void *)&lights[id],0,sizeof(BLINKER));
- // return id
- return(id);
- } // end if
- else
- return(-1); // problem
- } break;
- case BLINKER_UPDATE: // update the light indicated by id
- {
- // make sure light is active
- if (lights[id].state != 0)
- {
- // update on/off parms only
- lights[id].on_color = new_light->on_color;
- lights[id].off_color = new_light->off_color;
- lights[id].on_time = new_light->on_time;
- lights[id].off_time = new_light->off_time;
- // update palette entry
- if (lights[id].state == -1)
- lpddpal->SetEntries(0,lights[id].color_index,1,&lights[id].off_color);
- else
- lpddpal->SetEntries(0,lights[id].color_index,1,&lights[id].on_color);
- // return id
- return(id);
- } // end if
- else
- return(-1); // problem
- } break;
- case BLINKER_RUN: // run the algorithm
- {
- // run thru database and process each light
- for (int index=0; index < 256; index++)
- {
- // is this active?
- if (lights[index].state == -1)
- {
- // update counter
- if (++lights[index].counter >= lights[index].off_time)
- {
- // reset counter
- lights[index].counter = 0;
- // change states
- lights[index].state = -lights[index].state;
- // update color
- lpddpal->SetEntries(0,lights[index].color_index,1,&lights[index].on_color);
- } // end if
- } // end if
- else
- if (lights[index].state == 1)
- {
- // update counter
- if (++lights[index].counter >= lights[index].on_time)
- {
- // reset counter
- lights[index].counter = 0;
- // change states
- lights[index].state = -lights[index].state;
- // update color
- lpddpal->SetEntries(0,lights[index].color_index,1,&lights[index].off_color);
- } // end if
- } // end else if
- } // end for index
- } break;
- default: break;
- } // end switch
- // return success
- return(1);
- } // end Blink_Colors
- ///////////////////////////////////////////////////////////
- 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 (FAILED(lpdds->GetDC(&xdc)))
- 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 (FAILED(lpdds->GetDC(&xdc)))
- 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, FILE *fp_override)
- {
- // this function creates the output error file
- // is user requesting special file handle? stdout, stderr, etc.?
- if (fp_override)
- {
- fp_error = fp_override;
- }
- else
- {
- // test if this file is valid
- if ((fp_error = fopen(filename,"w"))==NULL)
- return(0);
- }
- // get the current time
- struct _timeb timebuffer;
- char *timeline;
- char timestring[280];
- _ftime(&timebuffer);
- timeline = ctime(&(timebuffer.time));
- sprintf(timestring, "%.19s.%hu, %s", timeline, timebuffer.millitm, &timeline[20]);
- // write out error header with time
- Write_Error("nOpening Error Output File (%s) on %sn",filename,timestring);
- // now the file is created, re-open with append mode
- if (!fp_override)
- {
- fclose(fp_error);
- if ((fp_error = fopen(filename,"a+"))==NULL)
- return(0);
- }
- // 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.");
- if (fp_error!=stdout || fp_error!=stderr)
- {
- // 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[1024]; // 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);
- // flush buffer incase the system bails
- fflush(fp_error);
- // return success
- return(1);
- } // end Write_Error
- ///////////////////////////////////////////////////////////////////////////////
- int Create_Bitmap(BITMAP_IMAGE_PTR image, int x, int y, int width, int height, int bpp)
- {
- // this function is used to intialize a bitmap, 8 or 16 bit
- // allocate the memory
- if (!(image->buffer = (UCHAR *)malloc(width*height*(bpp>>3))))
- return(0);
- // initialize variables
- image->state = BITMAP_STATE_ALIVE;
- image->attr = 0;
- image->width = width;
- image->height = height;
- image->bpp = bpp;
- image->x = x;
- image->y = y;
- image->num_bytes = width*height*(bpp>>3);
- // clear memory out
- memset(image->buffer,0,width*height*(bpp>>3));
- // return success
- return(1);
- } // end Create_Bitmap
- ///////////////////////////////////////////////////////////////////////////////
- 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 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 (8bit) or 0.0.0 (16bit) will be transparent
- // note this function does NOT clip, so be carefull!!!
- // test if this bitmap is loaded
- if (!(source_bitmap->attr & BITMAP_ATTR_LOADED))
- return(0);
- 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;
- // compute starting destination address
- dest_addr = dest_buffer + source_bitmap->y*lpitch + 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 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 (8bit) or 0.0.0 (16bit) will be transparent
- // note this function does NOT clip, so be carefull!!!
- // test if this bitmap is loaded
- if (!(source_bitmap->attr & BITMAP_ATTR_LOADED))
- return(0);
- 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,
- lpitch_2 = lpitch >> 1; // lpitch in USHORT terms
- // compute starting destination address
- dest_addr = ((USHORT *)dest_buffer) + source_bitmap->y*lpitch_2 + 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_2;
- source_addr += source_bitmap->width;
- } // end for index
- } // end if
- else
- {
- // non-transparent version
- // copy each line of bitmap into destination
- int source_bytes_per_line = source_bitmap->width*2;
- for (index=0; index < source_bitmap->height; index++)
- {
- // copy the memory
- memcpy(dest_addr, source_addr, source_bytes_per_line);
- // advance all the pointers
- dest_addr += lpitch_2;
- source_addr += source_bitmap->width;
- } // end for index
- } // end else
- // return success
- return(1);
- } // 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
- // is this a valid bitmap
- if (!image)
- return(0);
- UCHAR *source_ptr, // working pointers
- *dest_ptr;
- // 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 16-bit bitmap out of a 16-bit bitmap file
- // is this a valid bitmap
- if (!image)
- return(0);
- // must be a 16bit bitmap
- USHORT *source_ptr, // working pointers
- *dest_ptr;
- // 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;
- int bytes_per_line = image->width*2;
- // 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,bytes_per_line);
- // 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(BITMAP_IMAGE_PTR image, int dx, int dy)
- {
- // this function scrolls a bitmap
- BITMAP_IMAGE temp_image; // temp image buffer
- // are the parms valid
- if (!image || (dx==0 && dy==0))
- return(0);
- // scroll on x-axis first
- if (dx!=0)
- {
- // step 1: normalize scrolling amount
- dx %= image->width;
- // step 2: which way?
- if (dx > 0)
- {
- // scroll right
- // create bitmap to hold region that is scrolled around
- Create_Bitmap(&temp_image, 0, 0, dx, image->height, image->bpp);
- // copy region we are going to scroll and wrap around
- Copy_Bitmap(&temp_image,0,0,
- image, image->width-dx,0,
- dx, image->height);
- // set some pointers up
- UCHAR *source_ptr = image->buffer; // start of each line
- int shift = (image->bpp >> 3)*dx;
- // now scroll image to right "scroll" pixels
- for (int y=0; y < image->height; y++)
- {
- // scroll the line over
- memmove(source_ptr+shift, source_ptr, (image->width-dx)*(image->bpp >> 3));
- // advance to the next line
- source_ptr+=((image->bpp >> 3)*image->width);
- } // end for
- // and now copy it back
- Copy_Bitmap(image, 0,0, &temp_image,0,0,
- dx, image->height);
- } // end if
- else
- {
- // scroll left
- dx = -dx; // invert sign
- // create bitmap to hold region that is scrolled around
- Create_Bitmap(&temp_image, 0, 0, dx, image->height, image->bpp);
- // copy region we are going to scroll and wrap around
- Copy_Bitmap(&temp_image,0,0,
- image, 0,0,
- dx, image->height);
- // set some pointers up
- UCHAR *source_ptr = image->buffer; // start of each line
- int shift = (image->bpp >> 3)*dx;
- // now scroll image to left "scroll" pixels
- for (int y=0; y < image->height; y++)
- {
- // scroll the line over
- memmove(source_ptr, source_ptr+shift, (image->width-dx)*(image->bpp >> 3));
- // advance to the next line
- source_ptr+=((image->bpp >> 3)*image->width);
- } // end for
- // and now copy it back
- Copy_Bitmap(image, image->width-dx,0, &temp_image,0,0,
- dx, image->height);
- } // end else
- } // end scroll on x-axis
- // return success
- return(1);
- } // end Scroll_Bitmap
- ///////////////////////////////////////////////////////////
- int Copy_Bitmap(BITMAP_IMAGE_PTR dest_bitmap, int dest_x, int dest_y,
- BITMAP_IMAGE_PTR source_bitmap, int source_x, int source_y,
- int width, int height)
- {
- // this function copies a bitmap from one source to another
- // make sure the pointers are at least valid
- if (!dest_bitmap || !source_bitmap)
- return(0);
- // do some computations
- int bytes_per_pixel = (source_bitmap->bpp >> 3);
- // create some pointers
- UCHAR *source_ptr = source_bitmap->buffer + (source_x + source_y*source_bitmap->width)*bytes_per_pixel;
- UCHAR *dest_ptr = dest_bitmap->buffer + (dest_x + dest_y *dest_bitmap->width) *bytes_per_pixel;
- // now copying is easy :)
- for (int y = 0; y < height; y++)
- {
- // copy this line
- memcpy(dest_ptr, source_ptr, bytes_per_pixel*width);
- // advance the pointers
- source_ptr+=(source_bitmap->width*bytes_per_pixel);
- dest_ptr +=(dest_bitmap->width*bytes_per_pixel);
- } // end for
- // 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,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));
- // now set all the flags in the palette correctly and fix the reversed
- // BGR RGBQUAD data format
- for (index=0; index < MAX_COLORS_PALETTE; 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 (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
- if (bitmap->bitmapinfoheader.biBitCount==24)
- {
- // allocate temporary buffer to load 24 bit image
- 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 the file 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++)
- {
- // build up 16 bit color word
- USHORT color;
- // build pixel based on format of directdraw surface
- if (dd_pixel_format==DD_PIXEL_FORMAT555)
- {
- // extract RGB components (in BGR order), note the scaling
- UCHAR blue = (temp_buffer[index*3 + 0] >> 3),
- green = (temp_buffer[index*3 + 1] >> 3),
- red = (temp_buffer[index*3 + 2] >> 3);
- // use the 555 macro
- color = _RGB16BIT555(red,green,blue);
- } // end if 555
- else
- if (dd_pixel_format==DD_PIXEL_FORMAT565)
- {
- // extract RGB components (in BGR order), note the scaling
- UCHAR blue = (temp_buffer[index*3 + 0] >> 3),
- green = (temp_buffer[index*3 + 1] >> 2),
- red = (temp_buffer[index*3 + 2] >> 3);
- // use the 565 macro
- color = _RGB16BIT565(red,green,blue);
- } // end if 565
- // write color to buffer
- ((USHORT *)bitmap->buffer)[index] = color;
- } // end for index