1 // Emacs style mode select -*- C++ -*-
2 //-----------------------------------------------------------------------------
4 // Copyright(C) 1993-1996 Id Software, Inc.
5 // Copyright(C) 2005 Simon Howard
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24 //-----------------------------------------------------------------------------
35 #define WIN32_LEAN_AND_MEAN
47 #include "i_joystick.h"
62 #define DEFAULT_RAM 16 /* MiB */
63 #define MIN_RAM 4 /* MiB */
67 // Tactile feedback function, probably used for the Logitech Cyberman
69 void I_Tactile(int on
, int off
, int total
)
75 // Windows CE-specific auto-allocation function that allocates the zone
76 // size based on the amount of memory reported free by the OS.
78 static byte
*AutoAllocMemory(int *size
, int default_ram
, int min_ram
)
80 MEMORYSTATUS memory_status
;
84 // Get available physical RAM. We leave one megabyte extra free
85 // for the OS to keep running (my PDA becomes unstable if too
86 // much RAM is allocated)
88 GlobalMemoryStatus(&memory_status
);
89 available
= memory_status
.dwAvailPhys
- 2 * 1024 * 1024;
91 // Limit to default_ram if we have more than that available:
93 if (available
> default_ram
* 1024 * 1024)
95 available
= default_ram
* 1024 * 1024;
98 if (available
< min_ram
* 1024 * 1024)
100 I_Error("Unable to allocate %i MiB of RAM for zone", min_ram
);
106 zonemem
= malloc(*size
);
110 I_Error("Failed when allocating %i bytes", *size
);
118 // Zone memory auto-allocation function that allocates the zone size
119 // by trying progressively smaller zone sizes until one is found that
122 static byte
*AutoAllocMemory(int *size
, int default_ram
, int min_ram
)
126 // Allocate the zone memory. This loop tries progressively smaller
127 // zone sizes until a size is found that can be allocated.
128 // If we used the -mb command line parameter, only the parameter
129 // provided is accepted.
133 while (zonemem
== NULL
)
135 // We need a reasonable minimum amount of RAM to start.
137 if (default_ram
< min_ram
)
139 I_Error("Unable to allocate %i MiB of RAM for zone", default_ram
);
142 // Try to allocate the zone memory.
144 *size
= default_ram
* 1024 * 1024;
146 zonemem
= malloc(*size
);
148 // Failed to allocate? Reduce zone size until we reach a size
149 // that is acceptable.
162 byte
*I_ZoneBase (int *size
)
165 int min_ram
, default_ram
;
171 // Specify the heap size, in MiB (default 16).
174 p
= M_CheckParm("-mb");
178 default_ram
= atoi(myargv
[p
+1]);
179 min_ram
= default_ram
;
183 default_ram
= DEFAULT_RAM
;
187 zonemem
= AutoAllocMemory(size
, default_ram
, min_ram
);
189 printf("zone memory: %p, %x allocated for zone\n",
198 // Returns true if stdout is a real console, false if it is a file
201 boolean
I_ConsoleStdout(void)
204 // SDL "helpfully" always redirects stdout to a file.
207 return isatty(fileno(stdout
));
216 I_CheckIsScreensaver();
225 // Displays the text mode ending screen after the game quits
230 unsigned char *endoom_data
;
231 unsigned char *screendata
;
235 endoom_data
= W_CacheLumpName(DEH_String("ENDOOM"), PU_STATIC
);
237 // Set up text mode screen
241 // Make sure the new window has the right title and icon
243 I_SetWindowCaption();
246 // Write the data to the screen memory
248 screendata
= TXT_GetScreenData();
250 indent
= (ENDOOM_W
- TXT_SCREEN_W
) / 2;
252 for (y
=0; y
<TXT_SCREEN_H
; ++y
)
254 memcpy(screendata
+ (y
* TXT_SCREEN_W
* 2),
255 endoom_data
+ (y
* ENDOOM_W
+ indent
) * 2,
259 // Wait for a keypress
265 if (TXT_GetChar() >= 0)
273 // Shut down text mode screen
288 if (!screensaver_mode
)
293 I_ShutdownGraphics();
295 if (show_endoom
&& !testcontrols
&& !screensaver_mode
)
303 void I_WaitVBL(int count
)
305 I_Sleep((count
* 1000) / 70);
311 extern boolean demorecording
;
313 static boolean already_quitting
= false;
315 void I_Error (char *error
, ...)
319 if (already_quitting
)
321 fprintf(stderr
, "Warning: recursive call to I_Error detected.\n");
326 already_quitting
= true;
330 va_start(argptr
, error
);
331 fprintf(stderr
, "\nError: ");
332 vfprintf(stderr
, error
, argptr
);
333 fprintf(stderr
, "\n");
337 // Shutdown. Here might be other errors.
345 I_ShutdownGraphics();
349 // On Windows, pop up a dialog box with the error message.
352 wchar_t wmsgbuf
[512];
354 va_start(argptr
, error
);
355 memset(msgbuf
, 0, sizeof(msgbuf
));
356 vsnprintf(msgbuf
, sizeof(msgbuf
) - 1, error
, argptr
);
359 MultiByteToWideChar(CP_ACP
, 0,
360 msgbuf
, strlen(msgbuf
) + 1,
361 wmsgbuf
, sizeof(wmsgbuf
));
363 MessageBoxW(NULL
, wmsgbuf
, L
"Error", MB_OK
);