home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 15 / MA_Cover_15.iso / source / winquake / vid_amiga.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-26  |  25.5 KB  |  878 lines

  1. /*
  2. Copyright (C) 2000 Peter McGavin.
  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. // vid_amiga.h -- amiga video driver
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <signal.h>
  25. #ifdef __SASC
  26. #include <dos.h>
  27. #endif
  28.  
  29. #include <exec/exec.h>
  30. #include <dos/dos.h>
  31. #include <graphics/gfx.h>
  32. #include <graphics/gfxbase.h>
  33. #include <intuition/intuition.h>
  34. #include <utility/tagitem.h>
  35. #include <libraries/asl.h>
  36. #include <cybergraphics/cybergraphics.h>
  37. #include <devices/timer.h>
  38.  
  39. #if defined(__VBCC__) || (defined(__STORM__) && defined(__PPC__))
  40. #include <clib/exec_protos.h>
  41. #include <clib/dos_protos.h>
  42. #include <clib/graphics_protos.h>
  43. #include <clib/intuition_protos.h>
  44. #include <clib/asl_protos.h>
  45. #include <clib/cybergraphics_protos.h>
  46. #else
  47. #include <proto/exec.h>
  48. #include <proto/dos.h>
  49. #include <proto/graphics.h>
  50. #include <proto/intuition.h>
  51. #include <proto/asl.h>
  52. #ifndef __PPC__
  53. #include <proto/timer.h>
  54. #endif
  55. #include <proto/cybergraphics.h>
  56. #endif
  57.  
  58. #include "quakedef.h"
  59. #include "d_local.h"
  60.  
  61. #if defined(__PPC__) && defined(__SASC)
  62. #include "amiga_ppc_stubs.h"
  63. #endif
  64.  
  65. #ifdef __PPC__
  66. extern void ppc_c2p_line (int line, int src, struct BitMap *dst, int cnt);
  67. #else
  68. #include "c2p8_040_amlaukka.h"
  69. #endif
  70.  
  71. extern qboolean using_mouse;
  72. extern short int last_mouse[2];
  73. extern qboolean mouse_has_moved;
  74.  
  75. #define    BASEWIDTH    320
  76. #define    BASEHEIGHT    200
  77.  
  78. #if 0
  79.  static byte    vid_buffer[BASEWIDTH*BASEHEIGHT];
  80.  static short    zbuffer[BASEWIDTH*BASEHEIGHT];
  81.  /* static byte    surfcache[256*1024]; */
  82.  static byte    surfcache[(BASEWIDTH*BASEHEIGHT/(320*200))*256*1024*2];
  83. #else
  84.  static pixel_t *vid_buffer = NULL;
  85.  static short *zbuffer = NULL;
  86.  static byte *surfcache = NULL;
  87. #endif
  88.  
  89. unsigned short    d_8to16table[256];
  90. /* unsigned    d_8to24table[256]; */
  91.  
  92. /**********************************************************************/
  93.  
  94. #if defined(__STORM__) || defined(__VBCC__)
  95. extern struct GfxBase *GfxBase;
  96. #endif
  97. struct Library *CyberGfxBase = NULL;
  98. struct Library *AslBase = NULL;
  99.  
  100. static struct Screen *video_screen = NULL;
  101. static struct Window *video_window = NULL;
  102. static struct RastPort tmp_rp, rp;
  103. static struct ScreenModeRequester *smr = NULL;
  104. static struct ScreenBuffer *sbuffer[3] = {NULL, NULL, NULL};
  105. static struct ScreenBuffer *nextsbuffer = NULL;
  106. static APTR bitmap_handle = NULL;
  107. static BOOL is_cyber_mode = FALSE;
  108. static BOOL is_native_mode = FALSE;
  109. static BOOL is_directcgx = FALSE;
  110. static BOOL do_fps = FALSE;
  111. static UWORD *emptypointer;
  112. static struct RastPort temprp;
  113. static struct BitMap tmp_bm = {
  114.   0, 0, 0, 0, 0, {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
  115. };
  116.  
  117. #ifndef __PPC__
  118. struct Library *TimerBase = NULL;
  119. static struct MsgPort *timermp = NULL;
  120. static struct timerequest *timerio = NULL;
  121. static ULONG timerclosed = TRUE;
  122. static ULONG eclocks_per_second; /* EClock frequency in Hz */
  123.  
  124. void *c2p[3] = {NULL, NULL, NULL};
  125. void *nextc2p = NULL;
  126. #endif
  127.  
  128. /**********************************************************************/
  129. void    VID_SetPalette (unsigned char *palette)
  130. {
  131.   int i;
  132.   ULONG v;
  133.   static ULONG colourtable[1+3*256+1];
  134.  
  135.   colourtable[0] = (256 << 16) + 0;
  136.   for (i = 0; i < 3*256; i++) {
  137.     v = *palette++;
  138.     v += (v << 8);
  139.     v += (v << 16);
  140.     colourtable[i+1] = v;
  141.   }
  142.   colourtable[1 + 3*256] = 0;
  143.   LoadRGB32 (&video_screen->ViewPort, colourtable);
  144. }
  145.  
  146. /**********************************************************************/
  147. void    VID_ShiftPalette (unsigned char *palette)
  148. {
  149.   VID_SetPalette (palette);
  150. }
  151.  
  152. /****************************************************************************/
  153. #ifndef __PPC__
  154. static ULONG __saveds __asm smr_filter (register __a0 struct Hook *smr_filter_hook,
  155.                                         register __a2 struct ScreenModeRequester *smr,
  156.                                         register __a1 ULONG mode)
  157. /* reject modes deeper than depth 8 */
  158. /* (because setting ASLSM_MaxDepth = 8 seems to be insufficient) */
  159. {
  160.   UWORD count;
  161.   struct DimensionInfo dimsinfo;
  162.   void *handle;
  163.  
  164.   if ((handle = FindDisplayInfo (mode)) != NULL &&
  165.       (count = GetDisplayInfoData (handle, (UBYTE *)&dimsinfo,
  166.                                    sizeof(struct DimensionInfo), DTAG_DIMS,
  167.                                    NULL)) < 66
  168.                                              /* sizeof(struct DimensionInfo) */)
  169.     Sys_Error ("GetDisplayInfoData(Dims) failed");
  170.   return (ULONG)(dimsinfo.MaxDepth == 8);
  171. }
  172. #endif
  173.  
  174. /**********************************************************************/
  175. void    VID_Init (unsigned char *palette)
  176. {
  177.   int mode, width, height, nbytes, d;
  178. #ifndef __PPC__
  179.   struct EClockVal start_time;
  180.   static struct Hook smr_filter_hook = {
  181.     {NULL},
  182.     (ULONG (*)())smr_filter,
  183.     NULL,
  184.     NULL
  185.   };
  186. #endif
  187.   ULONG propertymask, idcmp, flags;
  188.   DisplayInfoHandle handle;
  189.   struct DisplayInfo dispinfo;
  190.   static struct TextAttr topaz8 = {
  191.     "topaz.font", 8, FS_NORMAL, FPF_ROMFONT
  192.   };
  193.  
  194. //  printf ("VID_Init %08x\n", palette);
  195.  
  196. #ifndef __PPC__
  197.   if ((timermp = CreatePort (NULL, 0)) == NULL)
  198.     Sys_Error ("Can't create messageport!");
  199.   if ((timerio = (struct timerequest *)CreateExtIO (timermp,
  200.                   sizeof(struct timerequest))) == NULL)
  201.     Sys_Error ("Can't create External IO!");
  202.   if (timerclosed = OpenDevice (TIMERNAME, UNIT_ECLOCK,
  203.                                 (struct IORequest *)timerio, 0))
  204.     Sys_Error ("Can't open timer.device!");
  205.   TimerBase = (struct Library *)timerio->tr_node.io_Device;
  206.   eclocks_per_second = ReadEClock (&start_time);
  207. #endif
  208.  
  209.   CyberGfxBase = OpenLibrary ("cybergraphics.library", 0);
  210.  
  211.   if ((AslBase = OpenLibrary ("asl.library", 38L)) == NULL ||
  212.       (smr = AllocAslRequestTags (ASL_ScreenModeRequest, TAG_END)) == NULL)
  213.     Sys_Error ("OpenLibrary(""asl.library"", 38) failed");
  214.  
  215.   propertymask = DIPF_IS_EXTRAHALFBRITE | DIPF_IS_DUALPF | DIPF_IS_PF2PRI |
  216.                  DIPF_IS_HAM;
  217.   if (CyberGfxBase != NULL)
  218.     mode = BestCModeIDTags (CYBRBIDTG_NominalWidth,  BASEWIDTH,
  219.                             CYBRBIDTG_NominalHeight, BASEHEIGHT,
  220.                             CYBRBIDTG_Depth,         8,
  221.                             TAG_DONE);
  222.   else if (GfxBase->LibNode.lib_Version >= 39)
  223.     mode = BestModeID (BIDTAG_NominalWidth,     BASEWIDTH,
  224.                        BIDTAG_NominalHeight,    BASEHEIGHT,
  225.                        BIDTAG_Depth,            8,
  226.                        BIDTAG_DIPFMustNotHave,  propertymask,
  227.                        TAG_DONE);
  228.   else
  229.     mode = 0;
  230.  
  231.   if (!AslRequestTags (smr,
  232.                        ASLSM_TitleText,            (ULONG)"Quake",
  233.                        ASLSM_InitialDisplayID,     mode,
  234.                        ASLSM_InitialDisplayWidth,  BASEWIDTH,
  235.                        ASLSM_InitialDisplayHeight, BASEHEIGHT,
  236.                        ASLSM_MinWidth,             BASEWIDTH,
  237.                        ASLSM_MinHeight,            BASEHEIGHT,
  238. /*
  239.                        ASLSM_MaxWidth,             BASEWIDTH,
  240.                        ASLSM_MaxHeight,            BASEHEIGHT,
  241. */
  242.                        ASLSM_MinDepth,             8,
  243.                        ASLSM_MaxDepth,             8,
  244.                        ASLSM_PropertyMask,         propertymask,
  245.                        ASLSM_PropertyFlags,        0,
  246.                        ASLSM_DoWidth,              TRUE,
  247.                        ASLSM_DoHeight,             TRUE,
  248. #ifndef __PPC__
  249.                        ASLSM_FilterFunc,           &smr_filter_hook,
  250. #endif
  251.                        TAG_END))
  252.     Sys_Error ("AslRequestTags() failed");
  253.  
  254.   mode = smr->sm_DisplayID;
  255.   width = smr->sm_DisplayWidth;
  256.   height = smr->sm_DisplayHeight;
  257.  
  258.   if ((handle = FindDisplayInfo (mode)) == NULL) {
  259.     Sys_Error ("Can't FindDisplayInfo() for mode %08x", mode);
  260.   }
  261.   nbytes = GetDisplayInfoData (handle, (UBYTE *)&dispinfo,
  262.                                sizeof(struct DisplayInfo), DTAG_DISP,
  263.                                0);
  264.   if (nbytes < 40 /*sizeof(struct DisplayInfo)*/)
  265.     Sys_Error ("Can't GetDisplayInfoData() for mode %08x, got %d bytes",
  266.                mode, nbytes);
  267.  
  268.   is_cyber_mode = 0;
  269.   if (CyberGfxBase != NULL)
  270.     is_cyber_mode = IsCyberModeID (mode);
  271.  
  272.   /* this test needs improving */
  273.   is_native_mode = ((GfxBase->LibNode.lib_Version < 39 ||
  274.                      (dispinfo.PropertyFlags & DIPF_IS_EXTRAHALFBRITE) != 0 ||
  275.                      (dispinfo.PropertyFlags & DIPF_IS_AA) != 0 ||
  276.                      (dispinfo.PropertyFlags & DIPF_IS_ECS) != 0 ||
  277.                      (dispinfo.PropertyFlags & DIPF_IS_DBUFFER) != 0) &&
  278.                     !is_cyber_mode &&
  279.                     (dispinfo.PropertyFlags & DIPF_IS_FOREIGN) == 0);
  280.  
  281.   Con_Printf ("Screen Mode $%08x is", mode);
  282.   if (is_native_mode)
  283.     Con_Printf (" NATIVE-PLANAR");
  284.   else
  285.     Con_Printf (" FOREIGN");
  286.   Con_Printf (" 8-BIT");
  287.   if (is_cyber_mode)
  288.     Con_Printf (" CYBERGRAPHX");
  289.   Con_Printf (", using size %d x %d\n", width, height);
  290.  
  291.   if ((video_screen = OpenScreenTags (NULL,
  292.         SA_Type,        CUSTOMSCREEN,
  293.         SA_DisplayID,   mode,
  294.         /* SA_DClip,       (ULONG)&rect, */
  295.         SA_Width,       width,
  296.         SA_Height,      height,
  297.         SA_Depth,       8,
  298.         SA_Font,        &topaz8,
  299.         /* SA_Draggable,FALSE, */
  300.         /* SA_AutoScroll,FALSE, */
  301.         /* SA_Exclusive,TRUE, */
  302.         SA_Quiet,       TRUE,
  303.         TAG_DONE,       0)) == NULL) {
  304.     Sys_Error ("OpenScreen() failed");
  305.   }
  306.  
  307.   idcmp = IDCMP_RAWKEY;
  308.   flags = WFLG_ACTIVATE | WFLG_BORDERLESS | WFLG_NOCAREREFRESH |
  309.           WFLG_SIMPLE_REFRESH;
  310.   if (using_mouse) {
  311.     idcmp |= IDCMP_MOUSEBUTTONS | IDCMP_DELTAMOVE | IDCMP_MOUSEMOVE;
  312.     flags |= WFLG_RMBTRAP | WFLG_REPORTMOUSE;
  313.   }
  314.   if ((video_window = OpenWindowTags (NULL,
  315.         WA_Left,         0,
  316.         WA_Top,          0,
  317.         WA_Width,        width,
  318.         WA_Height,       height,
  319.         WA_IDCMP,        idcmp,
  320.         WA_Flags,        flags,
  321.         WA_CustomScreen, video_screen,
  322.         TAG_DONE,        0)) == NULL) {
  323.     Sys_Error ("OpenWindow() failed");
  324.   }
  325.   if (!COM_CheckParm ("-mousepointer")) {
  326.     if ((emptypointer = AllocVec (16, MEMF_CHIP | MEMF_CLEAR)) == NULL)
  327.       Sys_Error ("Couldn't allocate chip memory for pointer");
  328.     SetPointer (video_window, emptypointer, 1, 16, 0, 0);
  329.   }
  330.  
  331.   InitRastPort (&tmp_rp);
  332.   tmp_rp.BitMap = NULL;
  333.   InitRastPort (&rp);
  334.   rp.BitMap = video_screen->ViewPort.RasInfo->BitMap;
  335.  
  336.   /* tmp rastport and bitmap for WritePixelArray8() */
  337.   InitBitMap (&tmp_bm, 8, width, 1);
  338.   for (d = 0; d < 8; d++)
  339.     if ((tmp_bm.Planes[d] = (PLANEPTR)AllocRaster (width, 1)) == NULL)
  340.       Sys_Error ("AllocRaster() failed");
  341.   temprp = *video_window->RPort;
  342.   temprp.Layer = NULL;
  343.   temprp.BitMap = &tmp_bm;
  344.  
  345.   if (is_native_mode) {
  346.     if ((sbuffer[0] = AllocScreenBuffer (video_screen, NULL, SB_SCREEN_BITMAP)) == NULL |
  347.         (sbuffer[1] = AllocScreenBuffer (video_screen, NULL, 0)) == NULL ||
  348.         (sbuffer[2] = AllocScreenBuffer (video_screen, NULL, 0)) == NULL)
  349.       Sys_Error ("AllocScreenBuffer() failed");
  350.     nextsbuffer = sbuffer[1];
  351.     rp.BitMap = nextsbuffer->sb_BitMap;
  352. #ifndef __PPC__
  353.     c2p[0] = c2p8_reloc (sbuffer[0]->sb_BitMap);
  354.     c2p[1] = c2p8_reloc (sbuffer[1]->sb_BitMap);
  355.     c2p[2] = c2p8_reloc (sbuffer[2]->sb_BitMap);
  356.     nextc2p = c2p[1];
  357. #endif
  358.   }
  359.  
  360.   is_directcgx = (is_cyber_mode && COM_CheckParm ("-directcgx"));
  361.  
  362.   if (!is_directcgx)
  363.     if ((vid_buffer = (pixel_t *)malloc(sizeof(pixel_t) *
  364.                                         width * height)) == NULL)
  365.       Sys_Error ("Out of memory");
  366.   if ((zbuffer = (short *)malloc(sizeof(short) * width * height)) == NULL ||
  367.       (surfcache = (byte *)malloc(sizeof(byte) *
  368.                                   (width*height/(320*200))*256*1024*2)) == NULL)
  369.     Sys_Error ("Out of memory");
  370.  
  371.   vid.width = vid.conwidth = width;
  372.   vid.height = vid.conheight = height;
  373.   vid.maxwarpwidth = WARP_WIDTH;
  374.   vid.maxwarpheight = WARP_HEIGHT;
  375.   vid.aspect = 1.0;
  376.   if (is_native_mode) {
  377.     if ((mode & (LACE | HIRES)) != (LACE | HIRES)) {
  378.       if (mode & LACE)
  379.         vid.aspect *= 2.0;
  380.       if (mode & HIRES)
  381.         vid.aspect /= 2.0;
  382.     }
  383.     if (mode & SUPERHIRES)
  384.       vid.aspect /= 2.0;
  385.   }
  386.   if (is_native_mode)
  387.     vid.numpages = 3;
  388.   else
  389.     vid.numpages = 1;
  390.   vid.colormap = host_colormap;
  391.   vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
  392.   vid.buffer = vid.conbuffer = vid_buffer;
  393.   vid.rowbytes = vid.conrowbytes = width;
  394.   vid.direct = NULL;
  395.  
  396.   d_pzbuffer = zbuffer;
  397.  
  398.   D_InitCaches (surfcache, sizeof(byte) *
  399.                            (width*height/(320*200))*256*1024*2);
  400.  
  401.   VID_SetPalette (palette);
  402.  
  403.   do_fps = COM_CheckParm("-fps");
  404. }
  405.  
  406. /**********************************************************************/
  407. void    VID_Shutdown (void)
  408. {
  409.   int d;
  410.  
  411. //  printf ("VID_Shutdown\n");
  412.   VID_UnlockBuffer ();
  413.   if (surfcache != NULL) {
  414.     free (surfcache);
  415.     surfcache = NULL;
  416.   }
  417.   if (zbuffer != NULL) {
  418.     free (zbuffer);
  419.     zbuffer = NULL;
  420.   }
  421.   if (vid_buffer != NULL) {
  422.     free (vid_buffer);
  423.     vid_buffer = NULL;
  424.   }
  425.   if (sbuffer[0] != NULL) {
  426.     ChangeScreenBuffer (video_screen, sbuffer[0]);
  427.     WaitTOF ();
  428.     WaitTOF ();
  429.     FreeScreenBuffer (video_screen, sbuffer[0]);
  430.     sbuffer[0] = NULL;
  431.   }
  432.   if (sbuffer[1] != NULL) {
  433.     FreeScreenBuffer (video_screen, sbuffer[1]);
  434.     sbuffer[1] = NULL;
  435.   }
  436.   if (sbuffer[2] != NULL) {
  437.     FreeScreenBuffer (video_screen, sbuffer[2]);
  438.     sbuffer[2] = NULL;
  439.   }
  440.   if (video_window != NULL) {
  441.     ClearPointer (video_window);
  442.     CloseWindow (video_window);
  443.     video_window = NULL;
  444.   }
  445.   if (emptypointer != NULL) {
  446.     FreeVec (emptypointer);
  447.     emptypointer = NULL;
  448.   }
  449.   if (video_screen != NULL) {
  450.     CloseScreen (video_screen);
  451.     video_screen = NULL;
  452.   }
  453.   for (d = 0; d < 8; d++) {
  454.     if (tmp_bm.Planes[d] != NULL) {
  455.       FreeRaster (tmp_bm.Planes[d], vid.width, 1);
  456.       tmp_bm.Planes[d] = NULL;
  457.     }
  458.   }
  459.   if (smr != NULL) {
  460.     FreeAslRequest (smr);
  461.     smr = NULL;
  462.   }
  463.   if (AslBase != NULL) {
  464.     CloseLibrary (AslBase);
  465.     AslBase = NULL;
  466.   }
  467.   if (CyberGfxBase == NULL) {
  468.     CloseLibrary (CyberGfxBase);
  469.     CyberGfxBase = NULL;
  470.   }
  471. #ifndef __PPC__
  472.   if (!timerclosed) {
  473.     if (!CheckIO((struct IORequest *)timerio)) {
  474.       AbortIO ((struct IORequest *)timerio);
  475.       WaitIO ((struct IORequest *)timerio);
  476.     }
  477.     CloseDevice ((struct IORequest *)timerio);
  478.     timerclosed = TRUE;
  479.     TimerBase = NULL;
  480.   }
  481.   if (timerio != NULL) {
  482.     DeleteExtIO ((struct IORequest *)timerio);
  483.     timerio = NULL;
  484.   }
  485.   if (timermp != NULL) {
  486.     DeletePort (timermp);
  487.     timermp = NULL;
  488.   }
  489.   if (c2p[0]) {
  490.     c2p8_deinit (c2p[0]);
  491.     c2p[0] = NULL;
  492.   }
  493.   if (c2p[1]) {
  494.     c2p8_deinit (c2p[1]);
  495.     c2p[1] = NULL;
  496.   }
  497.   if (c2p[2]) {
  498.     c2p8_deinit (c2p[2]);
  499.     c2p[2] = NULL;
  500.   }
  501. #endif
  502. }
  503.  
  504. /**********************************************************************/
  505. #ifdef __SASC
  506. void _STD_VID_Shutdown (void)
  507. {
  508. //  printf ("_STD_VID_Shutdown\n");
  509.   S_Shutdown ();
  510.   VID_Shutdown ();
  511. }
  512. #endif
  513.  
  514. /**********************************************************************/
  515. #ifdef __STORM__
  516. void EXIT_9_VID_Shutdown (void)
  517. {
  518. //  printf ("EXIT_9_VID_Shutdown\n");
  519.   S_Shutdown ();
  520.   VID_Shutdown ();
  521. }
  522. #endif
  523.  
  524. /**********************************************************************/
  525. #ifdef __VBCC__
  526. void _EXIT_9_VID_Shutdown (void)
  527. {
  528. //  printf ("_EXIT_9_VID_Shutdown\n");
  529.   S_Shutdown ();
  530.   VID_Shutdown ();
  531. }
  532. #endif
  533.  
  534. /**********************************************************************/
  535. static void video_do_fps (struct RastPort *rp, int yoffset)
  536. {
  537.   ULONG x;
  538.   char msg[4];
  539.  
  540. #ifdef __PPC__
  541.  
  542.   static double start_time = 0.0;
  543.   double end_time;
  544.  
  545.   end_time = Sys_FloatTime ();
  546.   x = (ULONG)(1.0 / (end_time - start_time) + 0.5);
  547.   if (TRUE) {
  548.  
  549. #else
  550.  
  551.   static struct EClockVal start_time = {0, 0};
  552.   struct EClockVal end_time;
  553.  
  554.   ReadEClock (&end_time);
  555.   x = end_time.ev_lo - start_time.ev_lo;
  556.   if (x != 0) {
  557.     x = (eclocks_per_second + (x >> 1)) / x;   /* round to nearest */
  558.  
  559. #endif
  560.  
  561.     msg[0] = (x % 1000) / 100 + '0';
  562.     msg[1] = (x % 100) / 10 + '0';
  563.     msg[2] = (x % 10) + '0';
  564.     msg[3] = '\0';
  565.     Move (rp, vid.width - 24, yoffset + 6);
  566.     Text (rp, msg, 3);
  567.   }
  568.   start_time = end_time;
  569. }
  570.  
  571. /**********************************************************************/
  572. #if 0
  573. static void PPCWriteChunkyPixels (struct RastPort *dst_rp,
  574.                                   int dst_x, int dst_y, int stop_x, int stop_y,
  575.                                   UBYTE *src, int src_bytesperrow)
  576. {
  577.   APTR bitmap_handle;
  578.   LONG pixfmt, dst_bytesperrow;
  579.   UBYTE *dst;
  580.   static ULONG bitmap_width = 0, bitmap_height = 0;
  581.   int width, height, i;
  582.   static BOOL first = TRUE;
  583.  
  584.   if (!is_cyber_mode) {
  585.     WriteChunkyPixels (dst_rp, dst_x, dst_y, stop_x, stop_y, src,
  586.                        src_bytesperrow);
  587.     return;
  588.   }
  589.   if (first) {
  590.     first = FALSE;
  591.     if (dst_rp == video_window->RPort) {
  592.       bitmap_width = video_window->Width;
  593.       bitmap_height = video_window->Height;
  594.     } else {
  595.       bitmap_width = GetBitMapAttr (dst_rp->BitMap, BMA_WIDTH);
  596.       bitmap_height = GetBitMapAttr (dst_rp->BitMap, BMA_HEIGHT);
  597.     }
  598.   }
  599.   width = stop_x - dst_x + 1;
  600.   height = stop_y - dst_y + 1;
  601.   if (dst_x < 0) {
  602.     src -= dst_x;
  603.     width += dst_x;
  604.     if (width <= 0)
  605.       return;
  606.     dst_x = 0;
  607.   } else if (width > bitmap_width - dst_x) {
  608.     width = bitmap_width - dst_x;
  609.     if (width <= 0)
  610.       return;
  611.   }
  612.   if (dst_y < 0) {
  613.     src -= (dst_y * width);
  614.     height += dst_y;
  615.     if (height <= 0)
  616.       return;
  617.     dst_y = 0;
  618.   } else if (height > bitmap_height - dst_y) {
  619.     height = bitmap_height - dst_y;
  620.     if (height < 0)
  621.       return;
  622.   }
  623.   if ((bitmap_handle = LockBitMapTags (dst_rp->BitMap,
  624.                                        LBMI_BASEADDRESS, &dst,
  625.                                        LBMI_PIXFMT,      &pixfmt,
  626.                                        LBMI_BYTESPERROW, &dst_bytesperrow,
  627.                                        TAG_DONE)) == NULL)
  628.     Sys_Error ("Error locking BitMap");
  629.   dst += dst_y * dst_bytesperrow + dst_x;
  630.   for ( ; height > 0; height--) {
  631.     /* memcpy (dst, src, width); */
  632.     for (i = width >> 2; i > 0; --i) {
  633.       *(ULONG *)dst = *(ULONG *)src;
  634.       dst += 4;
  635.       src += 4;
  636.     }
  637.     dst += dst_bytesperrow - width;
  638.     src += src_bytesperrow - width;
  639.   }
  640.   UnLockBitMap (bitmap_handle);
  641. }
  642. #endif
  643.  
  644. /**********************************************************************/
  645. void VID_LockBuffer (void)
  646. {
  647. //  printf ("Lock\n");
  648.   if (is_directcgx && bitmap_handle == NULL) {
  649.     if ((bitmap_handle = LockBitMapTags (rp.BitMap,
  650.                                          LBMI_BASEADDRESS, &vid.direct,
  651.                                          LBMI_BYTESPERROW, &vid.rowbytes,
  652.                                          TAG_DONE)) == NULL)
  653.       Sys_Error ("Error locking BitMap");
  654.     vid.buffer = vid.conbuffer = vid.direct;
  655.     vid.conrowbytes = vid.rowbytes;
  656.   }
  657. }
  658.  
  659. /**********************************************************************/
  660. void VID_UnlockBuffer (void)
  661. {
  662. //  printf ("Unlock\n");
  663.   if (is_directcgx && bitmap_handle != NULL) {
  664.     UnLockBitMap (bitmap_handle);
  665.     bitmap_handle = NULL;
  666.     vid.buffer = vid.conbuffer = vid.direct = NULL;
  667.   }
  668. }
  669.  
  670. /**********************************************************************/
  671. void    VID_Update (vrect_t *rects)
  672. {
  673. #ifdef __PPC__
  674.   int i, j;
  675. #endif
  676.  
  677.   if (is_directcgx)
  678.     return;
  679.  
  680.   if (is_native_mode) {
  681. #ifdef __PPC__
  682.     while (rects != NULL) {
  683.       for (i = rects->y, j = ((int)(vid.buffer)) + rects->y * vid.width;
  684.            i < rects->y + rects->height; i++, j += vid.width)
  685.         ppc_c2p_line (i, j, rp.BitMap, (vid.width + 31) >> 5);
  686.       rects = rects->pnext;
  687.     }
  688. #else
  689.     if (rects != NULL)
  690.       c2p8 (nextc2p, nextsbuffer->sb_BitMap, vid.buffer,
  691.             vid.width * (rects->y + rects->height));
  692. #endif
  693.   } else {
  694.     while (rects != NULL) {
  695. #if 0
  696.       if (GfxBase->LibNode.lib_Version >= 40)
  697.         WriteChunkyPixels (&rp, rects->x, rects->y,
  698.                            rects->x + rects->width - 1,
  699.                            rects->y + rects->height - 1,
  700.                            vid.buffer, rects->width);
  701.       else if (CyberGfxBase != NULL)
  702.         WritePixelArray (vid.buffer, rects->x, rects->y, rects->width, &rp,
  703.                          rects->x, rects->y, rects->width, rects->height,
  704.                          RECTFMT_LUT8);
  705.       else
  706. #endif
  707.         WritePixelArray8 (&rp, rects->x, rects->y,
  708.                           rects->x + rects->width - 1,
  709.                           rects->y + rects->height - 1,
  710.                           vid.buffer, &temprp);
  711.       rects = rects->pnext;
  712.     }
  713.   }
  714.   if (do_fps)
  715.     video_do_fps (&rp, 0);
  716.   if (is_native_mode) {
  717.     if (ChangeScreenBuffer (video_screen, nextsbuffer)) {
  718.       if (nextsbuffer == sbuffer[0]) {
  719.         nextsbuffer = sbuffer[1];
  720. #ifndef __PPC__
  721.         nextc2p = c2p[1];
  722. #endif
  723.       } else if (nextsbuffer == sbuffer[1]) {
  724.         nextsbuffer = sbuffer[2];
  725. #ifndef __PPC__
  726.         nextc2p = c2p[2];
  727. #endif
  728.       } else {
  729.         nextsbuffer = sbuffer[0];
  730. #ifndef __PPC__
  731.         nextc2p = c2p[0];
  732. #endif
  733.       }
  734.       rp.BitMap = nextsbuffer->sb_BitMap;
  735.     }
  736.   }
  737. }
  738.  
  739. /**********************************************************************/
  740. /*
  741. ================
  742. D_BeginDirectRect
  743. ================
  744. */
  745. static struct BitMap *saved_bm = NULL;
  746.  
  747. void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height)
  748. {
  749. //  printf ("D_BeginDirectRect %d %d %08x %d %d\n", x, y, pbitmap, width, height);
  750.   if (video_window != NULL) {
  751.     saved_bm = rp.BitMap;
  752.     rp.BitMap = video_screen->ViewPort.RasInfo->BitMap;
  753.     if ((tmp_rp.BitMap = AllocBitMap (width, height, 8, 0,
  754.                                       rp.BitMap)) == NULL)
  755.       Sys_Error ("AllocBitMap failed");
  756.     ClipBlit (&rp, x, y, &tmp_rp, 0, 0, width, height, 0xc0);
  757.     if (GfxBase->LibNode.lib_Version >= 40)
  758.       WriteChunkyPixels (&rp, x, y, x+width-1, y+height-1,
  759.                          pbitmap, width);
  760.     else if (CyberGfxBase != NULL)
  761.       WritePixelArray (pbitmap, 0, 0, width, &rp, x, y, width, height,
  762.                        RECTFMT_LUT8);
  763.     //else
  764.     //  Sys_Error ("KS3.1 or cybergraphics.library required\n");
  765.   }
  766. }
  767.  
  768. /**********************************************************************/
  769. /*
  770. ================
  771. D_EndDirectRect
  772. ================
  773. */
  774. void D_EndDirectRect (int x, int y, int width, int height)
  775. {
  776. //  printf ("D_EndDirectRect %d %d %d %d\n", x, y, width, height);
  777.   if (video_window != NULL && tmp_rp.BitMap != NULL) {
  778.     ClipBlit (&tmp_rp, 0, 0, &rp, x, y, width, height, 0xc0);
  779.     FreeBitMap (tmp_rp.BitMap);
  780.     tmp_rp.BitMap = NULL;
  781.     rp.BitMap = saved_bm;
  782.     saved_bm = NULL;
  783.   }
  784. }
  785.  
  786. /**********************************************************************/
  787. extern void (*vid_menudrawfn)(void);
  788. extern void (*vid_menukeyfn)(int key);
  789.  
  790. /**********************************************************************/
  791. void Sys_SendKeyEvents(void)
  792. {
  793.   ULONG class;
  794.   UWORD code;
  795.   WORD mousex, mousey;
  796.   struct IntuiMessage *msg;
  797.   static int xlate[0x68] = {
  798.     '`', '1', '2', '3', '4', '5', '6', '7',
  799.     '8', '9', '0', '-', '=', '\\', 0, '0',
  800.     'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
  801.     'o', 'p', K_F11, K_F12, 0, '0', '2', '3',
  802.     'a', 's', 'd', 'f', 'g', 'h', 'j', 'k',
  803.     'l', ';', '\'', K_ENTER, 0, '4', '5', '6',
  804.     K_SHIFT, 'z', 'x', 'c', 'v', 'b', 'n', 'm',
  805.     ',', '.', '/', 0, '.', '7', '8', '9',
  806.     K_SPACE, K_BACKSPACE, K_TAB, K_ENTER, K_ENTER, K_ESCAPE, K_F11,
  807.     0, 0, 0, '-', 0, K_UPARROW, K_DOWNARROW, K_RIGHTARROW, K_LEFTARROW,
  808.     K_F1, K_F2, K_F3, K_F4, K_F5, K_F6, K_F7, K_F8,
  809.     K_F9, K_F10, '(', ')', '/', '*', '=', K_PAUSE,
  810.     K_SHIFT, K_SHIFT, 0, K_CTRL, K_ALT, K_ALT, 0, K_CTRL
  811.   };
  812.  
  813.   if (video_window != NULL) {
  814.     while ((msg = (struct IntuiMessage *)GetMsg (video_window->UserPort)) != NULL) {
  815.       class = msg->Class;
  816.       code = msg->Code;
  817.       mousex = msg->MouseX;
  818.       mousey = msg->MouseY;
  819.       ReplyMsg ((struct Message *)msg);
  820.       switch (class) {
  821.         case IDCMP_RAWKEY:
  822.           if ((code & 0x80) != 0) {
  823.             code &= ~0x80;
  824.             if (code < 0x68)
  825.               Key_Event (xlate[code], false);
  826.           } else {
  827.             if (code < 0x68)
  828.               Key_Event (xlate[code], true);
  829.           }
  830.           break;
  831.         case IDCMP_MOUSEBUTTONS:
  832.           switch (code) {
  833.             case IECODE_LBUTTON:
  834.               Key_Event (K_MOUSE1, true);
  835.               break;
  836.             case IECODE_LBUTTON + IECODE_UP_PREFIX:
  837.               Key_Event (K_MOUSE1, false);
  838.               break;
  839.             case IECODE_MBUTTON:
  840.               Key_Event (K_MOUSE2, true);
  841.               break;
  842.             case IECODE_MBUTTON + IECODE_UP_PREFIX:
  843.               Key_Event (K_MOUSE2, false);
  844.               break;
  845.             case IECODE_RBUTTON:
  846.               Key_Event (K_MOUSE3, true);
  847.               break;
  848.             case IECODE_RBUTTON + IECODE_UP_PREFIX:
  849.               Key_Event (K_MOUSE3, false);
  850.               break;
  851.             default:
  852.               break;
  853.           }
  854.           break;
  855.         case IDCMP_MOUSEMOVE:
  856.         case IDCMP_DELTAMOVE:
  857.           last_mouse[0] = mousex;
  858.           last_mouse[1] = mousey;
  859.           mouse_has_moved = true;
  860.           break;
  861.         default:
  862.           break;
  863.       }
  864.     }
  865.   }
  866. }
  867.  
  868. /**********************************************************************/
  869. #if 0
  870. char *Sys_ConsoleInput (void)
  871. {
  872.   printf ("Sys_ConsoleInput\n");
  873.   return 0;
  874. }
  875. #endif
  876.  
  877. /**********************************************************************/
  878.