📄 i_system.c
字号:
{
if( !timer_started )
return;
remove_timer();
}
//
// Installs the timer interrupt handler with timer speed as TICRATE.
//
void I_StartupTimer(void)
{
ticcount = 0;
//lock this from being swapped to disk! BEFORE INSTALLING
LOCK_VARIABLE(ticcount);
LOCK_FUNCTION(I_TimerISR);
if( install_timer() != 0 )
I_Error("I_StartupTimer: could not install timer.");
if( install_int_ex( I_TimerISR, BPS_TO_TIMER(TICRATE) ) != 0 )
//should never happen since we use only one.
I_Error("I_StartupTimer: no room for callback routine.");
//added:08-01-98: remove the timer explicitly because we don't use
// Allegro 's allegro_exit() shutdown code.
I_AddExitFunc(I_ShutdownTimer);
timer_started = true;
}
//added:07-02-98:
//
//
byte ASCIINames[128] =
{
// 0 1 2 3 4 5 6 7
// 8 9 A B C D E F
0 , 27, '1', '2', '3', '4', '5', '6',
'7', '8', '9', '0', KEY_MINUS,KEY_EQUALS,KEY_BACKSPACE, KEY_TAB,
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
'o', 'p', '[', ']', KEY_ENTER,KEY_CTRL,'a', 's',
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
'\'', '`', KEY_SHIFT, '\\', 'z', 'x', 'c', 'v',
'b', 'n', 'm', ',', '.', '/', KEY_SHIFT, '*',
KEY_ALT,KEY_SPACE,KEY_CAPSLOCK, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10,KEY_NUMLOCK,KEY_SCROLLLOCK,KEY_KEYPAD7,
KEY_KEYPAD8,KEY_KEYPAD9,KEY_MINUSPAD,KEY_KEYPAD4,KEY_KEYPAD5,KEY_KEYPAD6,KEY_PLUSPAD,KEY_KEYPAD1,
KEY_KEYPAD2,KEY_KEYPAD3,KEY_KEYPAD0,KEY_KPADDEL, 0, 0, 0, KEY_F11,
KEY_F12,0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
volatile int pausepressed=0;
volatile char nextkeyextended;
static void I_KeyboardHandler()
{
unsigned char ch;
event_t event;
ch=inportb(0x60);
if(pausepressed>0)
pausepressed--;
else
if(ch==0xE1) // pause key
{
event.type=ev_keydown;
event.data1=KEY_PAUSE;
D_PostEvent(&event);
pausepressed=5;
}
else
if(ch==0xE0) // extended key handled at next call
{
nextkeyextended=1;
}
else
{
if((ch&0x80)==0)
event.type=ev_keydown;
else
event.type=ev_keyup;
ch&=0x7f;
if(nextkeyextended)
{
nextkeyextended=0;
if(ch==70) // crtl-break
{
asm ("movb $0x79, %%al
call ___djgpp_hw_exception"
: : :"%eax","%ebx","%ecx","%edx","%esi","%edi","memory");
}
// remap lonely keypad slash
if (ch==53)
event.data1 = KEY_KPADSLASH;
else
// remap the bill gates keys...
if (ch>=91 && ch<=93)
event.data1 = ch + 0x80; // leftwin, rightwin, menu
else
// remap non-keypad extended keys to a value<128, but
// make them different than the KEYPAD keys.
if (ch>=71 && ch<=83)
event.data1 = 0x80 + ch + 30;
else if (ch==28)
event.data1 = KEY_ENTER; // keypad enter -> return key
else if (ch==29)
event.data1 = KEY_CTRL; // rctrl -> lctrl
else if (ch==56)
event.data1 = KEY_ALT; // ralt -> lalt
else
ch = 0;
if (ch)
D_PostEvent(&event);
}
else
{
if (ASCIINames[ch]!=0)
event.data1=ASCIINames[ch];
else
event.data1=ch+0x80;
D_PostEvent(&event);
}
}
outportb(0x20,0x20);
}
END_OF_FUNCTION(I_KeyboardHandler);
// Return a key that has been pushed, or 0
// (replace getchar() at game startup)
//
int I_GetKey (void)
{
if( keyboard_started )
{
event_t *ev;
if (eventtail != eventhead)
{
ev = &events[eventtail];
eventtail = (++eventtail)&(MAXEVENTS-1);
if (ev->type == ev_keydown)
return ev->data1;
else
return 0;
}
return 0;
}
// keyboard not started use the bios call trouth djgpp
if(_conio_kbhit())
{
int key=getch();
if(key==0) key=getch()+256;
return key;
}
else
return 0;
}
/* Keyboard handler stuff */
_go32_dpmi_seginfo oldkeyinfo,newkeyinfo;
//
// Removes the keyboard handler.
//
void I_ShutdownKeyboard()
{
if( !keyboard_started )
return;
asm("cli");
_go32_dpmi_set_protected_mode_interrupt_vector(9, &oldkeyinfo);
_go32_dpmi_free_iret_wrapper(&newkeyinfo);
asm("sti");
keyboard_started=false;
}
//
// Installs the keyboard handler.
//
void I_StartupKeyboard()
{
if(keyboard_started)
return;
nextkeyextended=0;
asm("cli");
_go32_dpmi_get_protected_mode_interrupt_vector(9, &oldkeyinfo);
newkeyinfo.pm_offset=(int)I_KeyboardHandler;
newkeyinfo.pm_selector=_go32_my_cs();
_go32_dpmi_allocate_iret_wrapper(&newkeyinfo);
_go32_dpmi_set_protected_mode_interrupt_vector(9, &newkeyinfo);
LOCK_VARIABLE(nextkeyextended);
LOCK_VARIABLE(pausepressed);
_go32_dpmi_lock_data(ASCIINames,sizeof(ASCIINames));
LOCK_FUNCTION(I_KeyboardHandler);
_go32_dpmi_lock_data(events,sizeof(events));
LOCK_VARIABLE(eventhead);
LOCK_FUNCTION(D_PostEvent);
asm("sti");
//added:08-01-98:register shutdown keyboard code.
I_AddExitFunc(I_ShutdownKeyboard);
keyboard_started = true;
}
//added:08-01-98:
//
// Clean Startup & Shutdown handling, as does Allegro.
// We need this services for ourselves too, and we don't want to mix
// with Allegro, because someone might not use Allegro.
// (all 'exit' was renamed to 'quit')
//
#define MAX_QUIT_FUNCS 16
typedef void (*quitfuncptr)();
static quitfuncptr quit_funcs[MAX_QUIT_FUNCS] =
{ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
//added:08-01-98:
//
// Adds a function to the list that need to be called by I_SystemShutdown().
//
void I_AddExitFunc(void (*func)())
{
int c;
for (c=0; c<MAX_QUIT_FUNCS; c++) {
if (!quit_funcs[c]) {
quit_funcs[c] = func;
break;
}
}
}
//added:08-01-98:
//
// Removes a function from the list that need to be called by
// I_SystemShutdown().
//
void I_RemoveExitFunc(void (*func)())
{
int c;
for (c=0; c<MAX_QUIT_FUNCS; c++) {
if (quit_funcs[c] == func) {
while (c<MAX_QUIT_FUNCS-1) {
quit_funcs[c] = quit_funcs[c+1];
c++;
}
quit_funcs[MAX_QUIT_FUNCS-1] = NULL;
break;
}
}
}
//added:03-01-98:
//
// signal_handler:
// Used to trap various signals, to make sure things get shut down cleanly.
//
static void exception_handler(int num)
{
static char msg[255];
sprintf(msg,"Doom LEGACY v%i.%i"VERSIONSTRING"\r\n"
"This is a error of Legacy try to send the following info to programmers\r\n",VERSION/100,VERSION%100);
//D_QuitNetGame (); //say 'byebye' to other players when your machine
// crashes?... hmm... do they have to die with you???
I_ShutdownSystem();
_write(STDERR_FILENO, msg, strlen(msg));
signal(num, SIG_DFL);
raise(num);
// TODO: write it in a log !!
}
static void break_handler(int num)
{
static char msg[] = "Oh no! Back to reality!\r\n";
//D_QuitNetGame (); //say 'byebye' to other players when your machine
// crashes?... hmm... do they have to die with you???
I_ShutdownSystem();
_write(STDERR_FILENO, msg, sizeof(msg)-1);
signal(num, SIG_DFL);
raise(num);
}
//added:08-01-98: now this replaces allegro_init()
//
// REMEMBER: THIS ROUTINE MUST BE STARTED IN i_main.c BEFORE D_DoomMain()
//
// This stuff should get rid of the exception and page faults when
// Doom bugs out with an error. Now it should exit cleanly.
//
int I_StartupSystem(void)
{
I_DetectWin95 ();
i_love_bill = win95;
// some 'more globals than globals' things to initialize here ?
graphics_started = false;
keyboard_started = false;
sound_started = false;
timer_started = false;
cdaudio_started = false;
// check for OS type and version here ?
signal(SIGABRT, exception_handler);
signal(SIGFPE , exception_handler);
signal(SIGILL , exception_handler);
signal(SIGSEGV, exception_handler);
signal(SIGINT , break_handler);
signal(SIGKILL, break_handler);
signal(SIGQUIT, break_handler);
return 0;
}
//added:08-01-98:
//
// Closes down everything. This includes restoring the initial
// pallete and video mode, and removing whatever mouse, keyboard, and
// timer routines have been installed.
//
// NOTE : Shutdown user funcs. are effectively called in reverse order.
//
void I_ShutdownSystem()
{
int c;
for (c=MAX_QUIT_FUNCS-1; c>=0; c--)
if (quit_funcs[c])
(*quit_funcs[c])();
}
void I_GetDiskFreeSpace(INT64 *freespace)
{
struct diskfree_t df;
if(_dos_getdiskfree(0,&df))
*freespace = (unsigned long)df.avail_clusters *
(unsigned long)df.bytes_per_sector *
(unsigned long)df.sectors_per_cluster;
else
*freespace = MAXINT;
}
char *I_GetUserName(void)
{
static char username[MAXPLAYERNAME];
char *p;
if((p=getenv("USER"))==NULL)
if((p=getenv("user"))==NULL)
if((p=getenv("USERNAME"))==NULL)
if((p=getenv("username"))==NULL)
return NULL;
strncpy(username,p,MAXPLAYERNAME);
if( strcmp(username,"")==0 )
return NULL;
return username;
}
int I_mkdir(const char *dirname, int unixright)
{
return mkdir(dirname,unixright);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -