One of the biggest things keeping -mem/-heapsize numbers up is the video

memory in software mode. This is now taken care of, the memory is now
grabbed using calloc.

On Unix systems and all systems using SDL, the default video memory is now
8MB. This should now be enough for almost everybody, unless you have some
truly huge maps and boatloads of sounds. The minimum memory allowable is
now down to 4MB, but complex maps and/or models can cause the game to quit
-- not like this wasn't a problem already with the old 5.3MB lower limit,
but there it is.
This commit is contained in:
Jeff Teunissen 2000-10-18 10:16:11 +00:00
parent 2682888425
commit 17ea696c0d
10 changed files with 258 additions and 168 deletions

View file

@ -40,7 +40,8 @@
#define UNUSED(x) (x = x) // for pesky compiler / lint warnings
#define MINIMUM_MEMORY 0x550000
// Error out if we get less than 4MB
#define MINIMUM_MEMORY 0x400000

View file

@ -160,6 +160,7 @@ void R_DrawWaterSurfaces (void);
extern int reinit_surfcache; // if 1, surface cache is currently empty and
extern qboolean r_cache_thrash; // set if thrashing the surface cache
void *D_SurfaceCacheAddress (void);
int D_SurfaceCacheForRes (int width, int height);
void D_FlushCaches (void);
void D_DeleteSurfaceCache (void);

View file

@ -226,7 +226,7 @@ int main (int c, char **v)
parms.argc = com_argc;
parms.argv = com_argv;
parms.memsize = 16*1024*1024;
parms.memsize = 8 * 1024 * 1024; // 8MB default heap
j = COM_CheckParm("-mem");
if (j)

View file

@ -205,7 +205,7 @@ void Sys_Init (void)
if ((vinfo.dwMajorVersion < 4) ||
(vinfo.dwPlatformId == VER_PLATFORM_WIN32s))
{
Sys_Error ("This version of " PROGRAM " requires at least Win95 or NT 4.0");
Sys_Error ("This version of " PROGRAM " requires a full Win32 implementation.");
}
if (vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT)

View file

