Remove unused platform code
This commit is contained in:
parent
e5d77fbc3b
commit
86bc778f60
22 changed files with 1 additions and 27920 deletions
|
|
@ -21,11 +21,7 @@
|
|||
#define RPC_NO_WINDOWS_H
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#ifdef _WIN32_WCE
|
||||
#include "sdl12/SRB2CE/cehelp.h"
|
||||
#else
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#include "filesrch.h"
|
||||
|
|
@ -34,7 +30,7 @@
|
|||
#include "z_zone.h"
|
||||
#include "m_menu.h" // Addons_option_Onchange
|
||||
|
||||
#if (defined (_WIN32) && !defined (_WIN32_WCE)) && defined (_MSC_VER) && !defined (_XBOX)
|
||||
#if defined (_WIN32) && defined (_MSC_VER) && !defined (_XBOX)
|
||||
|
||||
#include <errno.h>
|
||||
#include <io.h>
|
||||
|
|
@ -371,76 +367,6 @@ boolean preparefilemenu(boolean samedepth, boolean replayhut)
|
|||
return false;
|
||||
}
|
||||
|
||||
#elif defined (_WIN32_WCE)
|
||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum,
|
||||
boolean completepath, int maxsearchdepth)
|
||||
{
|
||||
#ifdef __GNUC__
|
||||
//NONE?
|
||||
startpath = filename = NULL;
|
||||
wantedmd5sum = NULL;
|
||||
maxsearchdepth = 0;
|
||||
completepath = false;
|
||||
#else
|
||||
WIN32_FIND_DATA dta;
|
||||
HANDLE searchhandle = INVALID_HANDLE_VALUE;
|
||||
const wchar_t wm[4] = L"*.*";
|
||||
|
||||
//if (startpath) SetCurrentDirectory(startpath);
|
||||
if (FIL_ReadFileOK(filename))
|
||||
{
|
||||
// checkfilemd5 returns an FS_* value, either FS_FOUND or FS_MD5SUMBAD
|
||||
return checkfilemd5(filename, wantedmd5sum);
|
||||
}
|
||||
ZeroMemory(&dta,sizeof (dta));
|
||||
if (maxsearchdepth)
|
||||
searchhandle = FindFirstFile(wm,&dta);
|
||||
if (searchhandle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
do
|
||||
{
|
||||
if ((dta.cFileName[0]!='.') && (dta.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
//if (SetCurrentDirectory(dta.cFileName))
|
||||
{ // can fail if we haven't the right
|
||||
filestatus_t found;
|
||||
found = filesearch(filename,NULL,wantedmd5sum,completepath,maxsearchdepth-1);
|
||||
//SetCurrentDirectory("..");
|
||||
if (found == FS_FOUND || found == FS_MD5SUMBAD)
|
||||
{
|
||||
if (completepath)
|
||||
strcatbf(filename,(char *)dta.cFileName,"\\");
|
||||
FindClose(searchhandle);
|
||||
return found;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (FindNextFile(searchhandle,&dta)==0);
|
||||
FindClose(searchhandle);
|
||||
}
|
||||
#endif
|
||||
return FS_NOTFOUND;
|
||||
}
|
||||
|
||||
void closefilemenu(boolean validsize)
|
||||
{
|
||||
(void)validsize;
|
||||
return;
|
||||
}
|
||||
|
||||
void searchfilemenu(char *tempname)
|
||||
{
|
||||
(void)tempname;
|
||||
return;
|
||||
}
|
||||
|
||||
boolean preparefilemenu(boolean samedepth, boolean replayhut)
|
||||
{
|
||||
(void)samedepth;
|
||||
(void)replayhut;
|
||||
return false;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
filestatus_t filesearch(char *filename, const char *startpath, const UINT8 *wantedmd5sum, boolean completepath, int maxsearchdepth)
|
||||
|
|
|
|||
|
|
@ -1,148 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Portions Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file
|
||||
/// \brief SRB2 graphics stuff for NDS
|
||||
|
||||
|
||||
#include "../doomdef.h"
|
||||
#include "../command.h"
|
||||
#include "../i_video.h"
|
||||
|
||||
#include "../hardware/hw_drv.h"
|
||||
#include "../hardware/hw_main.h"
|
||||
#include "r_nds3d.h"
|
||||
|
||||
rendermode_t rendermode = render_opengl;
|
||||
|
||||
boolean highcolor = false;
|
||||
|
||||
boolean allow_fullscreen = false;
|
||||
|
||||
consvar_t cv_vidwait = {"vid_wait", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
void I_StartupGraphics(void)
|
||||
{
|
||||
vid.width = 256;
|
||||
vid.height = 192;
|
||||
vid.bpp = 1;
|
||||
vid.rowbytes = vid.width * vid.bpp;
|
||||
vid.recalc = true;
|
||||
|
||||
HWD.pfnInit = NDS3D_Init;
|
||||
HWD.pfnShutdown = NDS3D_Shutdown;
|
||||
HWD.pfnFinishUpdate = NDS3D_FinishUpdate;
|
||||
HWD.pfnDraw2DLine = NDS3D_Draw2DLine;
|
||||
HWD.pfnDrawPolygon = NDS3D_DrawPolygon;
|
||||
HWD.pfnSetBlend = NDS3D_SetBlend;
|
||||
HWD.pfnClearBuffer = NDS3D_ClearBuffer;
|
||||
HWD.pfnSetTexture = NDS3D_SetTexture;
|
||||
HWD.pfnReadRect = NDS3D_ReadRect;
|
||||
HWD.pfnGClipRect = NDS3D_GClipRect;
|
||||
HWD.pfnClearMipMapCache = NDS3D_ClearMipMapCache;
|
||||
HWD.pfnSetSpecialState = NDS3D_SetSpecialState;
|
||||
HWD.pfnSetPalette = NDS3D_SetPalette;
|
||||
HWD.pfnGetTextureUsed = NDS3D_GetTextureUsed;
|
||||
HWD.pfnDrawMD2 = NDS3D_DrawMD2;
|
||||
HWD.pfnDrawMD2i = NDS3D_DrawMD2i;
|
||||
HWD.pfnSetTransform = NDS3D_SetTransform;
|
||||
HWD.pfnGetRenderVersion = NDS3D_GetRenderVersion;
|
||||
|
||||
videoSetMode(MODE_0_3D);
|
||||
vramSetBankA(VRAM_A_TEXTURE);
|
||||
vramSetBankB(VRAM_B_TEXTURE);
|
||||
vramSetBankC(VRAM_C_TEXTURE);
|
||||
vramSetBankD(VRAM_D_TEXTURE);
|
||||
vramSetBankE(VRAM_E_TEX_PALETTE);
|
||||
|
||||
glInit();
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glClearColor(16,16,16,31);
|
||||
glClearPolyID(63);
|
||||
glClearDepth(0x7FFF);
|
||||
|
||||
glViewport(0, 0, vid.width - 1, vid.height - 1);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
gluPerspective(fov, ASPECT_RATIO, NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glScalef(1.0f, 1.0f, -1.0f);
|
||||
|
||||
HWD.pfnInit(I_Error);
|
||||
HWR_Startup();
|
||||
}
|
||||
|
||||
void I_ShutdownGraphics(void){}
|
||||
|
||||
void I_SetPalette(RGBA_t *palette)
|
||||
{
|
||||
(void)palette;
|
||||
}
|
||||
|
||||
INT32 VID_NumModes(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT32 VID_GetModeForSize(INT32 w, INT32 h)
|
||||
{
|
||||
(void)w;
|
||||
(void)h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void VID_PrepareModeList(void){}
|
||||
|
||||
INT32 VID_SetMode(INT32 modenum)
|
||||
{
|
||||
(void)modenum;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *VID_GetModeName(INT32 modenum)
|
||||
{
|
||||
(void)modenum;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void I_UpdateNoBlit(void){}
|
||||
|
||||
void I_FinishUpdate(void)
|
||||
{
|
||||
HWD.pfnFinishUpdate(true);
|
||||
}
|
||||
|
||||
void I_UpdateNoVsync(void) {}
|
||||
|
||||
void I_WaitVBL(INT32 count)
|
||||
{
|
||||
(void)count;
|
||||
}
|
||||
|
||||
void I_ReadScreen(UINT8 *scr)
|
||||
{
|
||||
(void)scr;
|
||||
}
|
||||
|
||||
void I_BeginRead(void){}
|
||||
|
||||
void I_EndRead(void){}
|
||||
|
|
@ -1,389 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Portions Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file
|
||||
/// \brief NDS 3D API for SRB2.
|
||||
//
|
||||
// In an ideal world, we would share as much code as possible with r_opengl.c,
|
||||
// but this will do for now.
|
||||
|
||||
#include "../doomtype.h"
|
||||
#include "../hardware/hw_defs.h"
|
||||
#include "../hardware/hw_dll.h"
|
||||
#include "../hardware/hw_md2.h"
|
||||
#include "r_nds3d.h"
|
||||
|
||||
static I_Error_t I_Error_GL = NULL;
|
||||
|
||||
#define NOTEXTURE_NUM 0 // small white texture
|
||||
#define FIRST_TEX_AVAIL (NOTEXTURE_NUM + 1)
|
||||
#define MAX_SRB2_TEXTURES 256
|
||||
|
||||
FCOORD NEAR_CLIPPING_PLANE = 0.9f;
|
||||
float fov = 90.0f;
|
||||
|
||||
static FBITFIELD CurrentPolyFlags = 0xFFFFFFFF;
|
||||
static UINT32 CurrentGLPolyFmt = POLY_CULL_NONE;
|
||||
static UINT8 CurrentPolyAlpha = 31;
|
||||
static UINT16 myPaletteData[256];
|
||||
static FTextureInfo* gr_cachetail = NULL;
|
||||
static FTextureInfo* gr_cachehead = NULL;
|
||||
static INT32 NextTexAvail = FIRST_TEX_AVAIL;
|
||||
static UINT32 tex_downloaded = 0;
|
||||
static INT32 texids[MAX_SRB2_TEXTURES];
|
||||
static boolean scalehack = false;
|
||||
|
||||
|
||||
static void GenerateTextureNames(void)
|
||||
{
|
||||
glGenTextures(MAX_SRB2_TEXTURES - 1, texids + 1);
|
||||
texids[NOTEXTURE_NUM] = 0;
|
||||
}
|
||||
|
||||
static void Flush(void)
|
||||
{
|
||||
// Delete all textures at once, since libnds's glDeleteTextures seems to be buggy.
|
||||
glResetTextures();
|
||||
GenerateTextureNames();
|
||||
while (gr_cachehead)
|
||||
{
|
||||
gr_cachehead->downloaded = 0;
|
||||
gr_cachehead = gr_cachehead->nextmipmap;
|
||||
}
|
||||
gr_cachetail = gr_cachehead = NULL;
|
||||
NextTexAvail = FIRST_TEX_AVAIL;
|
||||
tex_downloaded = 0;
|
||||
}
|
||||
|
||||
static void SetNoTexture(void)
|
||||
{
|
||||
// Set small white texture.
|
||||
if (tex_downloaded != NOTEXTURE_NUM)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, texids[NOTEXTURE_NUM]);
|
||||
tex_downloaded = NOTEXTURE_NUM;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void SetAlpha(UINT8 alpha)
|
||||
{
|
||||
CurrentPolyAlpha = alpha >> 3;
|
||||
glPolyFmt(CurrentGLPolyFmt | POLY_ALPHA(CurrentPolyAlpha));
|
||||
}
|
||||
|
||||
|
||||
|
||||
boolean NDS3D_Init(I_Error_t ErrorFunction)
|
||||
{
|
||||
I_Error_GL = ErrorFunction;
|
||||
glPolyFmt(CurrentGLPolyFmt | POLY_ALPHA(CurrentPolyAlpha));
|
||||
GenerateTextureNames();
|
||||
return true;
|
||||
}
|
||||
|
||||
void NDS3D_Shutdown(void) {}
|
||||
|
||||
void NDS3D_SetPalette(RGBA_t *ppal, RGBA_t *pgamma)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
UINT8 red = (UINT8)min((ppal[i].s.red*pgamma->s.red)/127, 255) >> 3;
|
||||
UINT8 green = (UINT8)min((ppal[i].s.green*pgamma->s.green)/127, 255) >> 3;
|
||||
UINT8 blue = (UINT8)min((ppal[i].s.blue*pgamma->s.blue)/127, 255) >> 3;
|
||||
|
||||
myPaletteData[i] = ARGB16(ppal[i].s.alpha ? 1 : 0, red, green, blue);
|
||||
}
|
||||
|
||||
Flush();
|
||||
}
|
||||
|
||||
void NDS3D_FinishUpdate(INT32 waitvbl)
|
||||
{
|
||||
(void)waitvbl;
|
||||
|
||||
glFlush(0);
|
||||
}
|
||||
|
||||
void NDS3D_Draw2DLine(F2DCoord *v1, F2DCoord *v2, RGBA_t Color)
|
||||
{
|
||||
(void)v1;
|
||||
(void)v2;
|
||||
(void)Color;
|
||||
}
|
||||
|
||||
void NDS3D_DrawPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags)
|
||||
{
|
||||
FUINT i;
|
||||
|
||||
NDS3D_SetBlend(PolyFlags);
|
||||
|
||||
// If Modulated, mix the surface colour to the texture
|
||||
if ((CurrentPolyFlags & PF_Modulated) && pSurf)
|
||||
{
|
||||
glColor3b(pSurf->FlatColor.s.red, pSurf->FlatColor.s.green, pSurf->FlatColor.s.blue);
|
||||
SetAlpha(pSurf->FlatColor.s.alpha);
|
||||
}
|
||||
|
||||
// libnds doesn't have GL_TRIANGLE_FAN, so use GL_TRIANGLE_STRIP instead
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
for (i = 0; i < iNumPts; i++)
|
||||
{
|
||||
FUINT index = (i & 1) ? (i >> 1) : (iNumPts - 1 - (i >> 1));
|
||||
FLOAT x, y, z;
|
||||
|
||||
if (scalehack)
|
||||
{
|
||||
x = pOutVerts[index].x/4096.0f;
|
||||
y = pOutVerts[index].y/4096.0f;
|
||||
z = pOutVerts[index].z/4096.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = pOutVerts[index].x;
|
||||
y = pOutVerts[index].y;
|
||||
z = pOutVerts[index].z;
|
||||
}
|
||||
|
||||
glTexCoord2f(pOutVerts[index].s, pOutVerts[index].tow);
|
||||
glVertex3f(x,y,z);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void NDS3D_SetBlend(FBITFIELD PolyFlags)
|
||||
{
|
||||
FBITFIELD Xor = PolyFlags ^ CurrentPolyFlags;
|
||||
|
||||
if (Xor & (PF_NoTexture|PF_Modulated))
|
||||
{
|
||||
if (Xor&PF_Modulated)
|
||||
{
|
||||
if(!(PolyFlags & PF_Modulated))
|
||||
{
|
||||
glColor3b(255, 255, 255);
|
||||
CurrentPolyAlpha = 31;
|
||||
}
|
||||
}
|
||||
|
||||
if (PolyFlags & PF_NoTexture)
|
||||
{
|
||||
SetNoTexture();
|
||||
}
|
||||
}
|
||||
|
||||
CurrentPolyFlags = PolyFlags;
|
||||
glPolyFmt(CurrentGLPolyFmt | POLY_ALPHA(CurrentPolyAlpha));
|
||||
}
|
||||
|
||||
void NDS3D_ClearBuffer(FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor)
|
||||
{
|
||||
(void)ClearColor;
|
||||
|
||||
if (ColorMask && ClearColor)
|
||||
{
|
||||
// TODO: Fixed-ify
|
||||
glClearColor((uint8)(ClearColor->red*31),
|
||||
(uint8)(ClearColor->green*31),
|
||||
(uint8)(ClearColor->blue*31),
|
||||
(uint8)(ClearColor->alpha*31));
|
||||
}
|
||||
|
||||
if (DepthMask)
|
||||
glClearDepth(GL_MAX_DEPTH);
|
||||
|
||||
NDS3D_SetBlend(DepthMask ? PF_Occlude | CurrentPolyFlags : CurrentPolyFlags&~PF_Occlude);
|
||||
}
|
||||
|
||||
void NDS3D_SetTexture(FTextureInfo *TexInfo)
|
||||
{
|
||||
if (!TexInfo)
|
||||
{
|
||||
SetNoTexture();
|
||||
return;
|
||||
}
|
||||
else if (TexInfo->downloaded)
|
||||
{
|
||||
if (TexInfo->downloaded != tex_downloaded)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, texids[TexInfo->downloaded]);
|
||||
tex_downloaded = TexInfo->downloaded;
|
||||
}
|
||||
}
|
||||
else if (TexInfo->grInfo.data)
|
||||
{
|
||||
UINT8 wtype, htype;
|
||||
INT32 texparam = GL_TEXTURE_COLOR0_TRANSPARENT;
|
||||
|
||||
// We rely on the numerical values of GL_TEXTURE_SIZE_ENUM here.
|
||||
wtype = TEXTURE_SIZE_8;
|
||||
while(TexInfo->width > 1 << (wtype + 3)) wtype++;
|
||||
|
||||
htype = TEXTURE_SIZE_8;
|
||||
while(TexInfo->height > 1 << (htype + 3)) htype++;
|
||||
|
||||
TexInfo->downloaded = NextTexAvail++;
|
||||
tex_downloaded = TexInfo->downloaded;
|
||||
glBindTexture(GL_TEXTURE_2D, texids[TexInfo->downloaded]);
|
||||
|
||||
if(!glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB256, wtype, htype, 0, TEXGEN_TEXCOORD, TexInfo->grInfo.data))
|
||||
{
|
||||
// HACK: If we're out of memory, flush and try again.
|
||||
// This will result in artefacts for one frame.
|
||||
Flush();
|
||||
TexInfo->downloaded = 0;
|
||||
NDS3D_SetTexture(TexInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
if (TexInfo->downloaded > FIRST_TEX_AVAIL)
|
||||
{
|
||||
// We already have a texture using the palette, so it's already in VRAM
|
||||
glAssignColorTable(GL_TEXTURE_2D, texids[FIRST_TEX_AVAIL]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Generate the palette in hardware
|
||||
glColorTableEXT(0, 0, 256, 0, 0, myPaletteData);
|
||||
}
|
||||
|
||||
if (TexInfo->flags & TF_WRAPX)
|
||||
texparam |= GL_TEXTURE_WRAP_S;
|
||||
|
||||
if (TexInfo->flags & TF_WRAPY)
|
||||
texparam |= GL_TEXTURE_WRAP_T;
|
||||
|
||||
glTexParameter(0, texparam);
|
||||
|
||||
TexInfo->nextmipmap = NULL;
|
||||
if (gr_cachetail)
|
||||
{
|
||||
gr_cachetail->nextmipmap = TexInfo;
|
||||
gr_cachetail = TexInfo;
|
||||
}
|
||||
else
|
||||
gr_cachetail = gr_cachehead = TexInfo;
|
||||
}
|
||||
}
|
||||
|
||||
void NDS3D_ReadRect(INT32 x, INT32 y, INT32 width, INT32 height, INT32 dst_stride, UINT16 *dst_data)
|
||||
{
|
||||
(void)x;
|
||||
(void)y;
|
||||
(void)width;
|
||||
(void)height;
|
||||
(void)dst_stride;
|
||||
(void)dst_data;
|
||||
}
|
||||
|
||||
void NDS3D_GClipRect(INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip)
|
||||
{
|
||||
(void)minx;
|
||||
(void)miny;
|
||||
(void)maxx;
|
||||
(void)maxy;
|
||||
//glViewport(minx, vid.height-maxy, maxx-minx, maxy-miny);
|
||||
NEAR_CLIPPING_PLANE = nearclip;
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(fov, ASPECT_RATIO, NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
void NDS3D_ClearMipMapCache(void) {}
|
||||
|
||||
void NDS3D_SetSpecialState(hwdspecialstate_t IdState, INT32 Value)
|
||||
{
|
||||
(void)IdState;
|
||||
(void)Value;
|
||||
}
|
||||
|
||||
void NDS3D_DrawMD2(INT32 *gl_cmd_buffer, md2_frame_t *frame, FTransform *pos, float scale)
|
||||
{
|
||||
(void)gl_cmd_buffer;
|
||||
(void)frame;
|
||||
(void)pos;
|
||||
(void)scale;
|
||||
}
|
||||
|
||||
void NDS3D_DrawMD2i(INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 duration, UINT32 tics, md2_frame_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color)
|
||||
{
|
||||
(void)gl_cmd_buffer;
|
||||
(void)frame;
|
||||
(void)duration;
|
||||
(void)tics;
|
||||
(void)nextframe;
|
||||
(void)pos;
|
||||
(void)scale;
|
||||
(void)flipped;
|
||||
(void)color;
|
||||
}
|
||||
|
||||
void NDS3D_SetTransform(FTransform *ptransform)
|
||||
{
|
||||
static INT32 special_splitscreen;
|
||||
glLoadIdentity();
|
||||
if (ptransform)
|
||||
{
|
||||
scalehack = true;
|
||||
|
||||
glScalef(ptransform->scalex*4096.0f, ptransform->scaley*4096.0f, -ptransform->scalez*4096.0f);
|
||||
glRotatef(ptransform->anglex , 1.0f, 0.0f, 0.0f);
|
||||
glRotatef(ptransform->angley+270.0f, 0.0f, 1.0f, 0.0f);
|
||||
glTranslatef(-ptransform->x/4096.0f, -ptransform->z/4096.0f, -ptransform->y/4096.0f);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
special_splitscreen = (ptransform->splitscreen && ptransform->fovxangle == 90.0f);
|
||||
if (special_splitscreen)
|
||||
gluPerspective(53.13l, 2*ASPECT_RATIO, // 53.13 = 2*atan(0.5)
|
||||
NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE);
|
||||
else
|
||||
gluPerspective(ptransform->fovxangle, ASPECT_RATIO, NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
else
|
||||
{
|
||||
scalehack = false;
|
||||
|
||||
glScalef(1.0f, 1.0f, -1.0f);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
if (special_splitscreen)
|
||||
gluPerspective(53.13l, 2*ASPECT_RATIO, // 53.13 = 2*atan(0.5)
|
||||
NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE);
|
||||
else
|
||||
//Hurdler: is "fov" correct?
|
||||
gluPerspective(fov, ASPECT_RATIO, NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
}
|
||||
|
||||
INT32 NDS3D_GetTextureUsed(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT32 NDS3D_GetRenderVersion(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Binary file not shown.
|
Before Width: | Height: | Size: 99 KiB |
|
|
@ -1,147 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
/// \file
|
||||
/// \brief Tool for dynamic referencing of hardware rendering functions
|
||||
///
|
||||
/// Declaration and definition of the HW rendering
|
||||
/// functions do have the same name. Originally, the
|
||||
/// implementation was stored in a separate library.
|
||||
/// For SDL, we need some function to return the addresses,
|
||||
/// otherwise we have a conflict with the compiler.
|
||||
|
||||
#include "hwsym_sdl.h"
|
||||
#include "../doomdef.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4214 4244)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SDL
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(default : 4214 4244)
|
||||
#endif
|
||||
|
||||
#if defined (_XBOX) || defined (_arch_dreamcast) || defined(GP2X)
|
||||
#define NOLOADSO
|
||||
#endif
|
||||
|
||||
#if SDL_VERSION_ATLEAST(1,2,6) && !defined (NOLOADSO)
|
||||
#include "SDL_loadso.h" // 1.2.6+
|
||||
#elif !defined (NOLOADSO)
|
||||
#define NOLOADSO
|
||||
#endif
|
||||
|
||||
#define _CREATE_DLL_ // necessary for Unix AND Windows
|
||||
|
||||
#ifdef HW3SOUND
|
||||
#include "../hardware/hw3dsdrv.h"
|
||||
#endif
|
||||
|
||||
#define GETFUNC(func) \
|
||||
else if (0 == strcmp(#func, funcName)) \
|
||||
funcPointer = &func \
|
||||
//
|
||||
//
|
||||
/** \brief The *hwSym function
|
||||
|
||||
Stupid function to return function addresses
|
||||
|
||||
\param funcName the name of the function
|
||||
\param handle an object to look in(NULL for self)
|
||||
|
||||
\return void
|
||||
*/
|
||||
//
|
||||
void *hwSym(const char *funcName,void *handle)
|
||||
{
|
||||
void *funcPointer = NULL;
|
||||
if (0 == strcmp("FinishUpdate", funcName))
|
||||
return funcPointer; //&FinishUpdate;
|
||||
#ifdef STATIC3DS
|
||||
GETFUNC(Startup);
|
||||
GETFUNC(AddSfx);
|
||||
GETFUNC(AddSource);
|
||||
GETFUNC(StartSource);
|
||||
GETFUNC(StopSource);
|
||||
GETFUNC(GetHW3DSVersion);
|
||||
GETFUNC(BeginFrameUpdate);
|
||||
GETFUNC(EndFrameUpdate);
|
||||
GETFUNC(IsPlaying);
|
||||
GETFUNC(UpdateListener);
|
||||
GETFUNC(UpdateSourceParms);
|
||||
GETFUNC(SetGlobalSfxVolume);
|
||||
GETFUNC(SetCone);
|
||||
GETFUNC(Update3DSource);
|
||||
GETFUNC(ReloadSource);
|
||||
GETFUNC(KillSource);
|
||||
GETFUNC(Shutdown);
|
||||
GETFUNC(GetHW3DSTitle);
|
||||
#endif
|
||||
#ifdef NOLOADSO
|
||||
else
|
||||
funcPointer = handle;
|
||||
#else
|
||||
else if (handle)
|
||||
funcPointer = SDL_LoadFunction(handle,funcName);
|
||||
#endif
|
||||
if (!funcPointer)
|
||||
I_OutputMsg("hwSym for %s: %s\n", funcName, SDL_GetError());
|
||||
return funcPointer;
|
||||
}
|
||||
|
||||
/** \brief The *hwOpen function
|
||||
|
||||
\param hwfile Open a handle to the SO
|
||||
|
||||
\return Handle to SO
|
||||
|
||||
|
||||
*/
|
||||
|
||||
void *hwOpen(const char *hwfile)
|
||||
{
|
||||
#ifdef NOLOADSO
|
||||
(void)hwfile;
|
||||
return NULL;
|
||||
#else
|
||||
void *tempso = NULL;
|
||||
tempso = SDL_LoadObject(hwfile);
|
||||
if (!tempso) I_OutputMsg("hwOpen of %s: %s\n", hwfile, SDL_GetError());
|
||||
return tempso;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief The hwClose function
|
||||
|
||||
\param handle Close the handle of the SO
|
||||
|
||||
\return void
|
||||
|
||||
|
||||
*/
|
||||
|
||||
void hwClose(void *handle)
|
||||
{
|
||||
#ifdef NOLOADSO
|
||||
(void)handle;
|
||||
#else
|
||||
SDL_UnloadObject(handle);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,221 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file
|
||||
/// \brief Main program, simply calls D_SRB2Main and D_SRB2Loop, the high level loop.
|
||||
|
||||
#include "../doomdef.h"
|
||||
#include "../m_argv.h"
|
||||
#include "../d_main.h"
|
||||
#include "../i_system.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WII
|
||||
#include <limits.h>
|
||||
#include <network.h>
|
||||
#include <fat.h>
|
||||
#ifdef REMOTE_DEBUGGING
|
||||
#include <debug.h>
|
||||
#endif
|
||||
static char wiicwd[PATH_MAX] = "sd:/";
|
||||
static char localip[16] = {0};
|
||||
static char gateway[16] = {0};
|
||||
static char netmask[16] = {0};
|
||||
#endif
|
||||
|
||||
#ifdef _PSP
|
||||
#include <pspmoduleinfo.h>
|
||||
#include <pspthreadman.h>
|
||||
PSP_HEAP_SIZE_KB(24*1024);
|
||||
PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER | PSP_THREAD_ATTR_VFPU);
|
||||
PSP_MAIN_THREAD_NAME("SRB2Kart");
|
||||
PSP_MAIN_THREAD_STACK_SIZE_KB(256);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SDL
|
||||
|
||||
#ifdef HAVE_TTF
|
||||
#include <SDL.h>
|
||||
#include "i_ttf.h"
|
||||
#endif
|
||||
|
||||
#ifdef SDLMAIN
|
||||
#include "SDL_main.h"
|
||||
#elif defined(FORCESDLMAIN)
|
||||
extern int SDL_main(int argc, char *argv[]);
|
||||
#endif
|
||||
|
||||
#ifdef LOGMESSAGES
|
||||
FILE *logstream = NULL;
|
||||
#endif
|
||||
|
||||
#ifndef DOXYGEN
|
||||
#ifndef O_TEXT
|
||||
#define O_TEXT 0
|
||||
#endif
|
||||
|
||||
#ifndef O_SEQUENTIAL
|
||||
#define O_SEQUENTIAL 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined (_WIN32) && !defined (_XBOX)
|
||||
#include "../win32/win_dbg.h"
|
||||
typedef BOOL (WINAPI *p_IsDebuggerPresent)(VOID);
|
||||
#endif
|
||||
|
||||
#ifdef _arch_dreamcast
|
||||
#include <arch/arch.h>
|
||||
KOS_INIT_FLAGS(INIT_DEFAULT
|
||||
//| INIT_NET
|
||||
//| INIT_MALLOCSTATS
|
||||
//| INIT_QUIET
|
||||
//| INIT_OCRAM
|
||||
//| INIT_NO_DCLOAD
|
||||
);
|
||||
#endif
|
||||
|
||||
#if defined (_WIN32) && !defined (_XBOX) && !defined (_WIN32_WCE)
|
||||
static inline VOID MakeCodeWritable(VOID)
|
||||
{
|
||||
;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief The main function
|
||||
|
||||
\param argc number of arg
|
||||
\param *argv string table
|
||||
|
||||
\return int
|
||||
*/
|
||||
FUNCNORETURN
|
||||
#if defined (_XBOX) && defined (__GNUC__)
|
||||
void XBoxStartup()
|
||||
{
|
||||
const char *logdir = NULL;
|
||||
myargc = -1;
|
||||
myargv = NULL;
|
||||
#else
|
||||
#ifdef FORCESDLMAIN
|
||||
int SDL_main(int argc, char **argv)
|
||||
#else
|
||||
int main(int argc, char **argv)
|
||||
#endif
|
||||
{
|
||||
const char *logdir = NULL;
|
||||
myargc = argc;
|
||||
myargv = argv; /// \todo pull out path to exe from this string
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TTF
|
||||
#ifdef _PS3
|
||||
// apparently there is a bug in SDL_PSL1GHT which needs this to be set to work around
|
||||
SDL_setenv("SDL_VIDEODRIVER", "psl1ght", 1);
|
||||
I_StartupTTF(FONTPOINTSIZE, SDL_INIT_VIDEO, SDL_SWSURFACE|SDL_DOUBLEBUF);
|
||||
#elif defined(_WIN32)
|
||||
I_StartupTTF(FONTPOINTSIZE, SDL_INIT_VIDEO|SDL_INIT_AUDIO, SDL_SWSURFACE);
|
||||
#else
|
||||
I_StartupTTF(FONTPOINTSIZE, SDL_INIT_VIDEO, SDL_SWSURFACE);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _PS3
|
||||
// initialise controllers.
|
||||
//ioPadInit(7);
|
||||
#endif
|
||||
|
||||
// init Wii-specific stuff
|
||||
#ifdef _WII
|
||||
// Start network
|
||||
if_config(localip, netmask, gateway, TRUE);
|
||||
|
||||
#ifdef REMOTE_DEBUGGING
|
||||
#if REMOTE_DEBUGGING == 0
|
||||
DEBUG_Init(GDBSTUB_DEVICE_TCP, GDBSTUB_DEF_TCPPORT); // Port 2828
|
||||
#elif REMOTE_DEBUGGING > 2
|
||||
DEBUG_Init(GDBSTUB_DEVICE_TCP, REMOTE_DEBUGGING); // Custom Port
|
||||
#elif REMOTE_DEBUGGING < 0
|
||||
DEBUG_Init(GDBSTUB_DEVICE_USB, GDBSTUB_DEF_CHANNEL); // Slot 1
|
||||
#else
|
||||
DEBUG_Init(GDBSTUB_DEVICE_USB, REMOTE_DEBUGGING-1); // Custom Slot
|
||||
#endif
|
||||
#endif
|
||||
// Start FAT filesystem
|
||||
fatInitDefault();
|
||||
|
||||
if (getcwd(wiicwd, PATH_MAX))
|
||||
I_PutEnv(va("HOME=%ssrb2wii", wiicwd));
|
||||
#endif
|
||||
|
||||
logdir = D_Home();
|
||||
|
||||
#ifdef LOGMESSAGES
|
||||
#if defined(_WIN32_WCE) || defined(GP2X)
|
||||
logstream = fopen(va("%s.log",argv[0]), "a");
|
||||
#elif defined (_WII)
|
||||
logstream = fopen(va("%s/srb2log.txt",logdir), "a");
|
||||
#elif defined (DEFAULTDIR)
|
||||
if (logdir)
|
||||
logstream = fopen(va("%s/"DEFAULTDIR"/srb2log.txt",logdir), "a");
|
||||
else
|
||||
#endif
|
||||
logstream = fopen("./srb2log.txt", "a");
|
||||
#endif
|
||||
|
||||
//I_OutputMsg("I_StartupSystem() ...\n");
|
||||
I_StartupSystem();
|
||||
#if defined (_WIN32) && !defined (_XBOX)
|
||||
#ifndef _WIN32_WCE
|
||||
{
|
||||
p_IsDebuggerPresent pfnIsDebuggerPresent = (p_IsDebuggerPresent)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsDebuggerPresent");
|
||||
if ((!pfnIsDebuggerPresent || !pfnIsDebuggerPresent())
|
||||
#ifdef BUGTRAP
|
||||
&& !InitBugTrap()
|
||||
#endif
|
||||
)
|
||||
{
|
||||
LoadLibraryA("exchndl.dll");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
prevExceptionFilter = SetUnhandledExceptionFilter(RecordExceptionInfo);
|
||||
#ifndef _WIN32_WCE
|
||||
MakeCodeWritable();
|
||||
#endif
|
||||
#endif
|
||||
// startup SRB2
|
||||
CONS_Printf("%s", M_GetText("Setting up SRB2Kart...\n"));
|
||||
D_SRB2Main();
|
||||
CONS_Printf("%s", M_GetText("Entering main game loop...\n"));
|
||||
// never return
|
||||
D_SRB2Loop();
|
||||
|
||||
#ifdef BUGTRAP
|
||||
// This is safe even if BT didn't start.
|
||||
ShutdownBugTrap();
|
||||
#endif
|
||||
|
||||
// return to OS
|
||||
#ifndef __GNUC__
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
3759
src/sdl12/i_system.c
3759
src/sdl12/i_system.c
File diff suppressed because it is too large
Load diff
1984
src/sdl12/i_video.c
1984
src/sdl12/i_video.c
File diff suppressed because it is too large
Load diff
Binary file not shown.
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
Binary file not shown.
|
Before Width: | Height: | Size: 122 KiB |
|
|
@ -1,629 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file
|
||||
/// \brief Sources from GameDeveloper magazine article, January 1998, by Bruce Dawson.
|
||||
/// this source file contains the exception handler for recording error
|
||||
/// information after crashes.
|
||||
|
||||
#include <tchar.h>
|
||||
#include "win_main.h"
|
||||
#include "../doomdef.h" //just for VERSION
|
||||
#include "win_dbg.h"
|
||||
#include "../m_argv.h" //print the parameter in the log
|
||||
|
||||
|
||||
#define NumCodeBytes 16 // Number of code bytes to record.
|
||||
#define MaxStackDump 2048 // Maximum number of DWORDS in stack dumps.
|
||||
#define StackColumns 8 // Number of columns in stack dump.
|
||||
|
||||
#define ONEK 1024
|
||||
#define SIXTYFOURK (64*ONEK)
|
||||
#define ONEM (ONEK*ONEK)
|
||||
#define ONEG (ONEK*ONEK*ONEK)
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// return a description for an ExceptionCode
|
||||
// --------------------------------------------------------------------------
|
||||
static LPCSTR GetExceptionDescription (DWORD ExceptionCode)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
struct ExceptionNames
|
||||
{
|
||||
DWORD ExceptionCode;
|
||||
LPCSTR ExceptionName;
|
||||
};
|
||||
|
||||
struct ExceptionNames ExceptionMap[] =
|
||||
{
|
||||
{EXCEPTION_ACCESS_VIOLATION, "an Access Violation"},
|
||||
{EXCEPTION_ARRAY_BOUNDS_EXCEEDED, "a Array Bounds Exceeded"},
|
||||
{EXCEPTION_BREAKPOINT, "a Breakpoint"},
|
||||
{EXCEPTION_DATATYPE_MISALIGNMENT, "a Datatype Misalignment"},
|
||||
{EXCEPTION_FLT_DENORMAL_OPERAND, "a Float Denormal Operand"},
|
||||
{EXCEPTION_FLT_DIVIDE_BY_ZERO, "a Float Divide By Zero"},
|
||||
{EXCEPTION_FLT_INEXACT_RESULT, "a Float Inexact Result"},
|
||||
{EXCEPTION_FLT_INVALID_OPERATION, "a Float Invalid Operation"},
|
||||
{EXCEPTION_FLT_OVERFLOW, "a Float Overflow"},
|
||||
{EXCEPTION_FLT_STACK_CHECK, "a Float Stack Check"},
|
||||
{EXCEPTION_FLT_UNDERFLOW, "a Float Underflow"},
|
||||
{EXCEPTION_ILLEGAL_INSTRUCTION, "an Illegal Instruction"},
|
||||
{EXCEPTION_IN_PAGE_ERROR, "an In Page Error"},
|
||||
{EXCEPTION_INT_DIVIDE_BY_ZERO, "an Integer Divide By Zero"},
|
||||
{EXCEPTION_INT_OVERFLOW, "an Integer Overflow"},
|
||||
{EXCEPTION_INVALID_DISPOSITION, "an Invalid Disposition"},
|
||||
{EXCEPTION_NONCONTINUABLE_EXCEPTION, "Noncontinuable Exception"},
|
||||
{EXCEPTION_PRIV_INSTRUCTION, "a Privileged Instruction"},
|
||||
{EXCEPTION_SINGLE_STEP, "a Single Step"},
|
||||
{EXCEPTION_STACK_OVERFLOW, "a Stack Overflow"},
|
||||
{0x40010005, "a Control-C"},
|
||||
{0x40010008, "a Control-Break"},
|
||||
{0xc0000006, "an In Page Error"},
|
||||
{0xc0000017, "a No Memory"},
|
||||
{0xc000001d, "an Illegal Instruction"},
|
||||
{0xc0000025, "a Noncontinuable Exception"},
|
||||
{0xc0000142, "a DLL Initialization Failed"},
|
||||
{0xe06d7363, "a Microsoft C++ Exception"},
|
||||
};
|
||||
|
||||
for (i = 0; i < (sizeof (ExceptionMap) / sizeof (ExceptionMap[0])); i++)
|
||||
if (ExceptionCode == ExceptionMap[i].ExceptionCode)
|
||||
return ExceptionMap[i].ExceptionName;
|
||||
|
||||
return "Unknown exception type";
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Directly output a formatted string to the errorlog file, using win32 funcs
|
||||
// --------------------------------------------------------------------------
|
||||
static VOID FPrintf (HANDLE fileHandle, LPCSTR lpFmt, ...)
|
||||
{
|
||||
CHAR str[1999];
|
||||
va_list arglist;
|
||||
DWORD bytesWritten;
|
||||
|
||||
va_start (arglist, lpFmt);
|
||||
vsprintf (str, lpFmt, arglist);
|
||||
va_end (arglist);
|
||||
|
||||
WriteFile (fileHandle, str, (DWORD)strlen(str), &bytesWritten, NULL);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Print the specified FILETIME to output in a human readable format,
|
||||
// without using the C run time.
|
||||
// --------------------------------------------------------------------------
|
||||
static VOID PrintTime (LPSTR output, FILETIME TimeToPrint)
|
||||
{
|
||||
WORD Date, Time;
|
||||
if (FileTimeToLocalFileTime (&TimeToPrint, &TimeToPrint) &&
|
||||
FileTimeToDosDateTime (&TimeToPrint, &Date, &Time))
|
||||
{
|
||||
// What a silly way to print out the file date/time.
|
||||
wsprintfA(output, "%d/%d/%d %02d:%02d:%02d",
|
||||
(Date / 32) & 15, Date & 31, (Date / 512) + 1980,
|
||||
(Time / 2048), (Time / 32) & 63, (Time & 31) * 2);
|
||||
}
|
||||
else
|
||||
output[0] = 0;
|
||||
}
|
||||
|
||||
|
||||
static LPTSTR GetFilePart(LPTSTR source)
|
||||
{
|
||||
LPTSTR result = _tcsrchr(source, '\\');
|
||||
if (result)
|
||||
result++;
|
||||
else
|
||||
result = source;
|
||||
return result;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Print information about a code module (DLL or EXE) such as its size,
|
||||
// location, time stamp, etc.
|
||||
// --------------------------------------------------------------------------
|
||||
static VOID ShowModuleInfo(HANDLE LogFile, HMODULE ModuleHandle)
|
||||
{
|
||||
CHAR ModName[MAX_PATH];
|
||||
IMAGE_DOS_HEADER *DosHeader;
|
||||
IMAGE_NT_HEADERS *NTHeader;
|
||||
HANDLE ModuleFile;
|
||||
CHAR TimeBuffer[100] = "";
|
||||
DWORD FileSize = 0;
|
||||
#ifdef NO_SEH_MINGW
|
||||
__try1(EXCEPTION_EXECUTE_HANDLER)
|
||||
#else
|
||||
__try
|
||||
#endif
|
||||
{
|
||||
if (GetModuleFileNameA(ModuleHandle, ModName, sizeof (ModName)) > 0)
|
||||
{
|
||||
// If GetModuleFileName returns greater than zero then this must
|
||||
// be a valid code module address. Therefore we can try to walk
|
||||
// our way through its structures to find the link time stamp.
|
||||
DosHeader = (IMAGE_DOS_HEADER*)ModuleHandle;
|
||||
if (IMAGE_DOS_SIGNATURE != DosHeader->e_magic)
|
||||
return;
|
||||
NTHeader = (IMAGE_NT_HEADERS*)((char *)DosHeader
|
||||
+ DosHeader->e_lfanew);
|
||||
if (IMAGE_NT_SIGNATURE != NTHeader->Signature)
|
||||
return;
|
||||
// Open the code module file so that we can get its file date
|
||||
// and size.
|
||||
ModuleFile = CreateFileA(ModName, GENERIC_READ,
|
||||
FILE_SHARE_READ, 0, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (ModuleFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
FILETIME LastWriteTime;
|
||||
FileSize = GetFileSize(ModuleFile, 0);
|
||||
if (GetFileTime(ModuleFile, 0, 0, &LastWriteTime))
|
||||
{
|
||||
wsprintfA(TimeBuffer, " - file date is ");
|
||||
PrintTime(TimeBuffer + strlen(TimeBuffer), LastWriteTime);
|
||||
}
|
||||
CloseHandle(ModuleFile);
|
||||
}
|
||||
FPrintf (LogFile, "%s, loaded at 0x%08x - %d bytes - %08x%s\r\n",
|
||||
ModName, ModuleHandle, FileSize,
|
||||
NTHeader->FileHeader.TimeDateStamp, TimeBuffer);
|
||||
}
|
||||
}
|
||||
// Handle any exceptions by continuing from this point.
|
||||
#ifdef NO_SEH_MINGW
|
||||
__except1
|
||||
#else
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Scan memory looking for code modules (DLLs or EXEs). VirtualQuery is used
|
||||
// to find all the blocks of address space that were reserved or committed,
|
||||
// and ShowModuleInfo will display module information if they are code
|
||||
// modules.
|
||||
// --------------------------------------------------------------------------
|
||||
static VOID RecordModuleList(HANDLE LogFile)
|
||||
{
|
||||
SYSTEM_INFO SystemInfo;
|
||||
size_t PageSize;
|
||||
size_t NumPages;
|
||||
size_t pageNum = 0;
|
||||
LPVOID LastAllocationBase = 0;
|
||||
|
||||
FPrintf (LogFile, "\r\n"
|
||||
"\tModule list: names, addresses, sizes, time stamps "
|
||||
"and file times:\r\n");
|
||||
|
||||
// Set NumPages to the number of pages in the 4GByte address space,
|
||||
// while being careful to avoid overflowing ints.
|
||||
GetSystemInfo(&SystemInfo);
|
||||
PageSize = SystemInfo.dwPageSize;
|
||||
NumPages = 4 * (unsigned int)(ONEG / PageSize);
|
||||
while (pageNum < NumPages)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION MemInfo;
|
||||
if (VirtualQuery((LPVOID)(pageNum * PageSize), &MemInfo,
|
||||
sizeof (MemInfo)))
|
||||
{
|
||||
if (MemInfo.RegionSize > 0)
|
||||
{
|
||||
// Adjust the page number to skip over this block of memory.
|
||||
pageNum += MemInfo.RegionSize / PageSize;
|
||||
if (MemInfo.State == MEM_COMMIT && MemInfo.AllocationBase >
|
||||
LastAllocationBase)
|
||||
{
|
||||
// Look for new blocks of committed memory, and try
|
||||
// recording their module names - this will fail
|
||||
// gracefully if they aren't code modules.
|
||||
LastAllocationBase = MemInfo.AllocationBase;
|
||||
ShowModuleInfo(LogFile, (HMODULE)LastAllocationBase);
|
||||
}
|
||||
}
|
||||
else
|
||||
pageNum += SIXTYFOURK / PageSize;
|
||||
}
|
||||
else
|
||||
pageNum += SIXTYFOURK / PageSize;
|
||||
// If VirtualQuery fails we advance by 64K because that is the
|
||||
// granularity of address space doled out by VirtualAlloc().
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Record information about the user's system, such as processor type, amount
|
||||
// of memory, etc.
|
||||
// --------------------------------------------------------------------------
|
||||
static VOID RecordSystemInformation(HANDLE fileHandle)
|
||||
{
|
||||
FILETIME CurrentTime;
|
||||
CHAR TimeBuffer[100];
|
||||
CHAR ModuleName[MAX_PATH];
|
||||
CHAR UserName[200];
|
||||
DWORD UserNameSize;
|
||||
SYSTEM_INFO SystemInfo;
|
||||
MEMORYSTATUS MemInfo;
|
||||
|
||||
GetSystemTimeAsFileTime (&CurrentTime);
|
||||
PrintTime (TimeBuffer, CurrentTime);
|
||||
FPrintf(fileHandle, "Error occurred at %s.\r\n", TimeBuffer);
|
||||
|
||||
if (GetModuleFileNameA(NULL, ModuleName, sizeof (ModuleName)) <= 0)
|
||||
strcpy (ModuleName, "Unknown");
|
||||
UserNameSize = sizeof (UserName);
|
||||
if (!GetUserNameA(UserName, &UserNameSize))
|
||||
strcpy (UserName, "Unknown");
|
||||
FPrintf(fileHandle, "%s, run by %s.\r\n", ModuleName, UserName);
|
||||
|
||||
GetSystemInfo (&SystemInfo);
|
||||
FPrintf (fileHandle, "%d processor(s), type %d %d.%d.\r\n"
|
||||
"Program Memory from 0x%p to 0x%p\r\n",
|
||||
SystemInfo.dwNumberOfProcessors,
|
||||
SystemInfo.dwProcessorType,
|
||||
SystemInfo.wProcessorLevel,
|
||||
SystemInfo.wProcessorRevision,
|
||||
SystemInfo.lpMinimumApplicationAddress,
|
||||
SystemInfo.lpMaximumApplicationAddress);
|
||||
|
||||
MemInfo.dwLength = sizeof (MemInfo);
|
||||
GlobalMemoryStatus(&MemInfo);
|
||||
// Print out the amount of physical memory, rounded up.
|
||||
FPrintf(fileHandle, "%d MBytes physical memory.\r\n", (MemInfo.dwTotalPhys +
|
||||
ONEM - 1) / ONEM);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// What we do here is trivial : open a file, write out the register information
|
||||
// from the PEXCEPTION_POINTERS structure, then return EXCEPTION_CONTINUE_SEARCH
|
||||
// whose magic value tells Win32 to proceed with its normal error handling
|
||||
// mechanism. This is important : an error dialog will popup if possible and
|
||||
// the debugger will hopefully coexist peacefully with the structured exception
|
||||
// handler.
|
||||
// --------------------------------------------------------------------------
|
||||
int __cdecl RecordExceptionInfo (PEXCEPTION_POINTERS data/*, LPCSTR Message, LPSTR lpCmdLine*/)
|
||||
{
|
||||
PEXCEPTION_RECORD Exception;
|
||||
PCONTEXT Context;
|
||||
TCHAR ModuleName[MAX_PATH];
|
||||
TCHAR FileName[MAX_PATH] = TEXT("Unknown");
|
||||
LPTSTR FilePart, lastperiod;
|
||||
TCHAR CrashModulePathName[MAX_PATH];
|
||||
LPCTSTR CrashModuleFileName = TEXT("Unknown");
|
||||
MEMORY_BASIC_INFORMATION MemInfo;
|
||||
static int BeenHere = false;
|
||||
HANDLE fileHandle;
|
||||
UINT8 *code;
|
||||
int codebyte,i;
|
||||
|
||||
if (data)
|
||||
{
|
||||
Exception = data->ExceptionRecord;
|
||||
Context = data->ContextRecord;
|
||||
}
|
||||
else
|
||||
{
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
if (BeenHere) // Going recursive! That must mean this routine crashed!
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
BeenHere = true;
|
||||
|
||||
// Create a filename to record the error information to.
|
||||
// Store it in the executable directory.
|
||||
if (GetModuleFileName(NULL, ModuleName, sizeof (ModuleName)) <= 0)
|
||||
ModuleName[0] = 0;
|
||||
FilePart = GetFilePart(ModuleName);
|
||||
|
||||
// Extract the file name portion and remove it's file extension. We'll
|
||||
// use that name shortly.
|
||||
lstrcpy (FileName, FilePart);
|
||||
lastperiod = _tcsrchr (FileName, '.');
|
||||
if (lastperiod)
|
||||
lastperiod[0] = 0;
|
||||
// Replace the executable filename with our error log file name.
|
||||
lstrcpy (FilePart, TEXT("errorlog.txt"));
|
||||
fileHandle = CreateFile (ModuleName, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL);
|
||||
if (fileHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
OutputDebugString (TEXT("Error creating exception report"));
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
// Append to the error log.
|
||||
SetFilePointer (fileHandle, 0, 0, FILE_END);
|
||||
|
||||
// Print out some blank lines to separate this error log from any previous ones.
|
||||
FPrintf (fileHandle, "Email Sonic Team Junior so we can fix the bugs\r\n"); // Tails
|
||||
FPrintf (fileHandle, "Make sure you tell us what you were doing to cause the crash, and if possible, record a demo!\r\n"); // Tails
|
||||
FPrintf (fileHandle, "\r\n\r\n\r\n\r\n");
|
||||
FPrintf (fileHandle, "SRB2Kart %s -ERROR LOG-\r\n\r\n", VERSIONSTRING);
|
||||
FPrintf (fileHandle, "\r\n");
|
||||
// VirtualQuery can be used to get the allocation base associated with a
|
||||
// code address, which is the same as the ModuleHandle. This can be used
|
||||
// to get the filename of the module that the crash happened in.
|
||||
if (VirtualQuery ((LPVOID)(size_t)Context->Eip, &MemInfo, sizeof (MemInfo)) &&
|
||||
GetModuleFileName ((HMODULE)MemInfo.AllocationBase,
|
||||
CrashModulePathName,
|
||||
sizeof (CrashModulePathName)) > 0)
|
||||
CrashModuleFileName = GetFilePart(CrashModulePathName);
|
||||
|
||||
// Print out the beginning of the error log in a Win95 error window
|
||||
// compatible format.
|
||||
FPrintf (fileHandle, "%s caused an %s in module %s at %04x:%08x.\r\n",
|
||||
FileName, GetExceptionDescription(Exception->ExceptionCode),
|
||||
CrashModuleFileName, Context->SegCs, Context->Eip);
|
||||
//if (&Message = Null)
|
||||
FPrintf (fileHandle, "Exception handler called in %s.\r\n", "main thread");
|
||||
//else
|
||||
//FPrintf (fileHandle, "Exception handler called in %s.\r\n", Message);
|
||||
|
||||
RecordSystemInformation (fileHandle);
|
||||
|
||||
// If the exception was an access violation, print out some additional
|
||||
// information, to the error log and the debugger.
|
||||
if (Exception->ExceptionCode == STATUS_ACCESS_VIOLATION &&
|
||||
Exception->NumberParameters >= 2)
|
||||
{
|
||||
TCHAR DebugMessage[1000];
|
||||
LPCTSTR readwrite = TEXT("Read from");
|
||||
if (Exception->ExceptionInformation[0])
|
||||
readwrite = TEXT("Write to");
|
||||
wsprintf(DebugMessage, TEXT("%s location %08x caused an access violation.\r\n"),
|
||||
readwrite, Exception->ExceptionInformation[1]);
|
||||
#ifdef _DEBUG
|
||||
// The VisualC++ debugger doesn't actually tell you whether a read
|
||||
// or a write caused the access violation, nor does it tell what
|
||||
// address was being read or written. So I fixed that.
|
||||
OutputDebugString(TEXT("Exception handler: "));
|
||||
OutputDebugString(DebugMessage);
|
||||
#endif
|
||||
FPrintf(fileHandle, "%s", DebugMessage);
|
||||
}
|
||||
|
||||
FPrintf(fileHandle, "\r\n");
|
||||
|
||||
// Print out the register values in a Win95 error window compatible format.
|
||||
if ((Context->ContextFlags & CONTEXT_FULL) == CONTEXT_FULL)
|
||||
{
|
||||
FPrintf (fileHandle, "Registers:\r\n");
|
||||
FPrintf (fileHandle, "EAX=%.8lx CS=%.4x EIP=%.8lx EFLGS=%.8lx\r\n",
|
||||
Context->Eax,Context->SegCs,Context->Eip,Context->EFlags);
|
||||
FPrintf (fileHandle, "EBX=%.8lx SS=%.4x ESP=%.8lx EBP=%.8lx\r\n",
|
||||
Context->Ebx,Context->SegSs,Context->Esp,Context->Ebp);
|
||||
FPrintf (fileHandle, "ECX=%.8lx DS=%.4x ESI=%.8lx FS=%.4x\r\n",
|
||||
Context->Ecx,Context->SegDs,Context->Esi,Context->SegFs);
|
||||
FPrintf (fileHandle, "EDX=%.8lx ES=%.4x EDI=%.8lx GS=%.4x\r\n",
|
||||
Context->Edx,Context->SegEs,Context->Edi,Context->SegGs);
|
||||
}
|
||||
|
||||
// moved down because it was causing the printout to stop
|
||||
FPrintf (fileHandle, "Command Line parameters: ");
|
||||
for (i = 1;i < myargc;i++)
|
||||
FPrintf (fileHandle, "%s ", myargv[i]);
|
||||
|
||||
FPrintf (fileHandle, "Bytes at CS : EIP:\r\n");
|
||||
|
||||
// Print out the bytes of code at the instruction pointer. Since the
|
||||
// crash may have been caused by an instruction pointer that was bad,
|
||||
// this code needs to be wrapped in an exception handler, in case there
|
||||
// is no memory to read. If the dereferencing of code[] fails, the
|
||||
// exception handler will print '??'.
|
||||
code = (UINT8 *)(size_t)Context->Eip;
|
||||
for (codebyte = 0; codebyte < NumCodeBytes; codebyte++)
|
||||
{
|
||||
#ifdef NO_SEH_MINGW
|
||||
__try1(EXCEPTION_EXECUTE_HANDLER)
|
||||
#else
|
||||
__try
|
||||
#endif
|
||||
{
|
||||
FPrintf (fileHandle, "%02x ", code[codebyte]);
|
||||
}
|
||||
#ifdef NO_SEH_MINGW
|
||||
__except1
|
||||
#else
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
#endif
|
||||
{
|
||||
FPrintf (fileHandle, "?? ");
|
||||
}
|
||||
}
|
||||
|
||||
// Time to print part or all of the stack to the error log. This allows
|
||||
// us to figure out the call stack, parameters, local variables, etc.
|
||||
FPrintf (fileHandle, "\r\n"
|
||||
"Stack dump:\r\n");
|
||||
#ifdef NO_SEH_MINGW
|
||||
__try1(EXCEPTION_EXECUTE_HANDLER)
|
||||
#else
|
||||
__try
|
||||
#endif
|
||||
{
|
||||
// Esp contains the bottom of the stack, or at least the bottom of
|
||||
// the currently used area.
|
||||
DWORD* pStack = (DWORD *)(size_t)Context->Esp;
|
||||
DWORD* pStackTop = NULL;
|
||||
size_t Count = 0;
|
||||
TCHAR buffer[1000] = TEXT("");
|
||||
const int safetyzone = 50;
|
||||
LPTSTR nearend = buffer + sizeof (buffer) - safetyzone*sizeof (TCHAR);
|
||||
LPTSTR output = buffer;
|
||||
const void *Suffix;
|
||||
|
||||
// Load the top (highest address) of the stack from the
|
||||
// thread information block. It will be found there in
|
||||
// Win9x and Windows NT.
|
||||
#ifdef __GNUC__
|
||||
__asm__("movl %%fs : 4, %%eax": "=a"(pStackTop));
|
||||
#else
|
||||
__asm
|
||||
{
|
||||
mov eax, fs:[4]
|
||||
mov pStackTop, eax
|
||||
}
|
||||
#endif
|
||||
if (pStackTop == NULL)
|
||||
goto StackSkip;
|
||||
else if (pStackTop > pStack + MaxStackDump)
|
||||
pStackTop = pStack + MaxStackDump;
|
||||
// Too many calls to WriteFile can take a long time, causing
|
||||
// confusing delays when programs crash. Therefore I implemented
|
||||
// simple buffering for the stack dumping code instead of calling
|
||||
// FPrintf directly.
|
||||
while (pStack + 1 <= pStackTop)
|
||||
{
|
||||
if ((Count % StackColumns) == 0)
|
||||
output += wsprintf(output, TEXT("%08x: "), pStack);
|
||||
if ((++Count % StackColumns) == 0 || pStack + 2 > pStackTop)
|
||||
Suffix = TEXT("\r\n");
|
||||
else
|
||||
Suffix = TEXT(" ");
|
||||
output += wsprintf(output, TEXT("%08x%s"), *pStack, Suffix);
|
||||
pStack++;
|
||||
// Check for when the buffer is almost full, and flush it to disk.
|
||||
if (output > nearend)
|
||||
{
|
||||
FPrintf (fileHandle, "%s", buffer);
|
||||
buffer[0] = 0;
|
||||
output = buffer;
|
||||
}
|
||||
}
|
||||
// Print out any final characters from the cache.
|
||||
StackSkip:
|
||||
FPrintf (fileHandle, "%s", buffer);
|
||||
}
|
||||
#ifdef NO_SEH_MINGW
|
||||
__except1
|
||||
#else
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
#endif
|
||||
{
|
||||
FPrintf(fileHandle, "Exception encountered during stack dump.\r\n");
|
||||
}
|
||||
|
||||
RecordModuleList (fileHandle);
|
||||
|
||||
CloseHandle (fileHandle);
|
||||
|
||||
// Return the magic value which tells Win32 that this handler didn't
|
||||
// actually handle the exception - so that things will proceed as per
|
||||
// normal.
|
||||
//BP: should put message for end user to send this file to fix any bug
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
/*
|
||||
//
|
||||
//FPrintf ("e-mail this file to legacy@newdoom.com, so that we can fix the problem.\r\n\r\n");
|
||||
|
||||
FPrintf ("Exception handler called in %s.\r\n", Message);
|
||||
|
||||
GetSystemTime (&systemTime);
|
||||
FPrintf ("Error occured at %02d/%02d/%04d %02d:%02d:%02d.\r\n",
|
||||
systemTime.wMonth, systemTime.wDay, systemTime.wYear,
|
||||
systemTime.wHour, systemTime.wMinute, systemTime.wSecond);
|
||||
|
||||
|
||||
FPrintf ("%s\r\n", filename);
|
||||
FPrintf ("Cmd-line: %s\r\n", lpCmdLine);
|
||||
|
||||
// Nested exceptions can occur, get info for each one
|
||||
|
||||
nER = 1;
|
||||
while (ER)
|
||||
{
|
||||
if (nER++>1)
|
||||
FPrintf ("Exception Record %d.\r\n", nER);
|
||||
|
||||
FPrintf ("application caused an %s", GetExceptionCodeStr(Exception->ExceptionCode));
|
||||
|
||||
if (Context->ContextFlags & CONTEXT_CONTROL)
|
||||
FPrintf (" at %.4x:%.8x.\r\n", Context->SegCs, Context->Eip);
|
||||
|
||||
// in case of..
|
||||
if (Context->Eip != (unsigned long)Exception->ExceptionAddress)
|
||||
FPrintf ("Exception Address = %.8x\r\n", Exception->ExceptionAddress);
|
||||
|
||||
if (Exception->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
|
||||
{
|
||||
FPrintf ("\r\n%s location 0x%x caused an access violation.\r\n",
|
||||
(Exception->ExceptionInformation[0] ? "Write to" : "Read from"),
|
||||
Exception->ExceptionInformation[1]);
|
||||
}
|
||||
|
||||
ER = Exception->ExceptionRecord;
|
||||
}
|
||||
|
||||
|
||||
if (Context->ContextFlags & CONTEXT_DEBUG_REGISTERS)
|
||||
{
|
||||
FPrintf ("\r\nDebug Registers:\r\n");
|
||||
FPrintf ("Dr0=%.8x Dr1=%.8x Dr2=%.8x\r\n"
|
||||
"Dr3=%.8x Dr6=%.8x Dr7=%.8x\r\n",
|
||||
Context->Dr0, Context->Dr1, Context->Dr2,
|
||||
Context->Dr3, Context->Dr6, Context->Dr7);
|
||||
}
|
||||
|
||||
if (Context->ContextFlags & CONTEXT_FLOATING_POINT)
|
||||
{
|
||||
FPrintf ("\r\nFloating Save Area:\r\n");
|
||||
FPrintf ("ControlWord =%.8x TagWord =%.8x ErrorSelector=%.8x DataSelector =%.8x\r\n"
|
||||
"StatusWord =%.8x ErrorOffset =%.8x DataOffset =%.8x Cr0NpxState =%.8x\r\n",
|
||||
Context->FloatSave.ControlWord, Context->FloatSave.TagWord, Context->FloatSave.ErrorSelector, Context->FloatSave.DataSelector,
|
||||
Context->FloatSave.StatusWord, Context->FloatSave.ErrorOffset, Context->FloatSave.DataOffset, Context->FloatSave.Cr0NpxState
|
||||
);
|
||||
|
||||
//BYTE RegisterArea[SIZE_OF_80387_REGISTERS];
|
||||
}
|
||||
|
||||
|
||||
// in case of...
|
||||
if ((Context->ContextFlags & CONTEXT_FULL) != CONTEXT_FULL)
|
||||
{
|
||||
if (!(Context->ContextFlags & CONTEXT_SEGMENTS))
|
||||
FPrintf ("Note! GS,FS,ES,DS are unspecified\r\n");
|
||||
if (!(Context->ContextFlags & CONTEXT_INTEGER))
|
||||
FPrintf ("Note! EDI,ESI,EBX,EDX,ECX,EAX are unspecified\r\n");
|
||||
if (!(Context->ContextFlags & CONTEXT_CONTROL))
|
||||
FPrintf ("Note! EBP,CS : EIP,EFlags,SS : ESP are unspecified\r\n");
|
||||
}
|
||||
|
||||
FPrintf ("\r\nBytes at CS : EIP:\r\n");
|
||||
ucptr = (UINT8 *)Context->Eip;
|
||||
for (i = 0; i < 16; i++)
|
||||
FPrintf ("%.2x ", *ucptr++);
|
||||
|
||||
FPrintf ("\r\n\r\nStack dump:\r\n");
|
||||
ulptr = (unsigned long*)Context->Esp;
|
||||
for (i = 0; i < 16; i++)
|
||||
FPrintf ("%.8x ", *ulptr++);
|
||||
|
||||
//FPrintf ("Bytes at CS : EIP:\r\n");
|
||||
//FPrintf ("%.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x ");
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
FPrintf ("%x
|
||||
}
|
||||
*/
|
||||
|
|
@ -1,118 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file
|
||||
/// \brief load and initialise the 3D driver DLL
|
||||
|
||||
#include "../doomdef.h"
|
||||
|
||||
#ifdef HW3SOUND
|
||||
#include "../hardware/hw3dsdrv.h" // get the 3D sound driver DLL export prototypes
|
||||
#endif
|
||||
|
||||
#include "win_dll.h"
|
||||
#include "win_main.h" // I_GetLastErrorMsgBox()
|
||||
|
||||
#if defined(HW3SOUND)
|
||||
typedef struct loadfunc_s {
|
||||
LPCSTR fnName;
|
||||
LPVOID fnPointer;
|
||||
} loadfunc_t;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Load a DLL, returns the HMODULE handle or NULL
|
||||
// --------------------------------------------------------------------------
|
||||
static inline HMODULE LoadDLL (LPCSTR dllName, loadfunc_t *funcTable)
|
||||
{
|
||||
LPVOID funcPtr;
|
||||
loadfunc_t *loadfunc;
|
||||
HMODULE hModule;
|
||||
|
||||
if ((hModule = LoadLibraryA(dllName)) != NULL)
|
||||
{
|
||||
// get function pointers for all functions we use
|
||||
for (loadfunc = funcTable; loadfunc->fnName != NULL; loadfunc++)
|
||||
{
|
||||
funcPtr = GetProcAddress(hModule, loadfunc->fnName);
|
||||
if (!funcPtr) {
|
||||
//I_GetLastErrorMsgBox ();
|
||||
MessageBoxA(NULL, va("The '%s' haven't the good specification (function %s missing)\n\n"
|
||||
"You must use dll from the same zip of this exe\n", dllName, loadfunc->fnName),
|
||||
"Error", MB_OK|MB_ICONINFORMATION);
|
||||
return FALSE;
|
||||
}
|
||||
// store function address
|
||||
*((LPVOID*)loadfunc->fnPointer) = funcPtr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBoxA(NULL, va("LoadLibrary() FAILED : couldn't load '%s'\r\n", dllName), "Warning", MB_OK|MB_ICONINFORMATION);
|
||||
//I_GetLastErrorMsgBox ();
|
||||
}
|
||||
|
||||
return hModule;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// Unload the DLL
|
||||
// --------------------------------------------------------------------------
|
||||
static inline VOID UnloadDLL (HMODULE* pModule)
|
||||
{
|
||||
if (FreeLibrary(*pModule))
|
||||
*pModule = NULL;
|
||||
else
|
||||
I_GetLastErrorMsgBox ();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HW3SOUND
|
||||
static HMODULE hwsModule = NULL;
|
||||
|
||||
static loadfunc_t hwsFuncTable[] = {
|
||||
{"_Startup@8", &hw3ds_driver.pfnStartup},
|
||||
{"_Shutdown@0", &hw3ds_driver.pfnShutdown},
|
||||
{"_AddSfx@4", &hw3ds_driver.pfnAddSfx},
|
||||
{"_AddSource@8", &hw3ds_driver.pfnAddSource},
|
||||
{"_StartSource@4", &hw3ds_driver.pfnStartSource},
|
||||
{"_StopSource@4", &hw3ds_driver.pfnStopSource},
|
||||
{"_GetHW3DSVersion@0", &hw3ds_driver.pfnGetHW3DSVersion},
|
||||
{"_BeginFrameUpdate@0", &hw3ds_driver.pfnBeginFrameUpdate},
|
||||
{"_EndFrameUpdate@0", &hw3ds_driver.pfnEndFrameUpdate},
|
||||
{"_IsPlaying@4", &hw3ds_driver.pfnIsPlaying},
|
||||
{"_UpdateListener@8", &hw3ds_driver.pfnUpdateListener},
|
||||
{"_UpdateSourceParms@12", &hw3ds_driver.pfnUpdateSourceParms},
|
||||
{"_SetCone@8", &hw3ds_driver.pfnSetCone},
|
||||
{"_SetGlobalSfxVolume@4", &hw3ds_driver.pfnSetGlobalSfxVolume},
|
||||
{"_Update3DSource@8", &hw3ds_driver.pfnUpdate3DSource},
|
||||
{"_ReloadSource@8", &hw3ds_driver.pfnReloadSource},
|
||||
{"_KillSource@4", &hw3ds_driver.pfnKillSource},
|
||||
{"_KillSfx@4", &hw3ds_driver.pfnKillSfx},
|
||||
{"_GetHW3DSTitle@8", &hw3ds_driver.pfnGetHW3DSTitle},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
BOOL Init3DSDriver(LPCSTR dllName)
|
||||
{
|
||||
hwsModule = LoadDLL(dllName, hwsFuncTable);
|
||||
return (hwsModule != NULL);
|
||||
}
|
||||
|
||||
VOID Shutdown3DSDriver (VOID)
|
||||
{
|
||||
UnloadDLL(&hwsModule);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file
|
||||
/// \brief load/unload a DLL at run-time
|
||||
|
||||
//#define WIN32_LEAN_AND_MEAN
|
||||
#define RPC_NO_WINDOWS_H
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef HW3SOUND
|
||||
BOOL Init3DSDriver(LPCSTR dllName);
|
||||
VOID Shutdown3DSDriver(VOID);
|
||||
#endif
|
||||
|
|
@ -1,530 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file
|
||||
/// \brief Win32 WinMain Entry Point
|
||||
///
|
||||
/// Win32 Sonic Robo Blast 2
|
||||
///
|
||||
/// NOTE:
|
||||
/// To compile WINDOWS SRB2 version : define a '_WINDOWS' symbol.
|
||||
/// to do this go to Project/Settings/ menu, click C/C++ tab, in
|
||||
/// 'Preprocessor definitions:' add '_WINDOWS'
|
||||
|
||||
#include "../doomdef.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../doomstat.h" // netgame
|
||||
#include "resource.h"
|
||||
|
||||
#include "../m_argv.h"
|
||||
#include "../d_main.h"
|
||||
#include "../i_system.h"
|
||||
|
||||
#include "../keys.h" //hack quick test
|
||||
|
||||
#include "../console.h"
|
||||
|
||||
#include "fabdxlib.h"
|
||||
#include "win_main.h"
|
||||
#include "win_dbg.h"
|
||||
#include "../i_sound.h" // midi pause/unpause
|
||||
#include "../g_input.h" // KEY_MOUSEWHEELxxx
|
||||
|
||||
// MSWheel support for Win95/NT3.51
|
||||
#include <zmouse.h>
|
||||
|
||||
#ifndef WM_XBUTTONDOWN
|
||||
#define WM_XBUTTONDOWN 523
|
||||
#endif
|
||||
#ifndef WM_XBUTTONUP
|
||||
#define WM_XBUTTONUP 524
|
||||
#endif
|
||||
#ifndef MK_XBUTTON1
|
||||
#define MK_XBUTTON1 32
|
||||
#endif
|
||||
#ifndef MK_XBUTTON2
|
||||
#define MK_XBUTTON2 64
|
||||
#endif
|
||||
|
||||
typedef BOOL (WINAPI *MyFunc)(VOID);
|
||||
|
||||
HINSTANCE myInstance = NULL;
|
||||
HWND hWndMain = NULL;
|
||||
static HCURSOR windowCursor = NULL; // main window cursor
|
||||
|
||||
boolean appActive = false; // app window is active
|
||||
|
||||
#ifdef LOGMESSAGES
|
||||
// this is were I log debug text, cons_printf, I_error ect for window port debugging
|
||||
HANDLE logstream;
|
||||
#endif
|
||||
|
||||
BOOL nodinput = FALSE;
|
||||
|
||||
static LRESULT CALLBACK MainWndproc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
event_t ev; //Doom input event
|
||||
int mouse_keys;
|
||||
|
||||
// judgecutor:
|
||||
// Response MSH Mouse Wheel event
|
||||
|
||||
if (message == MSHWheelMessage)
|
||||
{
|
||||
message = WM_MOUSEWHEEL;
|
||||
if (win9x)
|
||||
wParam <<= 16;
|
||||
}
|
||||
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_CREATE:
|
||||
nodinput = M_CheckParm("-nodinput");
|
||||
break;
|
||||
|
||||
case WM_ACTIVATEAPP: // Handle task switching
|
||||
appActive = (int)wParam;
|
||||
// pause music when alt-tab
|
||||
if (appActive && !paused)
|
||||
I_ResumeSong(0);
|
||||
else if (!paused)
|
||||
I_PauseSong(0);
|
||||
{
|
||||
HANDLE ci = GetStdHandle(STD_INPUT_HANDLE);
|
||||
if (ci != INVALID_HANDLE_VALUE && GetFileType(ci) == FILE_TYPE_CHAR)
|
||||
appActive = true;
|
||||
}
|
||||
InvalidateRect (hWnd, NULL, TRUE);
|
||||
break;
|
||||
|
||||
//for MIDI music
|
||||
case WM_MSTREAM_UPDATEVOLUME:
|
||||
I_SetMidiChannelVolume((DWORD)wParam, dwVolumePercent);
|
||||
break;
|
||||
|
||||
case WM_PAINT:
|
||||
if (!appActive && !bAppFullScreen && !netgame)
|
||||
// app becomes inactive (if windowed)
|
||||
{
|
||||
// Paint "Game Paused" in the middle of the screen
|
||||
PAINTSTRUCT ps;
|
||||
RECT rect;
|
||||
HDC hdc = BeginPaint (hWnd, &ps);
|
||||
GetClientRect (hWnd, &rect);
|
||||
DrawText (hdc, TEXT("Game Paused"), -1, &rect,
|
||||
DT_SINGLELINE | DT_CENTER | DT_VCENTER);
|
||||
EndPaint (hWnd, &ps);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
//case WM_RBUTTONDOWN:
|
||||
//case WM_LBUTTONDOWN:
|
||||
|
||||
case WM_MOVE:
|
||||
if (bAppFullScreen)
|
||||
{
|
||||
SetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
windowPosX = (SHORT) LOWORD(lParam); // horizontal position
|
||||
windowPosY = (SHORT) HIWORD(lParam); // vertical position
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// This is where switching windowed/fullscreen is handled. DirectDraw
|
||||
// objects must be destroyed, recreated, and artwork reloaded.
|
||||
|
||||
case WM_DISPLAYCHANGE:
|
||||
case WM_SIZE:
|
||||
break;
|
||||
|
||||
case WM_SETCURSOR:
|
||||
if (bAppFullScreen)
|
||||
SetCursor(NULL);
|
||||
else
|
||||
SetCursor(windowCursor);
|
||||
return TRUE;
|
||||
|
||||
case WM_KEYUP:
|
||||
ev.type = ev_keyup;
|
||||
goto handleKeyDoom;
|
||||
break;
|
||||
|
||||
case WM_KEYDOWN:
|
||||
ev.type = ev_keydown;
|
||||
|
||||
handleKeyDoom:
|
||||
ev.data1 = 0;
|
||||
if (wParam == VK_PAUSE)
|
||||
// intercept PAUSE key
|
||||
{
|
||||
ev.data1 = KEY_PAUSE;
|
||||
}
|
||||
else if (!keyboard_started)
|
||||
// post some keys during the game startup
|
||||
// (allow escaping from network synchronization, or pressing enter after
|
||||
// an error message in the console)
|
||||
{
|
||||
switch (wParam)
|
||||
{
|
||||
case VK_ESCAPE: ev.data1 = KEY_ESCAPE; break;
|
||||
case VK_RETURN: ev.data1 = KEY_ENTER; break;
|
||||
default: ev.data1 = MapVirtualKey((DWORD)wParam,2); // convert in to char
|
||||
}
|
||||
}
|
||||
|
||||
if (ev.data1)
|
||||
D_PostEvent (&ev);
|
||||
|
||||
return 0;
|
||||
break;
|
||||
|
||||
// judgecutor:
|
||||
// Handle mouse events
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_XBUTTONDOWN:
|
||||
case WM_XBUTTONUP:
|
||||
case WM_MOUSEMOVE:
|
||||
if (nodinput)
|
||||
{
|
||||
mouse_keys = 0;
|
||||
if (wParam & MK_LBUTTON)
|
||||
mouse_keys |= 1;
|
||||
if (wParam & MK_RBUTTON)
|
||||
mouse_keys |= 2;
|
||||
if (wParam & MK_MBUTTON)
|
||||
mouse_keys |= 4;
|
||||
if (wParam & MK_XBUTTON1)
|
||||
mouse_keys |= 8;
|
||||
if (wParam & MK_XBUTTON2)
|
||||
mouse_keys |= 16;
|
||||
I_GetSysMouseEvents(mouse_keys);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case WM_MOUSEWHEEL:
|
||||
//CONS_Printf("MW_WHEEL dispatched.\n");
|
||||
ev.type = ev_keydown;
|
||||
if ((INT16)HIWORD(wParam) > 0)
|
||||
ev.data1 = KEY_MOUSEWHEELUP;
|
||||
else
|
||||
ev.data1 = KEY_MOUSEWHEELDOWN;
|
||||
D_PostEvent(&ev);
|
||||
break;
|
||||
|
||||
case WM_SETTEXT:
|
||||
COM_BufAddText((LPCSTR)lParam);
|
||||
return TRUE;
|
||||
break;
|
||||
|
||||
case WM_CLOSE:
|
||||
PostQuitMessage(0); //to quit while in-game
|
||||
ev.data1 = KEY_ESCAPE; //to exit network synchronization
|
||||
ev.type = ev_keydown;
|
||||
D_PostEvent (&ev);
|
||||
return 0;
|
||||
case WM_DESTROY:
|
||||
//faB: main app loop will exit the loop and proceed with I_Quit()
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
static inline VOID OpenTextConsole(void)
|
||||
{
|
||||
HANDLE ci, co;
|
||||
const BOOL tco = M_CheckParm("-console") != 0;
|
||||
dedicated = M_CheckParm("-dedicated") != 0;
|
||||
if (!(dedicated || tco))
|
||||
return;
|
||||
FreeConsole();
|
||||
AllocConsole(); //Let get the real console HANDLE, because Mingw's Bash is bad!
|
||||
ci = CreateFile(TEXT("CONIN$") , GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
co = CreateFile(TEXT("CONOUT$"), GENERIC_WRITE|GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (ci != (HANDLE)-1)
|
||||
{
|
||||
const DWORD CM = ENABLE_LINE_INPUT|ENABLE_ECHO_INPUT|ENABLE_PROCESSED_INPUT;
|
||||
SetStdHandle(STD_INPUT_HANDLE,ci);
|
||||
if(GetFileType(ci) == FILE_TYPE_CHAR)
|
||||
SetConsoleMode(ci,CM); //default mode but no ENABLE_MOUSE_INPUT
|
||||
}
|
||||
if(co != (HANDLE)-1)
|
||||
{
|
||||
SetStdHandle(STD_OUTPUT_HANDLE,co);
|
||||
SetStdHandle(STD_ERROR_HANDLE,co); //maybe logstream?
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Do that Windows initialization stuff...
|
||||
//
|
||||
static HWND OpenMainWindow (HINSTANCE hInstance, int nCmdShow, LPSTR wTitle)
|
||||
{
|
||||
HWND hWnd;
|
||||
WNDCLASS wc;
|
||||
|
||||
// Set up and register window class
|
||||
nCmdShow = 0;
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW /*| CS_DBLCLKS*/;
|
||||
wc.lpfnWndProc = MainWndproc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = hInstance;
|
||||
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DLICON1));
|
||||
windowCursor = LoadCursor(NULL, IDC_WAIT); //LoadCursor(hInstance, MAKEINTRESOURCE(IDC_DLCURSOR1));
|
||||
wc.hCursor = windowCursor;
|
||||
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = TEXT("SRB2WC");
|
||||
if (!RegisterClass(&wc))
|
||||
return (HANDLE)-1;
|
||||
|
||||
// Create a window
|
||||
// CreateWindowEx - seems to create just the interior, not the borders
|
||||
|
||||
hWnd = CreateWindowExA(
|
||||
#ifdef _DEBUG
|
||||
0, //ExStyle
|
||||
#else
|
||||
dedicated ? 0:WS_EX_TOPMOST, //ExStyle
|
||||
#endif
|
||||
"SRB2WC", //Classname
|
||||
wTitle, //Windowname
|
||||
WS_CAPTION|WS_POPUP|WS_SYSMENU, //dwStyle //WS_VISIBLE|WS_POPUP for bAppFullScreen
|
||||
0,
|
||||
0,
|
||||
dedicated ? 0:BASEVIDWIDTH, //GetSystemMetrics(SM_CXSCREEN),
|
||||
dedicated ? 0:BASEVIDHEIGHT, //GetSystemMetrics(SM_CYSCREEN),
|
||||
NULL, //hWnd Parent
|
||||
NULL, //hMenu Menu
|
||||
hInstance,
|
||||
NULL);
|
||||
|
||||
return hWnd;
|
||||
}
|
||||
|
||||
|
||||
static inline BOOL tlErrorMessage(const TCHAR *err)
|
||||
{
|
||||
/* make the cursor visible */
|
||||
SetCursor(LoadCursor(NULL, IDC_ARROW));
|
||||
|
||||
//
|
||||
// warn user if there is one
|
||||
//
|
||||
printf("Error %s..\n", err);
|
||||
fflush(stdout);
|
||||
|
||||
MessageBox(hWndMain, err, TEXT("ERROR"), MB_OK);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
// ------------------
|
||||
// Command line stuff
|
||||
// ------------------
|
||||
#define MAXCMDLINEARGS 64
|
||||
static char * myWargv[MAXCMDLINEARGS+1];
|
||||
static char myCmdline[512];
|
||||
|
||||
static VOID GetArgcArgv (LPSTR cmdline)
|
||||
{
|
||||
LPSTR token;
|
||||
size_t i = 0, len;
|
||||
char cSep = ' ';
|
||||
BOOL bCvar = FALSE, prevCvar = FALSE;
|
||||
|
||||
// split arguments of command line into argv
|
||||
strncpy (myCmdline, cmdline, 511); // in case window's cmdline is in protected memory..for strtok
|
||||
len = strlen (myCmdline);
|
||||
|
||||
myargc = 0;
|
||||
while (myargc < MAXCMDLINEARGS)
|
||||
{
|
||||
// get token
|
||||
while (myCmdline[i] == cSep)
|
||||
i++;
|
||||
if (i >= len)
|
||||
break;
|
||||
token = myCmdline + i;
|
||||
if (myCmdline[i] == '"')
|
||||
{
|
||||
cSep = '"';
|
||||
i++;
|
||||
if (!prevCvar) //cvar leave the "" in
|
||||
token++;
|
||||
}
|
||||
else
|
||||
cSep = ' ';
|
||||
|
||||
//cvar
|
||||
if (myCmdline[i] == '+' && cSep == ' ') //a + begins a cvarname, but not after quotes
|
||||
bCvar = TRUE;
|
||||
else
|
||||
bCvar = FALSE;
|
||||
|
||||
while (myCmdline[i] &&
|
||||
myCmdline[i] != cSep)
|
||||
i++;
|
||||
|
||||
if (myCmdline[i] == '"')
|
||||
{
|
||||
cSep = ' ';
|
||||
if (prevCvar)
|
||||
i++; // get ending " quote in arg
|
||||
}
|
||||
|
||||
prevCvar = bCvar;
|
||||
|
||||
if (myCmdline + i > token)
|
||||
{
|
||||
myWargv[myargc++] = token;
|
||||
}
|
||||
|
||||
if (!myCmdline[i] || i >= len)
|
||||
break;
|
||||
|
||||
myCmdline[i++] = '\0';
|
||||
}
|
||||
myWargv[myargc] = NULL;
|
||||
|
||||
// m_argv.c uses myargv[], we used myWargv because we fill the arguments ourselves
|
||||
// and myargv is just a pointer, so we set it to point myWargv
|
||||
myargv = myWargv;
|
||||
}
|
||||
|
||||
|
||||
static inline VOID MakeCodeWritable(VOID)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// HandledWinMain : called by exception handler
|
||||
// -----------------------------------------------------------------------------
|
||||
static int WINAPI HandledWinMain(HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow)
|
||||
{
|
||||
int i;
|
||||
LPSTR args;
|
||||
|
||||
lpCmdLine = NULL;
|
||||
hPrevInstance = NULL;
|
||||
#ifdef LOGMESSAGES
|
||||
// DEBUG!!! - set logstream to NULL to disable debug log
|
||||
logstream = INVALID_HANDLE_VALUE;
|
||||
|
||||
logstream = CreateFile (TEXT("log.txt"), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL); //file flag writethrough?
|
||||
#endif
|
||||
|
||||
// fill myargc,myargv for m_argv.c retrieval of cmdline arguments
|
||||
CONS_Printf("GetArgcArgv() ...\n");
|
||||
args = GetCommandLineA();
|
||||
CONS_Printf("lpCmdLine is '%s'\n", args);
|
||||
GetArgcArgv(args);
|
||||
// Create a text console window
|
||||
OpenTextConsole();
|
||||
|
||||
CONS_Printf("Myargc: %d\n", myargc);
|
||||
for (i = 0; i < myargc; i++)
|
||||
CONS_Printf("myargv[%d] : '%s'\n", i, myargv[i]);
|
||||
|
||||
// store for later use, will we need it ?
|
||||
myInstance = hInstance;
|
||||
|
||||
// open a dummy window, both OpenGL and DirectX need one.
|
||||
if ((hWndMain = OpenMainWindow(hInstance,nCmdShow,
|
||||
va("SRB2Kart "VERSIONSTRING))) == (HANDLE)-1)
|
||||
{
|
||||
tlErrorMessage(TEXT("Couldn't open window"));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// currently starts DirectInput
|
||||
CONS_Printf("I_StartupSystem() ...\n");
|
||||
I_StartupSystem();
|
||||
MakeCodeWritable();
|
||||
|
||||
// startup SRB2
|
||||
CONS_Printf("D_SRB2Main() ...\n");
|
||||
D_SRB2Main();
|
||||
CONS_Printf("Entering main app loop...\n");
|
||||
// never return
|
||||
D_SRB2Loop();
|
||||
|
||||
// back to Windoze
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Exception handler calls WinMain for catching exceptions
|
||||
// -----------------------------------------------------------------------------
|
||||
int WINAPI WinMain (HINSTANCE hInstance,
|
||||
HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow)
|
||||
{
|
||||
int Result = -1;
|
||||
#if 1
|
||||
HMODULE h = GetModuleHandleA("kernel32.dll");
|
||||
MyFunc pfnIsDebuggerPresent = NULL;
|
||||
if (h)
|
||||
pfnIsDebuggerPresent = (MyFunc)GetProcAddress(h,"IsDebuggerPresent");
|
||||
if (!pfnIsDebuggerPresent || !pfnIsDebuggerPresent())
|
||||
LoadLibrary("exchndl.dll");
|
||||
#endif
|
||||
#ifdef NO_SEH_MINGW
|
||||
__try1(RecordExceptionInfo(GetExceptionInformation()/*, "main thread", lpCmdLine*/))
|
||||
#else
|
||||
__try
|
||||
#endif
|
||||
{
|
||||
Result = HandledWinMain (hInstance, hPrevInstance, lpCmdLine, nCmdShow);
|
||||
}
|
||||
#ifdef NO_SEH_MINGW
|
||||
__except1
|
||||
#else
|
||||
__except (RecordExceptionInfo(GetExceptionInformation()/*, "main thread", lpCmdLine*/))
|
||||
#endif
|
||||
{
|
||||
SetUnhandledExceptionFilter(EXCEPTION_CONTINUE_SEARCH); //Do nothing here.
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,781 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \file
|
||||
/// \brief win32 video driver for Doom Legacy
|
||||
|
||||
#include "../doomdef.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "../d_clisrv.h"
|
||||
#include "../i_system.h"
|
||||
#include "../m_argv.h"
|
||||
#include "../v_video.h"
|
||||
#include "../st_stuff.h"
|
||||
#include "../i_video.h"
|
||||
#include "../z_zone.h"
|
||||
#include "fabdxlib.h"
|
||||
|
||||
#include "win_main.h"
|
||||
#include "../command.h"
|
||||
#include "../screen.h"
|
||||
|
||||
// -------
|
||||
// Globals
|
||||
// -------
|
||||
|
||||
// this is the CURRENT rendermode!! very important: used by w_wad, and much other code
|
||||
rendermode_t rendermode = render_soft;
|
||||
|
||||
// synchronize page flipping with screen refresh
|
||||
consvar_t cv_vidwait = {"vid_wait", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
static consvar_t cv_stretch = {"stretch", "On", CV_SAVE|CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
boolean highcolor;
|
||||
|
||||
static BOOL bDIBMode; // means we are using DIB instead of DirectDraw surfaces
|
||||
static BITMAPINFO* bmiMain = NULL;
|
||||
static HDC hDCMain = NULL;
|
||||
|
||||
// -----------------
|
||||
// Video modes stuff
|
||||
// -----------------
|
||||
|
||||
#define MAX_EXTRA_MODES 36
|
||||
static vmode_t extra_modes[MAX_EXTRA_MODES] = {{NULL, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 0}};
|
||||
static char names[MAX_EXTRA_MODES][10];
|
||||
|
||||
static int numvidmodes; // total number of DirectDraw display modes
|
||||
static vmode_t *pvidmodes; // start of videomodes list.
|
||||
static vmode_t *pcurrentmode; // the current active videomode.
|
||||
static BOOL bWinParm;
|
||||
static int WINAPI VID_SetWindowedDisplayMode(viddef_t *lvid, vmode_t *pcurrentmode);
|
||||
|
||||
// this holds description of the startup video mode,
|
||||
// the resolution is 320x200, windowed on the desktop
|
||||
#define NUMSPECIALMODES 1
|
||||
static char winmode1[] ="320x200W"; // W to make sure it's the windowed mode
|
||||
static vmode_t specialmodes[NUMSPECIALMODES] =
|
||||
{
|
||||
{
|
||||
NULL,
|
||||
winmode1, // hehe
|
||||
320, 200, //(200.0/320.0)*(320.0/240.0),
|
||||
320, 1, // rowbytes, bytes per pixel
|
||||
1, 2, // windowed (TRUE), numpages
|
||||
NULL,
|
||||
VID_SetWindowedDisplayMode, 0
|
||||
}
|
||||
};
|
||||
|
||||
// ------
|
||||
// Protos
|
||||
// ------
|
||||
static void VID_Command_NumModes_f(void);
|
||||
static void VID_Command_ModeInfo_f(void);
|
||||
static void VID_Command_ModeList_f(void);
|
||||
static void VID_Command_Mode_f(void);
|
||||
static int WINAPI VID_SetDirectDrawMode(viddef_t *lvid, vmode_t *pcurrentmode);
|
||||
static vmode_t *VID_GetModePtr(int modenum);
|
||||
static void VID_Init(void);
|
||||
static BOOL VID_FreeAndAllocVidbuffer(viddef_t *lvid);
|
||||
|
||||
// -----------------
|
||||
// I_StartupGraphics
|
||||
// Initialize video mode, setup dynamic screen size variables,
|
||||
// and allocate screens.
|
||||
// -----------------
|
||||
void I_StartupGraphics(void)
|
||||
{
|
||||
if (graphics_started)
|
||||
return;
|
||||
|
||||
if (dedicated)
|
||||
rendermode = render_none;
|
||||
else
|
||||
VID_Init();
|
||||
|
||||
// register exit code for graphics
|
||||
I_AddExitFunc(I_ShutdownGraphics);
|
||||
if (!dedicated) graphics_started = true;
|
||||
}
|
||||
|
||||
// ------------------
|
||||
// I_ShutdownGraphics
|
||||
// Close the screen, restore previous video mode.
|
||||
// ------------------
|
||||
void I_ShutdownGraphics(void)
|
||||
{
|
||||
if (!graphics_started)
|
||||
return;
|
||||
|
||||
CONS_Printf("I_ShutdownGraphics()\n");
|
||||
|
||||
//FreeConsole();
|
||||
|
||||
// release windowed startup stuff
|
||||
if (hDCMain)
|
||||
{
|
||||
ReleaseDC(hWndMain, hDCMain);
|
||||
hDCMain = NULL;
|
||||
}
|
||||
if (bmiMain)
|
||||
{
|
||||
GlobalFree(bmiMain);
|
||||
bmiMain = NULL;
|
||||
}
|
||||
|
||||
// free the last video mode screen buffers
|
||||
if (vid.buffer)
|
||||
{
|
||||
GlobalFree(vid.buffer);
|
||||
vid.buffer = NULL;
|
||||
}
|
||||
|
||||
CloseDirectDraw();
|
||||
|
||||
graphics_started = false;
|
||||
}
|
||||
|
||||
// --------------
|
||||
// I_UpdateNoBlit
|
||||
// --------------
|
||||
void I_UpdateNoBlit(void)
|
||||
{
|
||||
// what is this?
|
||||
}
|
||||
|
||||
// --------------
|
||||
// I_FinishUpdate
|
||||
// --------------
|
||||
void I_FinishUpdate(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (rendermode == render_none)
|
||||
return;
|
||||
|
||||
// display a graph of ticrate
|
||||
if (cv_ticrate.value)
|
||||
SCR_DisplayTicRate();
|
||||
|
||||
if (cv_showping.value && netgame && consoleplayer != serverplayer)
|
||||
SCR_DisplayLocalPing();
|
||||
|
||||
//
|
||||
if (bDIBMode)
|
||||
{
|
||||
// paranoia
|
||||
if (!hDCMain || !bmiMain || !vid.buffer)
|
||||
return;
|
||||
// main game loop, still in a window (-win parm)
|
||||
SetDIBitsToDevice(hDCMain, 0, 0, 320, 200, 0, 0, 0, 200, vid.buffer, bmiMain,
|
||||
DIB_RGB_COLORS);
|
||||
}
|
||||
else
|
||||
{
|
||||
// DIRECT DRAW
|
||||
// copy virtual screen to real screen
|
||||
// can fail when not active (alt-tab)
|
||||
if (LockScreen())
|
||||
{
|
||||
/// \todo use directX blit here!!? a blit might use hardware with access
|
||||
/// to main memory on recent hardware, and software blit of directX may be
|
||||
/// optimized for p2 or mmx??
|
||||
VID_BlitLinearScreen(screens[0], ScreenPtr, vid.width*vid.bpp, vid.height,
|
||||
vid.width*vid.bpp, ScreenPitch);
|
||||
|
||||
UnlockScreen();
|
||||
|
||||
// swap screens
|
||||
ScreenFlip(cv_vidwait.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// This is meant to be called only by CONS_Printf() while game startup
|
||||
//
|
||||
void I_LoadingScreen(LPCSTR msg)
|
||||
{
|
||||
RECT rect;
|
||||
|
||||
// paranoia
|
||||
if (!hDCMain || !bmiMain || !vid.buffer)
|
||||
return;
|
||||
|
||||
GetClientRect(vid.WndParent, &rect);
|
||||
|
||||
SetDIBitsToDevice(hDCMain, 0, 0, 320, 200, 0, 0, 0, 200, vid.buffer, bmiMain, DIB_RGB_COLORS);
|
||||
|
||||
if (msg)
|
||||
{
|
||||
if (rect.bottom - rect.top > 32)
|
||||
rect.top = rect.bottom - 32; // put msg on bottom of window
|
||||
SetBkMode(hDCMain, TRANSPARENT);
|
||||
SetTextColor(hDCMain, RGB(0x00, 0x00, 0x00));
|
||||
DrawTextA(hDCMain, msg, -1, &rect, DT_WORDBREAK|DT_CENTER);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------
|
||||
// I_ReadScreen
|
||||
// ------------
|
||||
void I_ReadScreen(UINT8 *scr)
|
||||
{
|
||||
// DEBUGGING
|
||||
if (rendermode != render_soft)
|
||||
I_Error("I_ReadScreen: called while in non-software mode");
|
||||
VID_BlitLinearScreen(screens[0], scr, vid.width*vid.bpp, vid.height, vid.width*vid.bpp,
|
||||
vid.rowbytes);
|
||||
}
|
||||
|
||||
// ------------
|
||||
// I_SetPalette
|
||||
// ------------
|
||||
void I_SetPalette(RGBA_t *palette)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (bDIBMode)
|
||||
{
|
||||
// set palette in RGBQUAD format, NOT THE SAME ORDER as PALETTEENTRY, grmpf!
|
||||
RGBQUAD *pColors;
|
||||
pColors = (RGBQUAD *)((char *)bmiMain + bmiMain->bmiHeader.biSize);
|
||||
ZeroMemory(pColors, sizeof (RGBQUAD)*256);
|
||||
for (i = 0; i < 256; i++, pColors++, palette++)
|
||||
{
|
||||
pColors->rgbRed = palette->s.red;
|
||||
pColors->rgbGreen = palette->s.green;
|
||||
pColors->rgbBlue = palette->s.blue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PALETTEENTRY mainpal[256];
|
||||
|
||||
// this clears the 'flag' for each color in palette
|
||||
ZeroMemory(mainpal, sizeof mainpal);
|
||||
|
||||
// set palette in PALETTEENTRY format
|
||||
for (i = 0; i < 256; i++, palette++)
|
||||
{
|
||||
mainpal[i].peRed = palette->s.red;
|
||||
mainpal[i].peGreen = palette->s.green;
|
||||
mainpal[i].peBlue = palette->s.blue;
|
||||
}
|
||||
SetDDPalette(mainpal); // set DirectDraw palette
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// return number of video modes in pvidmodes list
|
||||
//
|
||||
INT32 VID_NumModes(void)
|
||||
{
|
||||
return numvidmodes - NUMSPECIALMODES; //faB: dont accept the windowed mode 0
|
||||
}
|
||||
|
||||
// return a video mode number from the dimensions
|
||||
// returns any available video mode if the mode was not found
|
||||
INT32 VID_GetModeForSize(INT32 w, INT32 h)
|
||||
{
|
||||
vmode_t *pv = pvidmodes;
|
||||
int modenum = 0;
|
||||
|
||||
// skip the special modes so that it finds only fullscreen modes
|
||||
for (; pv && modenum < NUMSPECIALMODES; pv = pv->pnext, ++modenum);
|
||||
for (; pv; pv = pv->pnext, ++modenum)
|
||||
if (pv->width == (unsigned)w && pv->height == (unsigned)h)
|
||||
return modenum;
|
||||
|
||||
// if not found, return the first mode available,
|
||||
// preferably a full screen mode (all modes after the 'specialmodes')
|
||||
if (numvidmodes > NUMSPECIALMODES)
|
||||
return NUMSPECIALMODES; // use first full screen mode
|
||||
|
||||
return 0; // no fullscreen mode, use windowed mode
|
||||
}
|
||||
|
||||
//
|
||||
// Enumerate DirectDraw modes available
|
||||
//
|
||||
static int nummodes = 0;
|
||||
static BOOL GetExtraModesCallback(int width, int height, int bpp)
|
||||
{
|
||||
CONS_Printf("mode %d x %d x %d bpp\n", width, height, bpp);
|
||||
|
||||
// skip all unwanted modes
|
||||
if (highcolor && bpp != 15)
|
||||
goto skip;
|
||||
if (!highcolor && bpp != 8)
|
||||
goto skip;
|
||||
|
||||
if (bpp > 16 || width > MAXVIDWIDTH || height > MAXVIDHEIGHT)
|
||||
goto skip;
|
||||
|
||||
// check if we have space for this mode
|
||||
if (nummodes >= MAX_EXTRA_MODES)
|
||||
{
|
||||
CONS_Printf("mode skipped (too many)\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// store mode info
|
||||
extra_modes[nummodes].pnext = &extra_modes[nummodes+1];
|
||||
memset(names[nummodes], 0, 10);
|
||||
snprintf(names[nummodes], 9, "%dx%d", width, height);
|
||||
|
||||
extra_modes[nummodes].name = names[nummodes];
|
||||
extra_modes[nummodes].width = width;
|
||||
extra_modes[nummodes].height = height;
|
||||
|
||||
// exactly, the current FinishUdpate() gets the rowbytes itself after locking the video buffer
|
||||
// so for now we put anything here
|
||||
extra_modes[nummodes].rowbytes = width;
|
||||
extra_modes[nummodes].windowed = false;
|
||||
extra_modes[nummodes].misc = 0; // unused
|
||||
extra_modes[nummodes].pextradata = NULL;
|
||||
extra_modes[nummodes].setmode = VID_SetDirectDrawMode;
|
||||
|
||||
extra_modes[nummodes].numpages = 2; // double-buffer (but this value is unused)
|
||||
|
||||
extra_modes[nummodes].bytesperpixel = (bpp+1)>>3;
|
||||
|
||||
nummodes++;
|
||||
skip:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Collect info about DirectDraw display modes we use
|
||||
//
|
||||
static inline void VID_GetExtraModes(void)
|
||||
{
|
||||
nummodes = 0;
|
||||
EnumDirectDrawDisplayModes(GetExtraModesCallback);
|
||||
|
||||
// add the extra modes (not 320x200) at the start of the mode list (if there are any)
|
||||
if (nummodes)
|
||||
{
|
||||
extra_modes[nummodes-1].pnext = NULL;
|
||||
pvidmodes = &extra_modes[0];
|
||||
numvidmodes += nummodes;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------
|
||||
// WindowMode_Init
|
||||
// Add windowed modes to the start of the list,
|
||||
// mode 0 is used for windowed console startup (works on all computers with no DirectX)
|
||||
// ---------------
|
||||
static void WindowMode_Init(void)
|
||||
{
|
||||
specialmodes[NUMSPECIALMODES-1].pnext = pvidmodes;
|
||||
pvidmodes = &specialmodes[0];
|
||||
numvidmodes += NUMSPECIALMODES;
|
||||
}
|
||||
|
||||
// *************************************************************************************
|
||||
// VID_Init
|
||||
// Initialize Video modes subsystem
|
||||
// *************************************************************************************
|
||||
static void VID_Init(void)
|
||||
{
|
||||
vmode_t *pv;
|
||||
int iMode;
|
||||
|
||||
// if '-win' is specified on the command line, do not add DirectDraw modes
|
||||
bWinParm = M_CheckParm("-win");
|
||||
|
||||
COM_AddCommand("vid_nummodes", VID_Command_NumModes_f);
|
||||
COM_AddCommand("vid_modeinfo", VID_Command_ModeInfo_f);
|
||||
COM_AddCommand("vid_modelist", VID_Command_ModeList_f);
|
||||
COM_AddCommand("vid_mode", VID_Command_Mode_f);
|
||||
|
||||
CV_RegisterVar(&cv_vidwait);
|
||||
CV_RegisterVar(&cv_stretch);
|
||||
|
||||
// setup the videmodes list,
|
||||
// note that mode 0 must always be VGA mode 0x13
|
||||
pvidmodes = pcurrentmode = NULL;
|
||||
numvidmodes = 0;
|
||||
|
||||
// store the main window handle in viddef struct
|
||||
SetWindowPos(hWndMain, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE|SWP_NOSENDCHANGING|SWP_NOSIZE|SWP_NOMOVE);
|
||||
vid.WndParent = hWndMain;
|
||||
vid.buffer = NULL;
|
||||
|
||||
// we startup in windowed mode using DIB bitmap
|
||||
// we will use DirectDraw when switching fullScreen and entering main game loop
|
||||
bDIBMode = TRUE;
|
||||
bAppFullScreen = FALSE;
|
||||
|
||||
if (!bWinParm)
|
||||
{
|
||||
if (!CreateDirectDrawInstance())
|
||||
I_Error("Error initializing DirectDraw");
|
||||
// get available display modes for the device
|
||||
VID_GetExtraModes();
|
||||
}
|
||||
|
||||
// the game boots in 320x200 standard VGA, but
|
||||
// we need a highcolor mode to run the game in highcolor
|
||||
if (highcolor && !numvidmodes)
|
||||
I_Error("Cannot run in highcolor - No 15bit highcolor DirectX video mode found.");
|
||||
|
||||
// add windowed mode at the start of the list, very important!
|
||||
WindowMode_Init();
|
||||
|
||||
if (!numvidmodes)
|
||||
I_Error("No display modes available.");
|
||||
|
||||
// DEBUG
|
||||
for (iMode = 0, pv = pvidmodes; pv; pv = pv->pnext, iMode++)
|
||||
CONS_Printf("#%02d: %dx%dx%dbpp (desc: '%s')\n", iMode, pv->width, pv->height,
|
||||
pv->bytesperpixel, pv->name);
|
||||
|
||||
// set the startup screen in a window
|
||||
VID_SetMode(0);
|
||||
}
|
||||
|
||||
// --------------------------
|
||||
// VID_SetWindowedDisplayMode
|
||||
// Display the startup 320x200 console screen into a window on the desktop,
|
||||
// switching to fullscreen display only when we will enter the main game loop.
|
||||
// - we can display error message boxes for startup errors
|
||||
// - we can set the last used resolution only once, when entering the main game loop
|
||||
// --------------------------
|
||||
static int WINAPI VID_SetWindowedDisplayMode(viddef_t *lvid, vmode_t *pcurrentmode)
|
||||
{
|
||||
int iScrWidth, iScrHeight, iWinWidth, iWinHeight;
|
||||
|
||||
pcurrentmode = NULL;
|
||||
#ifdef DEBUG
|
||||
CONS_Printf("VID_SetWindowedDisplayMode()\n");
|
||||
#endif
|
||||
|
||||
lvid->u.numpages = 1; // not used
|
||||
lvid->direct = NULL; // DOS remains
|
||||
lvid->buffer = NULL;
|
||||
|
||||
// allocate screens
|
||||
if (!VID_FreeAndAllocVidbuffer(lvid))
|
||||
return -1;
|
||||
|
||||
// lvid->buffer should be NULL here!
|
||||
|
||||
bmiMain = (void *)GlobalAlloc(GPTR, sizeof (BITMAPINFO) + (sizeof (RGBQUAD)*256));
|
||||
if (!bmiMain)
|
||||
I_Error("VID_SWDM(): No mem");
|
||||
|
||||
// setup a BITMAPINFO to allow copying our video buffer to the desktop,
|
||||
// with color conversion as needed
|
||||
bmiMain->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
|
||||
bmiMain->bmiHeader.biWidth = lvid->width;
|
||||
bmiMain->bmiHeader.biHeight= -(lvid->height);
|
||||
bmiMain->bmiHeader.biPlanes = 1;
|
||||
bmiMain->bmiHeader.biBitCount = 8;
|
||||
bmiMain->bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
// center window on the desktop
|
||||
iScrWidth = GetSystemMetrics(SM_CXFULLSCREEN);
|
||||
iScrHeight = GetSystemMetrics(SM_CYFULLSCREEN);
|
||||
|
||||
iWinWidth = lvid->width;
|
||||
iWinWidth += GetSystemMetrics(SM_CXFIXEDFRAME) * 2;
|
||||
|
||||
iWinHeight = lvid->height;
|
||||
iWinHeight += GetSystemMetrics(SM_CYCAPTION);
|
||||
iWinHeight += GetSystemMetrics(SM_CYFIXEDFRAME) * 2;
|
||||
|
||||
if (devparm)
|
||||
MoveWindow(hWndMain, (iScrWidth - iWinWidth), (iScrHeight - iWinHeight), iWinWidth, iWinHeight, TRUE);
|
||||
else
|
||||
MoveWindow(hWndMain, (iScrWidth - iWinWidth)>>1, (iScrHeight - iWinHeight)>>1, iWinWidth, iWinHeight, TRUE);
|
||||
|
||||
SetFocus(hWndMain);
|
||||
ShowWindow(hWndMain, SW_SHOW);
|
||||
|
||||
hDCMain = GetDC(hWndMain);
|
||||
if (!hDCMain)
|
||||
I_Error("VID_SWDM(): GetDC FAILED");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// Returns a vmode_t from the video modes list, given a video mode number.
|
||||
// ========================================================================
|
||||
vmode_t *VID_GetModePtr(int modenum)
|
||||
{
|
||||
vmode_t *pv;
|
||||
|
||||
pv = pvidmodes;
|
||||
if (!pv)
|
||||
I_Error("VID_error: No video mode found\n");
|
||||
|
||||
while (modenum--)
|
||||
{
|
||||
pv = pv->pnext;
|
||||
if (!pv)
|
||||
I_Error("VID_error: Mode not available\n");
|
||||
}
|
||||
return pv;
|
||||
}
|
||||
|
||||
//
|
||||
// return the name of a video mode
|
||||
//
|
||||
const char *VID_GetModeName(INT32 modenum)
|
||||
{
|
||||
return (VID_GetModePtr(modenum))->name;
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// Sets a video mode
|
||||
// ========================================================================
|
||||
INT32 VID_SetMode(INT32 modenum)
|
||||
{
|
||||
int stat;
|
||||
vmode_t *pnewmode;
|
||||
vmode_t *poldmode;
|
||||
|
||||
if (dedicated)
|
||||
return 0;
|
||||
|
||||
CONS_Printf("VID_SetMode(%d)\n", modenum);
|
||||
|
||||
// if mode 0 (windowed) we must not be fullscreen already,
|
||||
// if other mode, check it is not mode 0 and existing
|
||||
if (modenum >= numvidmodes)
|
||||
{
|
||||
if (!pcurrentmode)
|
||||
modenum = 0; // revert to the default base vid mode
|
||||
else
|
||||
I_Error("Unknown video mode: %d\n", modenum);
|
||||
}
|
||||
else if (bAppFullScreen && modenum < NUMSPECIALMODES)
|
||||
I_Error("Tried to switch from fullscreen back to windowed mode %d\n", modenum);
|
||||
|
||||
pnewmode = VID_GetModePtr(modenum);
|
||||
|
||||
// dont switch to the same display mode
|
||||
if (pnewmode == pcurrentmode)
|
||||
return 1;
|
||||
|
||||
// initialize the new mode
|
||||
poldmode = pcurrentmode;
|
||||
pcurrentmode = pnewmode;
|
||||
|
||||
// initialize vidbuffer size for setmode
|
||||
vid.width = pcurrentmode->width;
|
||||
vid.height = pcurrentmode->height;
|
||||
vid.rowbytes = pcurrentmode->rowbytes;
|
||||
vid.bpp = pcurrentmode->bytesperpixel;
|
||||
if (modenum) // if not 320x200 windowed mode, it's actually a hack
|
||||
{
|
||||
if (rendermode == render_opengl)
|
||||
{
|
||||
// don't accept depth < 16 for OpenGL mode (too much ugly)
|
||||
if (cv_scr_depth.value < 16)
|
||||
CV_SetValue(&cv_scr_depth, 16);
|
||||
vid.bpp = cv_scr_depth.value/8;
|
||||
vid.u.windowed = (bWinParm || !cv_fullscreen.value);
|
||||
pcurrentmode->bytesperpixel = vid.bpp;
|
||||
pcurrentmode->windowed = vid.u.windowed;
|
||||
}
|
||||
}
|
||||
|
||||
stat = (*pcurrentmode->setmode)(&vid, pcurrentmode);
|
||||
|
||||
if (stat == -1)
|
||||
I_Error("Not enough mem for VID_SetMode\n");
|
||||
else if (stat == -2)
|
||||
I_Error("Couldn't set video mode because it failed the test\n");
|
||||
else if (stat == -3)
|
||||
I_Error("Couldn't set video mode because it failed the change?\n");
|
||||
else if (!stat)
|
||||
I_Error("Couldn't set video mode %d (%dx%d %d bits)\n", modenum, vid.width, vid.height, (vid.bpp*8));// hardware could not setup mode
|
||||
else
|
||||
CONS_Printf(M_GetText("Mode changed to %d (%s)\n"), modenum, pcurrentmode->name);
|
||||
|
||||
vid.modenum = modenum;
|
||||
|
||||
// tell game engine to recalc all tables and realloc buffers based on new values
|
||||
vid.recalc = 1;
|
||||
|
||||
if (modenum < NUMSPECIALMODES)
|
||||
{
|
||||
// we are in startup windowed mode
|
||||
bAppFullScreen = FALSE;
|
||||
bDIBMode = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we switch to fullscreen
|
||||
bAppFullScreen = TRUE;
|
||||
bDIBMode = FALSE;
|
||||
}
|
||||
|
||||
I_RestartSysMouse();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// Free the video buffer of the last video mode,
|
||||
// allocate a new buffer for the video mode to set.
|
||||
// ========================================================================
|
||||
static BOOL VID_FreeAndAllocVidbuffer(viddef_t *lvid)
|
||||
{
|
||||
const DWORD vidbuffersize = (lvid->width * lvid->height * lvid->bpp * NUMSCREENS);
|
||||
|
||||
// free allocated buffer for previous video mode
|
||||
if (lvid->buffer)
|
||||
GlobalFree(lvid->buffer);
|
||||
|
||||
// allocate & clear the new screen buffer
|
||||
lvid->buffer = GlobalAlloc(GPTR, vidbuffersize);
|
||||
if (!lvid->buffer)
|
||||
return FALSE;
|
||||
|
||||
ZeroMemory(lvid->buffer, vidbuffersize);
|
||||
#ifdef DEBUG
|
||||
CONS_Printf("VID_FreeAndAllocVidbuffer done, vidbuffersize: %x\n",vidbuffersize);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// Set video mode routine for DirectDraw display modes
|
||||
// Out: 1 ok,
|
||||
// 0 hardware could not set mode,
|
||||
// -1 no mem
|
||||
// ========================================================================
|
||||
static int WINAPI VID_SetDirectDrawMode(viddef_t *lvid, vmode_t *pcurrentmode)
|
||||
{
|
||||
pcurrentmode = NULL;
|
||||
#ifdef DEBUG
|
||||
CONS_Printf("VID_SetDirectDrawMode...\n");
|
||||
#endif
|
||||
|
||||
// DD modes do double-buffer page flipping, but the game engine doesn't need this..
|
||||
lvid->u.numpages = 2;
|
||||
|
||||
// release ddraw surfaces etc..
|
||||
ReleaseChtuff();
|
||||
|
||||
// clean up any old vid buffer lying around, alloc new if needed
|
||||
if (!VID_FreeAndAllocVidbuffer(lvid))
|
||||
return -1; // no mem
|
||||
|
||||
// should clear video mem here
|
||||
|
||||
// note use lvid->bpp instead of 8...will this be needed? will we support other than 256color
|
||||
// in software ?
|
||||
if (!InitDirectDrawe(hWndMain, lvid->width, lvid->height, 8, TRUE)) // TRUE currently always full screen
|
||||
return 0; // could not set mode
|
||||
|
||||
// this is NOT used with DirectDraw modes, game engine should never use this directly
|
||||
// but rather render to memory bitmap buffer
|
||||
lvid->direct = NULL;
|
||||
|
||||
if (!cv_stretch.value && (float)vid.width/vid.height != ((float)BASEVIDWIDTH/BASEVIDHEIGHT))
|
||||
vid.height = (int)(vid.width * ((float)BASEVIDHEIGHT/BASEVIDWIDTH));// Adjust the height to match
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// VIDEO MODE CONSOLE COMMANDS
|
||||
// ========================================================================
|
||||
|
||||
// vid_nummodes
|
||||
//
|
||||
static void VID_Command_NumModes_f(void)
|
||||
{
|
||||
CONS_Printf(M_GetText("%d video mode(s) available(s)\n"), VID_NumModes());
|
||||
}
|
||||
|
||||
// vid_modeinfo <modenum>
|
||||
//
|
||||
static void VID_Command_ModeInfo_f(void)
|
||||
{
|
||||
vmode_t *pv;
|
||||
int modenum;
|
||||
|
||||
if (COM_Argc() != 2)
|
||||
modenum = vid.modenum; // describe the current mode
|
||||
else
|
||||
modenum = atoi(COM_Argv(1)); // the given mode number
|
||||
|
||||
if (modenum >= VID_NumModes() || modenum < NUMSPECIALMODES) // don't accept the windowed mode 0
|
||||
{
|
||||
CONS_Printf(M_GetText("Video mode not present\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
pv = VID_GetModePtr(modenum);
|
||||
|
||||
CONS_Printf("%s\n", VID_GetModeName(modenum));
|
||||
CONS_Printf(M_GetText("width: %d\nheight: %d\n"),
|
||||
pv->width, pv->height);
|
||||
if (rendermode == render_soft)
|
||||
CONS_Printf(M_GetText("bytes per scanline: %d\nbytes per pixel: %d\nnumpages: %d\n"),
|
||||
pv->rowbytes, pv->bytesperpixel, pv->numpages);
|
||||
}
|
||||
|
||||
// vid_modelist
|
||||
//
|
||||
static void VID_Command_ModeList_f(void)
|
||||
{
|
||||
int i, nummodes;
|
||||
const char *pinfo;
|
||||
vmode_t *pv;
|
||||
|
||||
nummodes = VID_NumModes();
|
||||
for (i = NUMSPECIALMODES; i <= nummodes; i++)
|
||||
{
|
||||
pv = VID_GetModePtr(i);
|
||||
pinfo = VID_GetModeName(i);
|
||||
|
||||
if (pv->bytesperpixel == 1)
|
||||
CONS_Printf("%d: %s\n", i, pinfo);
|
||||
else
|
||||
CONS_Printf("%d: %s (hicolor)\n", i, pinfo);
|
||||
}
|
||||
}
|
||||
|
||||
// vid_mode <modenum>
|
||||
//
|
||||
static void VID_Command_Mode_f(void)
|
||||
{
|
||||
int modenum;
|
||||
|
||||
if (COM_Argc() != 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("vid_mode <modenum> : set video mode, current video mode %i\n"), vid.modenum);
|
||||
return;
|
||||
}
|
||||
|
||||
modenum = atoi(COM_Argv(1));
|
||||
|
||||
if (modenum >= VID_NumModes() || modenum < NUMSPECIALMODES) // don't accept the windowed mode 0
|
||||
CONS_Printf(M_GetText("Video mode not present\n"));
|
||||
else
|
||||
setmodeneeded = modenum + 1; // request vid mode change
|
||||
}
|
||||
Loading…
Reference in a new issue