home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quake_src / sys_amiga.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-17  |  12.0 KB  |  563 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. ** Quake for Amiga M68k and Amiga PowerPC
  25. **
  26. ** Written by Frank Wille <frank@phoenix.owl.de>
  27. **
  28. */
  29.  
  30. #pragma amiga-align
  31. #include <exec/types.h>
  32. #include <exec/memory.h>
  33. #include <exec/execbase.h>
  34. #include <dos/dos.h>
  35. #include <utility/tagitem.h>
  36. #include <graphics/gfxbase.h>
  37. #include <devices/timer.h>
  38. #include <proto/exec.h>
  39. #include <proto/dos.h>
  40. #include <proto/timer.h>
  41. #ifdef __PPC__
  42. #ifdef WOS
  43. #include <clib/powerpc_protos.h>
  44. #else
  45. #include <powerup/ppclib/time.h>
  46. #include <powerup/gcclib/powerup_protos.h>
  47. #endif
  48. #endif
  49. #pragma default-align
  50.  
  51. #include "quakedef.h"
  52. #if defined(__PPC__) && !defined(WOS)
  53. #include "sys_timer.h"  /* GetSysTimePPC() emulation for PowerUp */
  54. #endif
  55.  
  56. #define MAX_HANDLES     10
  57. #define CLOCK_PAL       3546895
  58. #define CLOCK_NTSC      3579545
  59.  
  60. #ifdef __STORM__
  61. extern struct Library *TimerBase;
  62. extern struct Library *UtilityBase;
  63. #else
  64. struct Library *TimerBase = NULL;
  65. struct Library *UtilityBase = NULL;
  66. #endif
  67. struct Library *LowLevelBase = NULL;
  68. #ifdef __PPC__
  69. #ifdef __STORM__
  70. extern struct Library *MathIeeeDoubBasBase = NULL;
  71. #else
  72. struct Library *MathIeeeDoubBasBase;
  73. #endif
  74. qboolean no68kFPU = false; /* for LC040/LC060 systems */
  75. #endif
  76. qboolean isDedicated = false;
  77. long sysclock = CLOCK_PAL;
  78. int FirstTime = 0;
  79. int FirstTime2 = 0;
  80.  
  81. static BPTR amiga_stdin,amiga_stdout;
  82. static BPTR sys_handles[MAX_HANDLES];
  83. static struct timerequest *timerio;
  84. static int membase_offs = 32;
  85. static int nostdout=0, coninput=0;
  86.  
  87. #ifndef __PPC__
  88. extern void MMUHackOn(void);
  89. extern void MMUHackOff(void);
  90. #endif
  91.  
  92.  
  93. /*
  94. ===============================================================================
  95.  
  96. FILE IO
  97.  
  98. ===============================================================================
  99. */
  100.  
  101. static int findhandle (void)
  102. {
  103.   int i;
  104.   
  105.   for (i=1 ; i<MAX_HANDLES ; i++)
  106.     if (!sys_handles[i])
  107.       return i;
  108.   Sys_Error ("out of handles");
  109.   return -1;
  110. }
  111.  
  112. int Sys_FileOpenRead (char *path, int *hndl)
  113. {
  114.   BPTR fh;
  115.   struct FileInfoBlock *fib;
  116.   int     i = -1;
  117.   int flen = -1;
  118.   
  119.   *hndl = -1;
  120.   if (fib = AllocDosObjectTags(DOS_FIB,TAG_DONE)) {
  121.     if (fh = Open(path,MODE_OLDFILE)) {
  122.       if (ExamineFH(fh,fib)) {
  123.         if ((i = findhandle()) > 0) {
  124.           sys_handles[i] = fh;
  125.           *hndl = i;
  126.           flen = (int)fib->fib_Size;
  127.         }
  128.         else
  129.           Close(fh);
  130.       }
  131.       else
  132.         Close(fh);
  133.     }
  134.     FreeDosObject(DOS_FIB,fib);
  135.   }
  136.   return flen;
  137. }
  138.  
  139. int Sys_FileOpenWrite (char *path)
  140. {
  141.   BPTR fh;
  142.   int  i;
  143.   
  144.   if ((i = findhandle ()) > 0) {
  145.     if (fh = Open(path,MODE_NEWFILE)) {
  146.       sys_handles[i] = fh;
  147.     }
  148.     else {
  149.       char ebuf[80];
  150.       Fault(IoErr(),"",ebuf,80);
  151.       Sys_Error ("Error opening %s: %s", path, ebuf);
  152.       i = -1;
  153.     }
  154.   }
  155.   return i;
  156. }
  157.  
  158. void Sys_FileClose (int handle)
  159. {
  160.   if (sys_handles[handle]) {
  161.     Close(sys_handles[handle]);
  162.     sys_handles[handle] = 0;
  163.   }
  164. }
  165.  
  166. void Sys_FileSeek (int handle, int position)
  167. {
  168.   Seek(sys_handles[handle],position,OFFSET_BEGINNING);
  169. }
  170.  
  171. int Sys_FileRead (int handle, void *dest, int count)
  172. {
  173.   return (int)Read(sys_handles[handle],dest,(LONG)count);
  174. }
  175.  
  176. int Sys_FileWrite (int handle, void *data, int count)
  177. {
  178.   return (int)Write(sys_handles[handle],data,(LONG)count);
  179. }
  180.  
  181. int Sys_FileTime (char *path)
  182. {
  183.   BPTR lck;
  184.   int  t = -1;
  185.  
  186.   if (lck = Lock(path,ACCESS_READ)) {
  187.     t = 1;
  188.     UnLock(lck);
  189.   }
  190.  
  191.   return t;
  192. }
  193.  
  194. void Sys_mkdir (char *path)
  195. {
  196.   BPTR lck;
  197.  
  198.   if (lck = CreateDir(path))
  199.     UnLock(lck);
  200. }
  201.  
  202.  
  203. /*
  204. ===============================================================================
  205.  
  206. SYSTEM Functions
  207.  
  208. ===============================================================================
  209. */
  210.  
  211. /*
  212. ================
  213. usleep
  214. ================
  215. */
  216. void usleep(unsigned long timeout)
  217. {
  218.   timerio->tr_node.io_Command = TR_ADDREQUEST;
  219.   timerio->tr_time.tv_secs = timeout / 1000000;
  220.   timerio->tr_time.tv_micro = timeout % 1000000;
  221.   SendIO((struct IORequest *)timerio);
  222.   WaitIO((struct IORequest *)timerio);
  223. }
  224.  
  225. /*
  226. ================
  227. strcasecmp
  228. ================
  229. */
  230. int strcasecmp(const char *str1, const char *str2)
  231. {
  232.   while(tolower((unsigned char)*str1) == tolower((unsigned char)*str2)) {
  233.     if(!*str1) return(0);
  234.     str1++;str2++;
  235.   }
  236.   return(tolower(*(unsigned char *)str1)-tolower(*(unsigned char *)str2));
  237. }
  238.  
  239. /*
  240. ================
  241. strncasecmp
  242. ================
  243. */
  244. int strncasecmp(const char *str1, const char *str2, size_t n)
  245. {
  246.   if (n==0) return 0;
  247.   while (--n && tolower((unsigned char)*str1)==tolower((unsigned char)*str2)){
  248.     if (!*str1) return(0);
  249.     str1++; str2++;
  250.   }
  251.   return(tolower(*(unsigned char *)str1)-tolower(*(unsigned char *)str2));
  252. }
  253.  
  254.  
  255. static void cleanup(int rc)
  256. {
  257.   int i;
  258.  
  259.   Host_Shutdown();
  260.  
  261.   if (coninput)
  262.     SetMode(amiga_stdin,0);  /* put console back into normal CON mode */
  263.  
  264.   if (host_parms.membase)
  265.     FreeMem((byte *)host_parms.membase-membase_offs,host_parms.memsize+3*32);
  266.  
  267. #ifndef __PPC__
  268.   if (COM_CheckParm("-hack"))
  269.   MMUHackOff();
  270. #endif
  271.  
  272. #ifdef __STORM__
  273.   if (TimerBase) {
  274.     if (!CheckIO((struct IORequest *)timerio)) {
  275.       AbortIO((struct IORequest *)timerio);
  276.       WaitIO((struct IORequest *)timerio);
  277.     }
  278.     CloseDevice((struct IORequest *)timerio);
  279.     DeleteMsgPort(timerio->tr_node.io_Message.mn_ReplyPort);
  280.     DeleteIORequest(timerio);
  281.   }
  282. #else
  283.   if (TimerBase) {
  284.     if (!CheckIO((struct IORequest *)timerio)) {
  285.       AbortIO((struct IORequest *)timerio);
  286.       WaitIO((struct IORequest *)timerio);
  287.     }
  288.     CloseDevice((struct IORequest *)timerio);
  289.     DeletePort(timerio->tr_node.io_Message.mn_ReplyPort);
  290.     DeleteExtIO((struct IORequest *)timerio);
  291.   }
  292. #endif
  293.  
  294. #ifdef __PPC__
  295.   if (no68kFPU) {
  296.     if (MathIeeeDoubBasBase)
  297.       CloseLibrary(MathIeeeDoubBasBase);
  298.   }
  299. #endif
  300.  
  301.   if (LowLevelBase)
  302.     CloseLibrary(LowLevelBase);
  303.   if (UtilityBase)
  304.     CloseLibrary(UtilityBase);
  305.  
  306.   for (i=1; i<MAX_HANDLES; i++) {
  307.     if (sys_handles[i])
  308.       Close(sys_handles[i]);
  309.   }
  310.   exit(rc);
  311. }
  312.  
  313.  
  314. void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length)
  315. {
  316. }
  317.  
  318.  
  319. void Sys_DebugLog(char *file, char *fmt, ...)
  320. {
  321.   va_list argptr; 
  322.   static char data[1024];
  323.   BPTR fh;
  324.  
  325.   va_start(argptr, fmt);
  326.   vsprintf(data, fmt, argptr);
  327.   va_end(argptr);
  328.   if (fh = Open(file,MODE_READWRITE)) {
  329.     Seek(fh,0,OFFSET_END);
  330.     Write(fh,data,(LONG)strlen(data));
  331.     Close(fh);
  332.   }
  333. }
  334.  
  335. void Sys_Error (char *error, ...)
  336. {
  337.   va_list         argptr;
  338.  
  339.   printf ("I_Error: ");   
  340.   va_start (argptr,error);
  341.   vprintf (error,argptr);
  342.   va_end (argptr);
  343.   printf ("\n");
  344.  
  345.   if (cls.state == ca_connected) {
  346.     printf("disconnecting from server...\n");
  347.     CL_Disconnect ();   /* leave server gracefully (phx) */
  348.   }
  349.   cleanup(1);
  350. }
  351.  
  352. void Sys_Printf (char *fmt, ...)
  353. {
  354.   if (!nostdout) {
  355.     va_list         argptr;
  356.  
  357.     va_start (argptr,fmt);
  358.     vprintf (fmt,argptr);
  359.     va_end (argptr);
  360.   }
  361. }
  362.  
  363. void Sys_Quit (void)
  364. {
  365.   cleanup(0);
  366. }
  367.  
  368. double Sys_FloatTime (void)
  369. {
  370.   struct timeval tv;
  371.  
  372. #ifdef __PPC__
  373.   GetSysTimePPC(&tv);
  374. #else
  375.   GetSysTime(&tv);
  376. #endif
  377.   return ((double)(tv.tv_secs-FirstTime) + (((double)tv.tv_micro) / 1000000.0));
  378. }
  379.  
  380. char *Sys_ConsoleInput (void)
  381. {
  382.   if (coninput) {
  383.     static const char *backspace = "\b \b";
  384.     static char text[256];
  385.     static int len = 0;
  386.     char ch;
  387.  
  388.     while (WaitForChar(amiga_stdin,10) == DOSTRUE) {
  389.       Read(amiga_stdin,&ch,1);  /* note: console is in RAW mode! */
  390.       if (ch == '\r') {
  391.         ch = '\n';
  392.         Write(amiga_stdout,&ch,1);
  393.         text[len] = 0;
  394.         len = 0;
  395.         return text;
  396.       }
  397.       else if (ch == '\b') {
  398.         if (len > 0) {
  399.           len--;
  400.           Write(amiga_stdout,(char *)backspace,3);
  401.         }
  402.       }
  403.       else {
  404.         if (len < sizeof(text)-1) {
  405.           Write(amiga_stdout,&ch,1);
  406.           text[len++] = ch;
  407.         }
  408.       }
  409.     }
  410.   }
  411.   return NULL;
  412. }
  413.  
  414. void Sys_Sleep (void)
  415. {
  416. }
  417.  
  418. void Sys_HighFPPrecision (void)
  419. {
  420. }
  421.  
  422. void Sys_LowFPPrecision (void)
  423. {
  424. }
  425.  
  426.  
  427. //=============================================================================
  428.  
  429. main (int argc, char *argv[])
  430. {
  431.   struct timeval tv;
  432.   quakeparms_t parms;
  433.   double time, oldtime, newtime;
  434.   struct MsgPort *timerport;
  435.   char cwd[128];
  436.   struct GfxBase *GfxBase;
  437.   int i;
  438.  
  439.   memset(&parms,0,sizeof(parms));
  440.   parms.memsize = 16*1024*1024;  /* 16MB is default */
  441.  
  442.   /* parse command string */
  443.   COM_InitArgv (argc, argv);
  444.   parms.argc = com_argc;
  445.   parms.argv = com_argv;
  446.  
  447. #ifndef __PPC__
  448.   if (COM_CheckParm("-hack"))
  449.   MMUHackOn();
  450. #endif
  451.  
  452.   host_parms.membase = parms.cachedir = NULL;
  453.   if ((UtilityBase = OpenLibrary("utility.library",36)) == NULL ||
  454.       (LowLevelBase = OpenLibrary("lowlevel.library",36)) == NULL)
  455.     Sys_Error("OS2.0 required!");
  456. #ifdef __PPC__
  457.   no68kFPU = COM_CheckParm("-no68kfpu") != 0;
  458.   if (no68kFPU) {
  459.      if (!(MathIeeeDoubBasBase = OpenLibrary("mathieeedoubbas.library",36)))
  460.        Sys_Error("mathieeedoubbas.library is missing");
  461.   }
  462. #endif
  463.   amiga_stdin = Input();
  464.   amiga_stdout = Output();
  465.  
  466.   isDedicated = COM_CheckParm("-dedicated") != 0;
  467.   nostdout = COM_CheckParm("-nostdout");
  468.   coninput = COM_CheckParm("-console");
  469.   if (coninput)
  470.     SetMode(amiga_stdin,1);  /* put console into RAW mode */
  471.  
  472.   /* open timer.device */
  473. #ifdef __STORM__  
  474.   if (timerport = CreateMsgPort()) {
  475.     if (timerio = CreateIORequest(timerport,sizeof(struct timerequest))) {
  476.       if (OpenDevice(TIMERNAME,UNIT_MICROHZ,
  477.                      (struct IORequest *)timerio,0) == 0) {
  478.         TimerBase = (struct Library *)timerio->tr_node.io_Device;
  479.       }
  480.       else {
  481.         DeleteIORequest(timerio);
  482.         DeleteMsgPort(timerport);
  483.       }
  484.     }
  485.     else
  486.       DeleteMsgPort(timerport);
  487.   }
  488. #else
  489.   if (timerport = CreatePort(NULL,0)) {
  490.     if (timerio = (struct timerequest *)
  491.                    CreateExtIO(timerport,sizeof(struct timerequest))) {
  492.       if (OpenDevice(TIMERNAME,UNIT_MICROHZ,
  493.                      (struct IORequest *)timerio,0) == 0) {
  494.         TimerBase = (struct Library *)timerio->tr_node.io_Device;
  495.       }
  496.       else {
  497.         DeleteExtIO((struct IORequest *)timerio);
  498.         DeletePort(timerport);
  499.       }
  500.     }
  501.     else
  502.       DeletePort(timerport);
  503.   }
  504. #endif
  505.  
  506.   if (!TimerBase)
  507.     Sys_Error("Can't open timer.device");
  508.   usleep(1);  /* don't delete, otherwise we can't do timer.device cleanup */
  509.  
  510. #if defined(__PPC__) && !defined(WOS)
  511.   /* init GetSysTimePPC() emulation for PowerUp */
  512.   InitSysTimePPC();
  513. #endif
  514.  
  515. #ifdef __PPC__
  516.   GetSysTimePPC(&tv);
  517.   FirstTime = tv.tv_secs;
  518.   GetSysTime(&tv);
  519.   FirstTime2 = tv.tv_secs;
  520. #else
  521.   GetSysTime(&tv);
  522.   FirstTime2 = FirstTime = tv.tv_secs;
  523. #endif
  524.  
  525.   if (i = COM_CheckParm("-mem"))
  526.     parms.memsize = (int)(Q_atof(com_argv[i+1]) * 1024 * 1024);
  527.  
  528.   /* alloc 16-byte aligned quake memory */
  529.   parms.memsize = (parms.memsize+15)&~15;
  530.   if ((parms.membase = AllocMem((ULONG)parms.memsize,MEMF_FAST)) == NULL)
  531.     Sys_Error("Can't allocate %ld bytes\n", parms.memsize);
  532.   if ((ULONG)parms.membase & 8)
  533.     membase_offs = 40;  /* guarantee 16-byte aligment */
  534.   else
  535.     membase_offs = 32;
  536.   parms.membase = (char *)parms.membase + membase_offs;
  537.   parms.memsize -= 3*32;
  538.  
  539.   /* get name of current directory */
  540.   GetCurrentDirName(cwd,128);
  541.   parms.basedir = cwd;
  542.  
  543.   /* set the clock constant */
  544.   if (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",36)) {
  545.     if (GfxBase->DisplayFlags & PAL)
  546.       sysclock = CLOCK_PAL;
  547.     else
  548.       sysclock = CLOCK_NTSC;
  549.     CloseLibrary((struct Library *)GfxBase);
  550.   }
  551.  
  552.   Host_Init (&parms);
  553.   oldtime = Sys_FloatTime () - 0.1;
  554.   while (1)
  555.   {
  556.     newtime = Sys_FloatTime ();
  557.     time = newtime - oldtime;
  558.     Host_Frame (time);
  559.  
  560.     oldtime = newtime;
  561.   }
  562. }
  563.