@ -39,13 +39,19 @@
float surfscale;
qboolean r_cache_thrash; // set if surface cache is thrashing
int sc_size;
surfcache_t *sc_rover, *sc_base;
int sc_size;
surfcache_t *sc_rover, *sc_base;
#define GUARDSIZE 4
void *
D_SurfaceCacheAddress (void)
{
return sc_base;
}
int D_SurfaceCacheForRes (int width, int height)
int
D_SurfaceCacheForRes (int width, int height)
{
int size, pix;

View file

@ -105,11 +105,6 @@ static int stride, drawstride;
static int pixelsize;
static int usedbuf, havedbuf;
static long GGI_highhunkmark, GGI_buffersize;
static int vid_surfcachesize;
static void *vid_surfcache;
int VID_options_items = 1;
static void
@ -228,44 +223,54 @@ do_copy32(int xsize, int ysize, uint32 *dest, uint8 *src)
}
// ========================================================================
// Tragic death handler
// ========================================================================
void ResetFrameBuffer(void)
void
ResetFrameBuffer(void)
{
if (d_pzbuffer)
{
D_FlushCaches ();
Hunk_FreeToHighMark (GGI_highhunkmark);
int tbuffersize, tcachesize;
void *vid_surfcache;
// Calculate the sizes we want first
tbuffersize = vid.width * vid.height * sizeof (*d_pzbuffer);
tcachesize = D_SurfaceCacheForRes(vid.width, vid.height);
// Free the old z-buffer
if (d_pzbuffer) {
free (d_pzbuffer);
d_pzbuffer = NULL;
}
GGI_highhunkmark = Hunk_HighMark ();
// Free the old surface cache
vid_surfcache = D_SurfaceCacheAddress ();
if (vid_surfcache) {
D_FlushCaches ();
free (vid_surfcache);
vid_surfcache = NULL;
}
// alloc an extra line in case we want to wrap, and allocate the z-buffer
GGI_buffersize = vid.width * vid.height * sizeof (*d_pzbuffer);
vid_surfcachesize = D_SurfaceCacheForRes (vid.width, vid.height);
GGI_buffersize += vid_surfcachesize;
d_pzbuffer = Hunk_HighAllocName (GGI_buffersize, "video");
if (d_pzbuffer == NULL)
// Allocate the new z-buffer
d_pzbuffer = calloc (tbuffersize, 1);
if (!d_pzbuffer) {
Sys_Error ("Not enough memory for video mode\n");
}
vid_surfcache = (byte *) d_pzbuffer
+ vid.width * vid.height * sizeof (*d_pzbuffer);
// Allocate the new surface cache; free the z-buffer if we fail
vid_surfcache = calloc (tcachesize, 1);
if (!vid_surfcache) {
free (d_pzbuffer);
d_pzbuffer = NULL;
Sys_Error ("Not enough memory for video mode\n");
}
D_InitCaches(vid_surfcache, vid_surfcachesize);
D_InitCaches (vid_surfcache, tcachesize);
}
// Called at startup to set up translation tables, takes 256 8 bit RGB values
// the palette data will go away after the call, so it must be copied off if
// the video driver will need it again
void VID_Init(unsigned char *pal)
void
VID_Init (unsigned char *pal)
{
int pnum;
@ -456,14 +461,15 @@ void VID_Init(unsigned char *pal)
vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
}
void VID_ShiftPalette(unsigned char *pal)
void
VID_ShiftPalette(unsigned char *pal)
{
VID_SetPalette(pal);
}
void VID_SetPalette(unsigned char *pal)
void
VID_SetPalette (unsigned char *pal)
{
int i;
@ -483,7 +489,8 @@ void VID_SetPalette(unsigned char *pal)
// Called at shutdown
void VID_Shutdown (void)
void
VID_Shutdown (void)
{
Con_Printf("VID_Shutdown\n");
@ -509,7 +516,8 @@ void VID_Shutdown (void)
// flushes the given rectangles from the view buffer to the screen
void VID_Update(vrect_t *rects)
void
VID_Update (vrect_t *rects)
{
int height = 0;

View file

@ -266,20 +266,6 @@ VID_CheckAdequateMem
*/
qboolean VID_CheckAdequateMem (int width, int height)
{
int tbuffersize;
tbuffersize = width * height * sizeof (*d_pzbuffer);
tbuffersize += D_SurfaceCacheForRes (width, height);
// see if there's enough memory, allowing for the normal mode 0x13 pixel,
// z, and surface buffers
if ((host_parms.memsize - tbuffersize + SURFCACHE_SIZE_AT_320X200 +
0x10000 * 3) < MINIMUM_MEMORY)
{
return false; // not enough memory for mode
}
return true;
}
@ -289,41 +275,46 @@ qboolean VID_CheckAdequateMem (int width, int height)
VID_AllocBuffers
================
*/
qboolean VID_AllocBuffers (int width, int height)
qboolean
VID_AllocBuffers (int width, int height)
{
int tsize, tbuffersize;
int tbuffersize, tcachesize;
void *temp_z, *temp_sc;
tbuffersize = width * height * sizeof (*d_pzbuffer);
tcachesize = D_SurfaceCacheForRes (width, height);
tsize = D_SurfaceCacheForRes (width, height);
tbuffersize += tsize;
// see if there's enough memory, allowing for the normal mode 0x13 pixel,
// z, and surface buffers
if ((host_parms.memsize - tbuffersize + SURFCACHE_SIZE_AT_320X200 +
0x10000 * 3) < MINIMUM_MEMORY)
{
Con_Printf ("Not enough memory for video mode\n");
return false; // not enough memory for mode
// Allocate the new z-buffer
temp_z = calloc (tbuffersize, 1);
if (temp_z == NULL) {
Sys_Printf ("Not enough memory for video mode\n");
return false;
}
vid_surfcachesize = tsize;
// Allocate the new surface cache
temp_sc = calloc (tcachesize, 1);
if (temp_sc == NULL) {
free (temp_z);
Sys_Printf ("Not enough memory for video mode\n");
return false;
}
if (d_pzbuffer)
{
// Free the old z-buffer, switch to the new one
if (d_pzbuffer) {
free (d_pzbuffer);
d_pzbuffer = temp_z;
temp_z = NULL;
}
// Free surface cache, switch to the new one
vid_surfcache = D_SurfaceCacheAddress ();
if (vid_surfcache) {
D_FlushCaches ();
Hunk_FreeToHighMark (VID_highhunkmark);
d_pzbuffer = NULL;
free (vid_surfcache);
vid_surfcache = temp_sc;
temp_sc = NULL;
}
VID_highhunkmark = Hunk_HighMark ();
d_pzbuffer = Hunk_HighAllocName (tbuffersize, "video");
vid_surfcache = (byte *)d_pzbuffer +
width * height * sizeof (*d_pzbuffer);
return true;
}

View file

@ -81,6 +81,48 @@ static qboolean mouse_avail;
static float mouse_x, mouse_y;
static int mouse_oldbuttonstate = 0;
void
VID_InitBuffers (int width, int height)
{
int tbuffersize, tcachesize;
void *vid_surfcache;
// Calculate the sizes we want first
tbuffersize = vid.width * vid.height * sizeof (*d_pzbuffer);
tcachesize = D_SurfaceCacheForRes(width, height);
// Free the old z-buffer
if (d_pzbuffer) {
free (d_pzbuffer);
d_pzbuffer = NULL;
}
// Free the old surface cache
vid_surfcache = D_SurfaceCacheAddress ();
if (vid_surfcache) {
D_FlushCaches ();
free (vid_surfcache);
vid_surfcache = NULL;
}
// Allocate the new z-buffer
d_pzbuffer = calloc (tbuffersize, 1);
if (!d_pzbuffer) {
Sys_Error ("Not enough memory for video mode\n");
}
// Allocate the new surface cache; free the z-buffer if we fail
vid_surfcache = calloc (tcachesize, 1);
if (!vid_surfcache) {
free (d_pzbuffer);
d_pzbuffer = NULL;
Sys_Error ("Not enough memory for video mode\n");
}
D_InitCaches (vid_surfcache, tcachesize);
}
void
VID_SetPalette (unsigned char *palette)
{
@ -104,9 +146,7 @@ VID_ShiftPalette (unsigned char *palette)
void
VID_Init (unsigned char *palette)
{
int pnum, chunk;
byte *cache;
int cachesize;
int pnum;
//Uint8 video_bpp;
//Uint16 video_w, video_h;
Uint32 flags;
@ -155,16 +195,7 @@ VID_Init (unsigned char *palette)
vid.direct = 0;
// allocate z buffer and surface cache
chunk = vid.width * vid.height * sizeof (*d_pzbuffer);
cachesize = D_SurfaceCacheForRes (vid.width, vid.height);
chunk += cachesize;
d_pzbuffer = Hunk_HighAllocName(chunk, "video");
if (d_pzbuffer == NULL)
Sys_Error ("Not enough memory for video mode\n");
// initialize the cache memory
cache = (byte *) d_pzbuffer + vid.width * vid.height * sizeof (*d_pzbuffer);
D_InitCaches (cache, cachesize);
VID_InitBuffers (vid.width, vid.height);
// initialize the mouse
SDL_ShowCursor(0);

View file

@ -61,8 +61,6 @@ void VGA_UpdatePlanarScreen (void *srcbuffer);
unsigned short d_8to16table[256];
static byte *vid_surfcache;
static int VID_highhunkmark;
static int num_modes, current_mode;
static vga_modeinfo *modes;
@ -359,6 +357,65 @@ get_mode(char *name, int width, int height, int depth)
}
void
VID_InitBuffers (void)
{
int buffersize, zbuffersize, cachesize;
void *vid_surfcache;
// Calculate the sizes we want first
buffersize = vid.rowbytes * vid.height;
zbuffersize = vid.width * vid.height * sizeof (*d_pzbuffer);
cachesize = D_SurfaceCacheForRes(vid.width, vid.height);
// Free the old screen buffer
if (vid.buffer) {
free (vid.buffer);
vid.conbuffer = vid.buffer = NULL;
}
// Free the old z-buffer
if (d_pzbuffer) {
free (d_pzbuffer);
d_pzbuffer = NULL;
}
// Free the old surface cache
vid_surfcache = D_SurfaceCacheAddress ();
if (vid_surfcache) {
D_FlushCaches ();
free (vid_surfcache);
vid_surfcache = NULL;
}
// Allocate the new screen buffer
vid.conbuffer = vid.buffer = calloc (buffersize, 1);
if (!vid.conbuffer) {
Sys_Error ("Not enough memory for video mode\n");
}
// Allocate the new z-buffer
d_pzbuffer = calloc (zbuffersize, 1);
if (!d_pzbuffer) {
free (vid.buffer);
vid.conbuffer = vid.buffer = NULL;
Sys_Error ("Not enough memory for video mode\n");
}
// Allocate the new surface cache; free the z-buffer if we fail
vid_surfcache = calloc (cachesize, 1);
if (!vid_surfcache) {
free (vid.buffer);
free (d_pzbuffer);
vid.conbuffer = vid.buffer = NULL;
d_pzbuffer = NULL;
Sys_Error ("Not enough memory for video mode\n");
}
D_InitCaches (vid_surfcache, cachesize);
}
void
VID_Shutdown(void)
{
@ -407,7 +464,6 @@ VID_SetPalette(byte *palette)
int
VID_SetMode (int modenum, unsigned char *palette)
{
int bsize, zsize, tsize;
int err;
if ((modenum >= num_modes) || (modenum < 0) || !modes[modenum].width) {
@ -446,27 +502,8 @@ VID_SetMode (int modenum, unsigned char *palette)
vid.maxwarpwidth = WARP_WIDTH;
vid.maxwarpheight = WARP_HEIGHT;
/* alloc zbuffer and surface cache */
if (d_pzbuffer) {
D_FlushCaches();
Hunk_FreeToHighMark (VID_highhunkmark);
d_pzbuffer = NULL;
vid_surfcache = NULL;
}
bsize = vid.rowbytes * vid.height;
tsize = D_SurfaceCacheForRes (vid.width, vid.height);
zsize = vid.width * vid.height * sizeof(*d_pzbuffer);
VID_highhunkmark = Hunk_HighMark ();
d_pzbuffer = Hunk_HighAllocName (bsize+tsize+zsize, "video");
vid_surfcache = ((byte *)d_pzbuffer) + zsize;
vid.conbuffer = vid.buffer = (pixel_t *)(((byte *)d_pzbuffer) + zsize + tsize);
D_InitCaches (vid_surfcache, tsize);
// alloc screen buffer, z-buffer, and surface cache
VID_InitBuffers ();
/* get goin' */
err = vga_setmode(current_mode);

View file

@ -105,7 +105,7 @@ static int shiftmask_fl=0;
static long r_shift,g_shift,b_shift;
static unsigned long r_mask,g_mask,b_mask;
static long X11_highhunkmark;
//static long X11_highhunkmark;
int scr_width, scr_height;
@ -297,38 +297,48 @@ void VID_Gamma_f (void)
static void
ResetFrameBuffer(void)
{
int vid_surfcachesize, buffersize;
void *vid_surfcache;
int mem, pwidth;
int tbuffersize, tcachesize;
void *vid_surfcache;
int mem, pwidth;
// Calculate the sizes we want first
tbuffersize = vid.width * vid.height * sizeof (*d_pzbuffer);
tcachesize = D_SurfaceCacheForRes(vid.width, vid.height);
if (x_framebuffer[0]) {
XDestroyImage(x_framebuffer[0]);
}
// Free the old z-buffer
if (d_pzbuffer) {
D_FlushCaches ();
Hunk_FreeToHighMark(X11_highhunkmark);
free (d_pzbuffer);
d_pzbuffer = NULL;
}
X11_highhunkmark = Hunk_HighMark ();
// Free the old surface cache
vid_surfcache = D_SurfaceCacheAddress ();
if (vid_surfcache) {
D_FlushCaches ();
free (vid_surfcache);
vid_surfcache = NULL;
}
/* Alloc an extra line in case we want to wrap, and allocate
the z-buffer */
buffersize = vid.width * vid.height * sizeof(*d_pzbuffer);
vid_surfcachesize = D_SurfaceCacheForRes(vid.width, vid.height);
buffersize += vid_surfcachesize;
d_pzbuffer = Hunk_HighAllocName(buffersize, "video");
if (d_pzbuffer == NULL) {
// Allocate the new z-buffer
d_pzbuffer = calloc (tbuffersize, 1);
if (!d_pzbuffer) {
Sys_Error ("Not enough memory for video mode\n");
}
vid_surfcache = (byte *) d_pzbuffer
+ vid.width * vid.height * sizeof(*d_pzbuffer);
// Allocate the new surface cache; free the z-buffer if we fail
vid_surfcache = calloc (tcachesize, 1);
if (!vid_surfcache) {
free (d_pzbuffer);
d_pzbuffer = NULL;
Sys_Error ("Not enough memory for video mode\n");
}
D_InitCaches(vid_surfcache, vid_surfcachesize);
D_InitCaches (vid_surfcache, tcachesize);
pwidth = x_visinfo->depth / 8;
if (pwidth == 3) pwidth = 4;
@ -349,53 +359,59 @@ ResetFrameBuffer(void)
static void
ResetSharedFrameBuffers(void)
{
int vid_surfcachesize, buffersize;
void *vid_surfcache;
int tbuffersize, tcachesize;
void *vid_surfcache;
int size;
int key;
int minsize = getpagesize();
int frm;
if (d_pzbuffer) {
D_FlushCaches ();
Hunk_FreeToHighMark(X11_highhunkmark);
// Calculate the sizes we want first
tbuffersize = vid.width * vid.height * sizeof (*d_pzbuffer);
tcachesize = D_SurfaceCacheForRes(vid.width, vid.height);
// Free the old z-buffer
if (d_pzbuffer) {
free (d_pzbuffer);
d_pzbuffer = NULL;
}
// Free the old surface cache
vid_surfcache = D_SurfaceCacheAddress ();
if (vid_surfcache) {
D_FlushCaches ();
free (vid_surfcache);
vid_surfcache = NULL;
}
X11_highhunkmark = Hunk_HighMark ();
// alloc an extra line in case we want to wrap, and allocate the z-buffer
buffersize = vid.width * vid.height * sizeof (*d_pzbuffer);
vid_surfcachesize = D_SurfaceCacheForRes (vid.width, vid.height);
buffersize += vid_surfcachesize;
d_pzbuffer = Hunk_HighAllocName(buffersize, "video");
if (d_pzbuffer == NULL) {
// Allocate the new z-buffer
d_pzbuffer = calloc (tbuffersize, 1);
if (!d_pzbuffer) {
Sys_Error ("Not enough memory for video mode\n");
}
vid_surfcache = (byte *) d_pzbuffer
+ vid.width * vid.height * sizeof (*d_pzbuffer);
// Allocate the new surface cache; free the z-buffer if we fail
vid_surfcache = calloc (tcachesize, 1);
if (!vid_surfcache) {
free (d_pzbuffer);
d_pzbuffer = NULL;
Sys_Error ("Not enough memory for video mode\n");
}
D_InitCaches(vid_surfcache, vid_surfcachesize);
D_InitCaches (vid_surfcache, tcachesize);
for (frm=0 ; frm<2 ; frm++)
{
for (frm=0 ; frm<2 ; frm++) {
// free up old frame buffer memory
if (x_framebuffer[frm])
{
// free up old frame buffer memory
if (x_framebuffer[frm]) {
XShmDetach(x_disp, &x_shminfo[frm]);
free(x_framebuffer[frm]);
shmdt(x_shminfo[frm].shmaddr);
}
// create the image
x_framebuffer[frm] = XShmCreateImage( x_disp,
// create the image
x_framebuffer[frm] = XShmCreateImage (x_disp,
x_vis,
x_visinfo->depth,
ZPixmap,
@ -404,10 +420,10 @@ ResetSharedFrameBuffers(void)
vid.width,
vid.height );
// grab shared memory
// grab shared memory
size = x_framebuffer[frm]->bytes_per_line
* x_framebuffer[frm]->height;
if (size < minsize)
Sys_Error("VID: Window must use at least %d bytes\n", minsize);
@ -425,8 +441,7 @@ ResetSharedFrameBuffers(void)
x_framebuffer[frm]->data = x_shminfo[frm].shmaddr;
// get the X server to attach to it
// get the X server to attach to it
if (!XShmAttach(x_disp, &x_shminfo[frm]))
Sys_Error("VID: XShmAttach() failed\n");
XSync(x_disp, 0);