📄 t3dlib1.cpp
字号:
// 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
// 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
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////
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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -