⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i_system.c

📁 The source code of Doom legacy for windows
💻 C
字号:
// Emacs style mode select   -*- C++ -*-//-----------------------------------------------------------------------------//// $Id: i_system.c,v 1.7 2001/03/12 21:03:10 metzgermeister Exp $//// 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.////// $Log: i_system.c,v $// Revision 1.7  2001/03/12 21:03:10  metzgermeister//   * new symbols for rendererlib added in SDL//   * console printout fixed for Linux&SDL//   * Crash fixed in Linux SW renderer initialization//// Revision 1.6  2001/02/24 13:35:23  bpereira// no message//// Revision 1.5  2000/11/02 19:49:40  bpereira// no message//// Revision 1.4  2000/10/16 21:20:53  hurdler// remove unecessary code//// Revision 1.3  2000/09/26 17:58:06  metzgermeister// I_Getkey implemented//// Revision 1.2  2000/09/10 10:56:00  metzgermeister// clean up & made it work again//// Revision 1.1  2000/08/21 21:17:32  metzgermeister// Initial import to CVS//////// DESCRIPTION:////-----------------------------------------------------------------------------#include <stdio.h>#include <stdlib.h>#include <string.h>#include <SDL/SDL.h>#ifdef LINUX#include <sys/vfs.h>#endif#ifdef LMOUSE2#include <termios.h>#endif#ifdef LJOYSTICK // linux joystick 1.x#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <fcntl.h>#include <linux/joystick.h>#endif#include "doomdef.h"#include "m_misc.h"#include "i_video.h"#include "i_sound.h"#include "i_system.h"#include "d_net.h"#include "g_game.h"#include "endtxt.h"#include "i_joy.h"extern void D_PostEvent(event_t*);#ifdef LJOYSTICKint joyfd = -1;int joyaxes = 0;int joystick_started = 0;int joy_scale = 1;#endifJoyType_t Joystick;#ifdef LMOUSE2int fdmouse2 = -1;int mouse2_started = 0;#endifbyte keyboard_started = 0;void I_StartupKeyboard (void) {}void I_StartupTimer    (void) {}void I_OutputMsg       (char *fmt, ...) {    va_list     argptr;    va_start (argptr,fmt);    vfprintf (stderr,fmt,argptr);    va_end (argptr);}int  I_GetKey          (void){    // Warning: I_GetKey emties the event queue till next keypress    event_t*    ev;    int rc=0;    // return the first keypress from the event queue    for ( ; eventtail != eventhead ; eventtail = (++eventtail)&(MAXEVENTS-1) )    {        ev = &events[eventtail];        if(ev->type == ev_keydown)        {            rc = ev->data1;            continue;        }    }    return rc;}#ifdef LJOYSTICKvoid I_JoyScale() {  joy_scale = (cv_joyscale.value==0)?1:cv_joyscale.value;}void I_GetJoyEvent() {  struct js_event jdata;  static event_t event = {0,0,0,0};  static int buttons = 0;  if(!joystick_started) return;  while(read(joyfd,&jdata,sizeof(jdata))!=-1) {    switch(jdata.type) {    case JS_EVENT_AXIS:      event.type = ev_joystick;      event.data1 = 0;      switch(jdata.number) {      case 0:        event.data2 = ((jdata.value >> 5)/joy_scale)*joy_scale;        D_PostEvent(&event);        break;      case 1:        event.data3 = ((jdata.value >> 5)/joy_scale)*joy_scale;        D_PostEvent(&event);      default:        break;      }      break;    case JS_EVENT_BUTTON:      if(jdata.number<JOYBUTTONS) {        if(jdata.value) {          if(!((buttons >> jdata.number)&1)) {            buttons |= 1 << jdata.number;            event.type = ev_keydown;            event.data1 = KEY_JOY1+jdata.number;            D_PostEvent(&event);          }        } else {          if((buttons>>jdata.number)&1) {            buttons ^= 1 << jdata.number;            event.type = ev_keyup;            event.data1 = KEY_JOY1+jdata.number;            D_PostEvent(&event);          }        }      }      break;    }  }}void I_ShutdownJoystick() {  if(joyfd!=-1) {    close(joyfd);    joyfd = -1;  }  joyaxes = 0;  joystick_started = 0;}int joy_open(char *fname) {  joyfd = open(fname,O_RDONLY|O_NONBLOCK);  if(joyfd==-1) {    CONS_Printf("Error opening %s!\n",fname);    return 0;  }  ioctl(joyfd,JSIOCGAXES,&joyaxes);  if(joyaxes<2) {    CONS_Printf("Not enought axes?\n");    joyaxes = 0;    joyfd = -1;    close(joyfd);    return 0;  }  return joyaxes;}/*int joy_waitb(int fd, int *xpos,int *ypos,int *hxpos,int *hypos) {  int i,xps,yps,hxps,hyps;  struct js_event jdata;  for(i=0;i<1000;i++) {    while(read(fd,&jdata,sizeof(jdata))!=-1) {      switch(jdata.type) {      case JS_EVENT_AXIS:        switch(jdata.number) {        case 0: // x          xps = jdata.value;          break;        case 1: // y          yps = jdata.value;          break;        case 3: // hat x          hxps = jdata.value;          break;        case 4: // hat y          hyps = jdata.value;        default:          break;        }        break;      case JS_EVENT_BUTTON:        break;      }    }  }  }*/#endif // LJOYSTICKvoid I_InitJoystick (void) {#ifdef LJOYSTICK  I_ShutdownJoystick();  if(!strcmp(cv_usejoystick.string,"0"))    return;  if(!joy_open(cv_joyport.string)) return;  joystick_started = 1;  return;#endif}#ifdef LMOUSE2void I_GetMouse2Event() {  static unsigned char mdata[5];  static int i = 0,om2b = 0;  int di,j,mlp,button;  event_t event;  const int mswap[8] = {0,4,1,5,2,6,3,7};  if(!mouse2_started) return;  for(mlp=0;mlp<20;mlp++) {    for(;i<5;i++) {      di = read(fdmouse2,mdata+i,1);      if(di==-1) return;    }    if((mdata[0]&0xf8)!=0x80) {      for(j=1;j<5;j++) {        if((mdata[j]&0xf8)==0x80) {          for(i=0;i<5-j;i++) { // shift            mdata[i] = mdata[i+j];          }        }      }      if(i<5) continue;    } else {      button = mswap[~mdata[0]&0x07];      for(j=0;j<MOUSEBUTTONS;j++) {        if(om2b&(1<<j)) {          if(!(button&(1<<j))) { //keyup            event.type = ev_keyup;            event.data1 = KEY_2MOUSE1+j;            D_PostEvent(&event);            om2b ^= 1 << j;          }        } else {          if(button&(1<<j)) {            event.type = ev_keydown;            event.data1 = KEY_2MOUSE1+j;            D_PostEvent(&event);            om2b ^= 1 << j;          }        }      }      event.data2 = ((signed char)mdata[1])+((signed char)mdata[3]);      event.data3 = ((signed char)mdata[2])+((signed char)mdata[4]);      if(event.data2&&event.data3) {        event.type = ev_mouse2;        event.data1 = 0;        D_PostEvent(&event);      }    }    i = 0;  }}void I_ShutdownMouse2() {  if(fdmouse2!=-1) close(fdmouse2);  mouse2_started = 0;}#endifvoid I_StartupMouse2 (void) {#ifdef LMOUSE2  struct termios m2tio;  int i,dtr,rts;  I_ShutdownMouse2();  if(cv_usemouse2.value == 0) return;  if((fdmouse2 = open(cv_mouse2port.string,O_RDONLY|O_NONBLOCK|O_NOCTTY))==-1) {    CONS_Printf("Error opening %s!\n",cv_mouse2port.string);    return;  }  tcflush(fdmouse2, TCIOFLUSH);  m2tio.c_iflag = IGNBRK;  m2tio.c_oflag = 0;  m2tio.c_cflag = CREAD|CLOCAL|HUPCL|CS8|CSTOPB|B1200;  m2tio.c_lflag = 0;  m2tio.c_cc[VTIME] = 0;  m2tio.c_cc[VMIN] = 1;  tcsetattr(fdmouse2, TCSANOW, &m2tio);  strupr(cv_mouse2opt.string);  for(i=0,rts = dtr = -1;i<strlen(cv_mouse2opt.string);i++) {    if(cv_mouse2opt.string[i]=='D') {      if(cv_mouse2opt.string[i+1]=='-') {        dtr = 0;      } else {        dtr = 1;      }    }    if(cv_mouse2opt.string[i]=='R') {      if(cv_mouse2opt.string[i+1]=='-') {        rts = 0;      } else {        rts = 1;      }    }  }  if((dtr!=-1)||(rts!=-1)) {    if(!ioctl(fdmouse2, TIOCMGET, &i)) {      if(!dtr) {        i &= ~TIOCM_DTR;      } else {        if(dtr>0) i |= TIOCM_DTR;      }      if(!rts) {        i &= ~TIOCM_RTS;      } else {        if(rts>0) i |= TIOCM_RTS;      }      ioctl(fdmouse2, TIOCMSET, &i);    }  }  mouse2_started = 1;#endif}byte     mb_used = 6+2; // 2 more for caching soundstatic int quiting=0; /* prevent recursive I_Quit() */void I_Tactile(int on,int off,int total ){  // UNUSED.  on = off = total = 0;}ticcmd_t        emptycmd;ticcmd_t*       I_BaseTiccmd(void){    return &emptycmd;}int  I_GetHeapSize (void){    return mb_used*1024*1024;}//// I_GetTime// returns time in 1/TICRATE second tics//ULONG  I_GetTime (void){    Uint32        ticks;    static Uint32 basetime=0;    // milliseconds since SDL initialization    ticks = SDL_GetTicks();    if (!basetime)        basetime = ticks;    return (ticks - basetime)*TICRATE/1000;}//// I_Init//void I_Init (void){    I_StartupSound();    I_InitMusic();    quiting = 0;}//// I_Quit//void I_Quit (void){    /* prevent recursive I_Quit() */    if(quiting) return;    quiting = 1;  //added:16-02-98: when recording a demo, should exit using 'q' key,  //        but sometimes we forget and use 'F10'.. so save here too.    if (demorecording)        G_CheckDemoStatus();    D_QuitNetGame ();    I_ShutdownMusic();    I_ShutdownSound();    I_ShutdownCD();   // use this for 1.28 19990220 by Kin    M_SaveConfig (NULL);    I_ShutdownGraphics();    I_ShutdownSystem();    printf("\r");    ShowEndTxt();    exit(0);}void I_WaitVBL(int count){    SDL_Delay(1);}void I_BeginRead(void){}void I_EndRead(void){}byte*   I_AllocLow(int length){    byte*       mem;    mem = (byte *)malloc (length);    memset (mem,0,length);    return mem;}//// I_Error//extern boolean demorecording;void I_Error (char *error, ...){    va_list     argptr;    // Message first.    va_start (argptr,error);    fprintf (stderr, "Error: ");    vfprintf (stderr,error,argptr);    fprintf (stderr, "\n");    va_end (argptr);    fflush( stderr );    // Shutdown. Here might be other errors.    if (demorecording)        G_CheckDemoStatus();    D_QuitNetGame ();    I_ShutdownMusic();    I_ShutdownSound();    I_ShutdownGraphics();    // shutdown everything else which was registered    I_ShutdownSystem();    exit(-1);}#define MAX_QUIT_FUNCS     16typedef 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               };////  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;      }   }}////  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;      }   }}////  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(long long *freespace) {#ifdef LINUX    struct statfs stfs;    if(statfs(".",&stfs)==-1) {        *freespace = MAXINT;        return;    }    *freespace = stfs.f_bavail*stfs.f_bsize;#endif#ifdef __WIN32__    static MyFunc pfnGetDiskFreeSpaceEx=NULL;    static boolean testwin95 = false;    INT64 usedbytes;    if(!testwin95)    {        HINSTANCE h = LoadLibraryA("kernel32.dll");        if (h) {            pfnGetDiskFreeSpaceEx = (MyFunc)GetProcAddress(h,"GetDiskFreeSpaceExA");            FreeLibrary(h);        }        testwin95 = true;    }    if (pfnGetDiskFreeSpaceEx) {        if (!pfnGetDiskFreeSpaceEx(NULL,(PULARGE_INTEGER)freespace,(PULARGE_INTEGER)&usedbytes,NULL))            *freespace = MAXINT;    }    else    {        ULONG SectorsPerCluster, BytesPerSector, NumberOfFreeClusters;        ULONG TotalNumberOfClusters;        GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector,                         &NumberOfFreeClusters, &TotalNumberOfClusters);        *freespace = BytesPerSector*SectorsPerCluster*NumberOfFreeClusters;    }#endif#if !defined (LINUX) && !defined (__WIN32__)    // Dummy for platform independent; 1GB should be enough    *freespace = 1024*1024*1024;#endif}char *I_GetUserName(void){#ifdef LINUX    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;#endif#ifdef __WIN32__    static char username[MAXPLAYERNAME];    char  *p;    int   ret;    ULONG i=MAXPLAYERNAME;    ret = GetUserName(username,&i);    if(!ret)    {        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;#endif#if !defined (LINUX) && !defined (__WIN32__)    // dummy for platform independent version    return NULL;#endif}int  I_mkdir(const char *dirname, int unixright){#ifdef LINUX    return mkdir(dirname, unixright);#else    return mkdir(dirname);#endif}void I_LocateWad(void) {    // relict from the Linux version    return;}// quick fix for compilULONG I_GetFreeMem(ULONG *total){    return 16<<20;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -