home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quakeworld_src / client / sys_amiga.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-17  |  12.4 KB  |  605 lines

  1. /* 
  2. Copyright (C) 1996-1997 Id Software, Inc. 
  3.  
  4. This program is free software; you can redistribute it and/or 
  5. modify it under the terms of the GNU General Public License 
  6. as published by the Free Software Foundation; either version 2 
  7. of the License, or (at your option) any later version. 
  8.  
  9. This program is distributed in the hope that it will be useful, 
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of 
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   
  12.  
  13. See the GNU General Public License for more details. 
  14.  
  15. You should have received a copy of the GNU General Public License 
  16. along with this program; if not, write to the Free Software 
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
  18.  
  19. */ 
  20.  
  21. /*
  22. ** sys_amiga.c
  23. **
  24. ** QuakeWorld Server for Amiga M68k and Amiga PowerPC
  25. **
  26. */
  27.  
  28. #pragma amiga-align
  29. #include <exec/types.h>
  30. #include <exec/memory.h>
  31. #include <exec/execbase.h>
  32. #include <dos/dos.h>
  33. #include <utility/tagitem.h>
  34. #include <graphics/gfxbase.h>
  35. #include <devices/timer.h>
  36. #include <clib/alib_protos.h>
  37. #include <proto/exec.h>
  38. #include <proto/dos.h>
  39. #include <proto/timer.h>
  40. #ifdef __PPC__
  41. #ifdef WOS
  42. #include <clib/powerpc_protos.h>
  43. #else
  44. #include <powerup/ppclib/time.h>
  45. #include <powerup/gcclib/powerup_protos.h>
  46. #endif
  47. #endif
  48. #pragma default-align
  49.  
  50. /* Quake includes */
  51. #include "quakedef.h"
  52. #if defined(__PPC__) && !defined(WOS)
  53. #include "sys_timer.h"  /* GetSysTimePPC() emulation for PowerUp */
  54. #endif
  55.  
  56. #define CLOCK_PAL       3546895
  57. #define CLOCK_NTSC      3579545
  58. #define MAX_HANDLES     10
  59.  
  60.  
  61. #ifdef __STORM__
  62. extern struct Library *TimerBase;
  63. extern struct Library *UtilityBase;
  64. #else
  65. struct Library *TimerBase = NULL;
  66. struct Library *UtilityBase = NULL;
  67. #endif
  68. struct Library *LowLevelBase = NULL;
  69. #ifdef __PPC__
  70. #ifdef __STORM__
  71. extern struct Library *MathIeeeDoubBasBase = NULL;
  72. #else
  73. struct Library *MathIeeeDoubBasBase;
  74. #endif
  75.  
  76. qboolean no68kFPU = false; /* for LC040/LC060 systems */
  77. #endif
  78.  
  79. /* these are for snd_amiga.c */
  80. long sysclock = CLOCK_PAL;
  81. int FirstTime = 0;
  82. int FirstTime2 = 0;
  83.  
  84. static quakeparms_t parms;
  85. static struct timerequest *timerio;
  86. static int membase_offs;
  87. static int nostdout=0,coninput=0;
  88. static BPTR amiga_stdin,amiga_stdout;
  89. static BPTR sys_handles[MAX_HANDLES];
  90.  
  91. cvar_t  sys_linerefresh = {"sys_linerefresh","0"};// set for entity display
  92.  
  93.  
  94. #ifndef __PPC__
  95. extern void MMUHackOn(void);
  96. extern void MMUHackOff(void);
  97. #endif
  98.  
  99.  
  100.  
  101. // =======================================================================
  102. // General routines
  103. // =======================================================================
  104.  
  105. /*
  106. ================
  107. usleep
  108. ================
  109. */
  110. void usleep(unsigned long timeout)
  111. {
  112.   timerio->tr_node.io_Command = TR_ADDREQUEST;
  113.   timerio->tr_time.tv_secs = timeout / 1000000;
  114.   timerio->tr_time.tv_micro = timeout % 1000000;
  115.   SendIO((struct IORequest *)timerio);
  116.   WaitIO((struct IORequest *)timerio);
  117. }
  118.  
  119. /*
  120. ================
  121. strcasecmp
  122. ================
  123. */
  124. int strcasecmp(const char *str1, const char *str2)
  125. {
  126.   while(tolower((unsigned char)*str1) == tolower((unsigned char)*str2)) {
  127.     if(!*str1) return(0);
  128.     str1++;str2++;
  129.   }
  130.   return(tolower(*(unsigned char *)str1)-tolower(*(unsigned char *)str2));
  131. }
  132.  
  133. /*
  134. ================
  135. strncasecmp
  136. ================
  137. */
  138. int strncasecmp(const char *str1, const char *str2, size_t n)
  139. {
  140.   if (n==0) return 0;
  141.   while (--n && tolower((unsigned char)*str1)==tolower((unsigned char)*str2)){
  142.     if (!*str1) return(0);
  143.     str1++; str2++;
  144.   }
  145.   return(tolower(*(unsigned char *)str1)-tolower(*(unsigned char *)str2));
  146. }
  147.  
  148. /*
  149. ================
  150. bzero
  151. ================
  152. */
  153. void bzero(void *p,size_t n)
  154. {
  155.   memset(p,0,n);
  156. }
  157.  
  158.  
  159. static void cleanup(int rc)
  160. {
  161.   int i;
  162.  
  163.   Host_Shutdown();
  164.  
  165.   if (coninput)
  166.     SetMode(amiga_stdin,0);  /* put console back into normal CON mode */
  167.  
  168.   if (parms.membase)
  169.     FreeMem((char *)parms.membase-membase_offs,parms.memsize+3*32);
  170.  
  171. #ifndef __PPC__
  172.   if (COM_CheckParm("-hack"))
  173.     MMUHackOff();
  174. #endif
  175.  
  176.   if (TimerBase) {
  177.     if (!CheckIO((struct IORequest *)timerio)) {
  178.       AbortIO((struct IORequest *)timerio);
  179.       WaitIO((struct IORequest *)timerio);
  180.     }
  181.     CloseDevice((struct IORequest *)timerio);
  182.     DeletePort(timerio->tr_node.io_Message.mn_ReplyPort);
  183.     DeleteStdIO((struct IOStdReq *)timerio);
  184.   }
  185.  
  186. #ifdef __PPC__
  187.   if (no68kFPU) {
  188.     if (MathIeeeDoubBasBase)
  189.       CloseLibrary(MathIeeeDoubBasBase);
  190.   }
  191. #endif
  192.  
  193.   if (LowLevelBase)
  194.     CloseLibrary(LowLevelBase);
  195.   if (UtilityBase)
  196.     CloseLibrary(UtilityBase);
  197.  
  198.   for (i=1; i<MAX_HANDLES; i++) {
  199.     if (sys_handles[i])
  200.       Close(sys_handles[i]);
  201.   }
  202.   exit(rc);
  203. }
  204.  
  205. void Sys_DebugNumber(int y, int val)
  206. {
  207. }
  208.  
  209. void Sys_Printf (char *fmt, ...)
  210. {
  211.   va_list argptr;
  212.   static char text[2048];
  213.   unsigned char *p;
  214.  
  215.   va_start(argptr,fmt);
  216.   vsprintf(text,fmt,argptr);
  217.   va_end(argptr);
  218.  
  219.   if (strlen(text) > sizeof(text))
  220.     Sys_Error("memory overwrite in Sys_Printf");
  221.  
  222.   if (nostdout)
  223.     return;
  224.  
  225.   for (p = (unsigned char *)text; *p; p++) {
  226.     *p &= 0x7f;
  227.     if ((*p > 128 || *p < 32) && *p != 10 && *p != 13 && *p != 9)
  228.       printf("[%02x]", *p);
  229.     else
  230.       putc(*p, stdout);
  231.   }
  232.   fflush(stdout);
  233. }
  234.  
  235. void Sys_Quit (void)
  236. {
  237.   cleanup(0);
  238. }
  239.  
  240. void Sys_Init(void)
  241. {
  242. }
  243.  
  244. void Sys_Error (char *error, ...)
  245. {
  246.   va_list argptr;
  247.   
  248.   printf("Error: ");
  249.   va_start(argptr,error);
  250.   vprintf(error,argptr);
  251.   va_end(argptr);
  252.   printf("\n");
  253.   cleanup(1);
  254. }
  255.  
  256. void Sys_Warn (char *warning, ...)
  257.   va_list argptr;
  258.     
  259.   printf("Warning: ");
  260.   va_start(argptr,warning);
  261.   vprintf(warning,argptr);
  262.   va_end(argptr);
  263.   printf("\n");
  264.  
  265. /*
  266. ============
  267. Sys_FileTime
  268.  
  269. returns -1 if not present
  270. ============
  271. */
  272. int Sys_FileTime (char *path)
  273. {
  274.   BPTR lck;
  275.   int  t = -1;
  276.  
  277.   if (lck = Lock(path,ACCESS_READ)) {
  278.     t = 1;
  279.     UnLock(lck);
  280.   }
  281.  
  282.   return t;
  283. }
  284.  
  285.  
  286. void Sys_mkdir (char *path)
  287. {
  288.   BPTR lck;
  289.  
  290.   if (lck = CreateDir(path))
  291.     UnLock(lck);
  292. }
  293.  
  294. static int findhandle (void)
  295. {
  296.   int i;
  297.   
  298.   for (i=1 ; i<MAX_HANDLES ; i++)
  299.     if (!sys_handles[i])
  300.       return i;
  301.   Sys_Error ("out of handles");
  302.   return -1;
  303. }
  304.  
  305. int Sys_FileOpenRead (char *path, int *handle)
  306. {
  307.   BPTR fh;
  308.   struct FileInfoBlock *fib;
  309.   int     i = -1;
  310.   int flen = -1;
  311.   
  312.   *handle = -1;
  313.   if (fib = AllocDosObjectTags(DOS_FIB,TAG_DONE)) {
  314.     if (fh = Open(path,MODE_OLDFILE)) {
  315.       if (ExamineFH(fh,fib)) {
  316.         if ((i = findhandle()) > 0) {
  317.           sys_handles[i] = fh;
  318.           *handle = i;
  319.           flen = (int)fib->fib_Size;
  320.         }
  321.         else
  322.           Close(fh);
  323.       }
  324.       else
  325.         Close(fh);
  326.     }
  327.     FreeDosObject(DOS_FIB,fib);
  328.   }
  329.   return flen;
  330. }
  331.  
  332. int Sys_FileOpenWrite (char *path)
  333. {
  334.   BPTR fh;
  335.   int  i;
  336.   
  337.   if ((i = findhandle ()) > 0) {
  338.     if (fh = Open(path,MODE_NEWFILE)) {
  339.       sys_handles[i] = fh;
  340.     }
  341.     else {
  342.       char ebuf[80];
  343.       Fault(IoErr(),"",ebuf,80);
  344.       Sys_Error ("Error opening %s: %s", path, ebuf);
  345.       i = -1;
  346.     }
  347.   }
  348.   return i;
  349. }
  350.  
  351. int Sys_FileWrite (int handle, void *src, int count)
  352. {
  353.   return (int)Write(sys_handles[handle],src,(LONG)count);
  354. }
  355.  
  356. void Sys_FileClose (int handle)
  357. {
  358.   if (sys_handles[handle]) {
  359.     Close(sys_handles[handle]);
  360.     sys_handles[handle] = 0;
  361.   }
  362. }
  363.  
  364. void Sys_FileSeek (int handle, int position)
  365. {
  366.   Seek(sys_handles[handle],position,OFFSET_BEGINNING);
  367. }
  368.  
  369. int Sys_FileRead (int handle, void *dest, int count)
  370. {
  371.    return (int)Read(sys_handles[handle],dest,(LONG)count);
  372. }
  373.  
  374. void Sys_DebugLog(char *file, char *fmt, ...)
  375. {
  376.   va_list argptr; 
  377.   static char data[1024];
  378.   BPTR fh;
  379.  
  380.   va_start(argptr, fmt);
  381.   vsprintf(data, fmt, argptr);
  382.   va_end(argptr);
  383.   if (fh = Open(file,MODE_READWRITE)) {
  384.     Seek(fh,0,OFFSET_END);
  385.     Write(fh,data,(LONG)strlen(data));
  386.     Close(fh);
  387.   }
  388. }
  389.  
  390. void Sys_EditFile(char *filename)
  391. {
  392.   char cmd[256];
  393.   char *editor;
  394.  
  395.   editor = getenv("VISUAL");
  396.   if (!editor)
  397.     editor = getenv("EDITOR");
  398.   if (!editor)
  399.     editor = getenv("EDIT");
  400.   if (!editor)
  401.     editor = "ed";
  402.   sprintf(cmd, "%s %s", editor, filename);
  403.   system(cmd);
  404. }
  405.  
  406. double Sys_DoubleTime (void)
  407. {
  408.   struct timeval tv;
  409.  
  410. #ifdef __PPC__
  411.   GetSysTimePPC(&tv);
  412. #else
  413.   GetSysTime(&tv);
  414. #endif
  415.   return ((double)(tv.tv_secs-FirstTime) + (((double)tv.tv_micro) / 1000000.0));
  416. }
  417.  
  418. void Sys_LineRefresh(void)
  419. {
  420. }
  421.  
  422. char *Sys_ConsoleInput(void)
  423. {
  424.   if (coninput) {
  425.     static const char *backspace = "\b \b";
  426.     static char text[256];
  427.     static int len = 0;
  428.     char ch;
  429.  
  430.     while (WaitForChar(amiga_stdin,10) == DOSTRUE) {
  431.       Read(amiga_stdin,&ch,1);  /* note: console is in RAW mode! */
  432.       if (ch == '\r') {
  433.         ch = '\n';
  434.         Write(amiga_stdout,&ch,1);
  435.         text[len] = 0;
  436.         len = 0;
  437.         return text;
  438.       }
  439.       else if (ch == '\b') {
  440.         if (len > 0) {
  441.           len--;
  442.           Write(amiga_stdout,(char *)backspace,3);
  443.         }
  444.       }
  445.       else {
  446.         if (len < sizeof(text)-1) {
  447.           Write(amiga_stdout,&ch,1);
  448.           text[len++] = ch;
  449.         }
  450.       }
  451.     }
  452.   }
  453.   return NULL;
  454. }
  455.  
  456.  
  457. main(int argc, char *argv[])
  458. {
  459.   char cwd[128];
  460.   struct MsgPort *timerport;
  461.   int i;
  462.   double time, oldtime, newtime;
  463.   struct timeval tv;
  464.   struct GfxBase *GfxBase;
  465.  
  466.   memset(&parms,0,sizeof(parms));
  467.   parms.memsize = 16*1024*1024;  /* 16MB is default */
  468.  
  469.   COM_InitArgv (argc, argv);  
  470.   parms.argc = com_argc;
  471.   parms.argv = com_argv;
  472.  
  473.   /* Amiga Init */
  474.   if ((UtilityBase = OpenLibrary("utility.library",36)) == NULL ||
  475.       (LowLevelBase = OpenLibrary("lowlevel.library",36)) == NULL)
  476.     Sys_Error("OS2.0 required!");
  477. #ifdef __PPC__
  478.   no68kFPU = COM_CheckParm("-no68kfpu") != 0;
  479.   if (no68kFPU) {
  480.      if (!(MathIeeeDoubBasBase = OpenLibrary("mathieeedoubbas.library",36)))
  481.        Sys_Error("mathieeedoubbas.library is missing");
  482.   }
  483. #endif
  484.  
  485.   amiga_stdin = Input();
  486.   amiga_stdout = Output();
  487.  
  488.   coninput = COM_CheckParm("-console");
  489.   if (coninput)
  490.     SetMode(amiga_stdin,1);  /* put console into RAW mode */
  491.  
  492.   /* open timer.device */
  493. #ifdef __STORM__
  494.   if (timerport = CreateMsgPort()) {
  495.     if (timerio = CreateIORequest(timerport,sizeof(struct timerequest))) {
  496.       if (OpenDevice(TIMERNAME,UNIT_MICROHZ,
  497.                      (struct IORequest *)timerio,0) == 0) {
  498.         TimerBase = (struct Library *)timerio->tr_node.io_Device;
  499.       }
  500.       else {
  501.         DeleteIORequest(timerio);
  502.         DeleteMsgPort(timerport);
  503.       }
  504.     }
  505.     else
  506.       DeleteMsgPort(timerport);
  507.   }
  508. #else
  509.   if (timerport = CreatePort(NULL,0)) {
  510.     if (timerio = (struct timerequest *)
  511.                    CreateExtIO(timerport,sizeof(struct timerequest))) {
  512.       if (OpenDevice(TIMERNAME,UNIT_MICROHZ,
  513.                      (struct IORequest *)timerio,0) == 0) {
  514.         TimerBase = (struct Library *)timerio->tr_node.io_Device;
  515.       }
  516.       else {
  517.         DeleteStdIO((struct IOStdReq *)timerio);
  518.         DeletePort(timerport);
  519.       }
  520.     }
  521.     else
  522.       DeletePort(timerport);
  523.   }
  524. #endif
  525.  
  526.   if (!TimerBase)
  527.     Sys_Error("Can't open timer.device");
  528.   usleep(1);  /* don't delete, otherwise we can't do timer.device cleanup */
  529.  
  530. #if defined(__PPC__) && !defined(WOS)
  531.   /* init GetSysTimePPC() emulation for PowerUp */
  532.   InitSysTimePPC();
  533. #endif
  534.  
  535. #ifdef __PPC__
  536.   GetSysTimePPC(&tv);
  537.   FirstTime = tv.tv_secs;
  538.   GetSysTime(&tv);
  539.   FirstTime2 = tv.tv_secs;
  540. #else
  541.   GetSysTime(&tv);
  542.   FirstTime2 = FirstTime = tv.tv_secs;
  543. #endif
  544.  
  545.   /* check arguments */
  546.   nostdout = (COM_CheckParm("-nostdout"));
  547. #ifndef __PPC__
  548.   if (COM_CheckParm("-hack"))
  549.     MMUHackOn();
  550. #endif
  551.  
  552.   if (i = COM_CheckParm("-mem"))
  553.     parms.memsize = (int)(Q_atof(com_argv[i+1]) * 1024 * 1024);
  554.  
  555.   /* alloc 16-byte aligned quake memory */
  556.   parms.memsize = (parms.memsize+15)&~15;
  557.   if ((parms.membase = AllocMem((ULONG)parms.memsize,MEMF_FAST)) == NULL)
  558.     Sys_Error("Can't allocate %ld bytes\n", parms.memsize);
  559.   if ((ULONG)parms.membase & 8)
  560.     membase_offs = 40;  /* guarantee 16-byte aligment */
  561.   else
  562.     membase_offs = 32;
  563.   parms.membase = (char *)parms.membase + membase_offs;
  564.   parms.memsize -= 3*32;
  565.  
  566.   /* get name of current directory */
  567.   GetCurrentDirName(cwd,128);
  568.   parms.basedir = cwd;
  569.  
  570.   /* set the clock constant */
  571.   if (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",36)) {
  572.     if (GfxBase->DisplayFlags & PAL)
  573.       sysclock = CLOCK_PAL;
  574.     else
  575.       sysclock = CLOCK_NTSC;
  576.     CloseLibrary((struct Library *)GfxBase);
  577.   }
  578.  
  579.   Sys_Init();
  580.  
  581.   Host_Init(&parms);
  582.  
  583.   oldtime = Sys_DoubleTime ();
  584.   while (1) {
  585.     /* find time spent rendering last frame */
  586.     newtime = Sys_DoubleTime ();
  587.     time = newtime - oldtime;
  588.  
  589.     Host_Frame(time);
  590.     oldtime = newtime;
  591.   }
  592. }
  593.  
  594.  
  595. /*
  596. ================
  597. Sys_MakeCodeWriteable
  598. ================
  599. */
  600. void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length)
  601. {
  602. }
  603.