home *** CD-ROM | disk | FTP | other *** search
/ MACD 4 / MACD4.iso / Emulatory / v2600 / source.lha / source / amiga_disp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-12  |  10.1 KB  |  464 lines

  1. /*****************************************************************************
  2. Author     : Matthew Stroup
  3. Description: Amiga graphics output for v2600 Atari 2600 emulator
  4. Version    : 2.0 Feb 5, 1997
  5. ******************************************************************************/
  6.  
  7. #include "config.h"
  8. #include "version.h"
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include "types.h"
  13. #include "vmachine.h"
  14. #include "address.h"
  15. #include "files.h"
  16. #include "colours.h"
  17. #include "keyboard.h"
  18. #include "options.h"
  19. #include "display.h"
  20. #include <exec/types.h>
  21. #include <exec/memory.h>
  22. #include <intuition/intuition.h>
  23. #include <graphics/gfxmacros.h>
  24. #include <graphics/display.h>
  25. #include <proto/exec.h>
  26. #include <proto/graphics.h>
  27. #include <proto/intuition.h>
  28. #include <hardware/custom.h>
  29. #include <hardware/cia.h>
  30.  
  31. /*****************************************************************************/
  32.  
  33. void __asm chunky2planar(register __a0 UBYTE *chunky, register __a1 PLANEPTR raster);
  34.  
  35. void __asm c2p8_init (    register __a0 UBYTE *chunky,        // pointer to chunky data
  36.                         register __a1 UBYTE *chunky_cmp,    // pointer to chunky comparison buffer
  37.                         register __a2 PLANEPTR *planes,        // pointer to planes
  38.                         register __d0 ULONG signals1,        // 1 << sigbit1
  39.                         register __d1 ULONG signals2,        // 1 << sigbit2
  40.                         register __d2 ULONG pixels,            // WIDTH * HEIGHT
  41.                         register __d3 ULONG offset,            // byte offset into plane
  42.                         register __d4 UBYTE *buff2,            // Chip buffer (size = width*height)
  43.                         register __d5 UBYTE *buff3,            // Chip buffer (size = width*height)
  44.                         register __a3 struct GfxBase *GfxBase);
  45.  
  46. void __asm c2p8_go(void);
  47.  
  48. long get_signals(void);
  49. void free_signals(void);
  50. long get_chunky_mem(void);
  51. void free_chunky_mem(void);
  52. void init_chunky(void);
  53. long get_window(void);
  54.  
  55. UBYTE *chunky_cmp=0;    // chunky data comparison buffer (preferably in fast ram)
  56. UBYTE *buff2=0;        // blitter buffer (chip ram)
  57. UBYTE *buff3=0;        // blitter buffer (chip ram)
  58.  
  59. long sigbit1 = -1;        // used by c2p8()
  60. long sigbit2 = -1;        // used by c2p8()
  61.  
  62. struct Screen *scr=0;
  63. struct Window *win=0;
  64. struct RastPort *rp=0, temprp;
  65. struct ViewPort *vp=0;
  66. struct IntuiMessage *message=0;
  67. struct GfxBase *GfxBase=0;
  68. struct IntuitionBase *IntuitionBase=0;
  69.  
  70. struct TagItem TagArray[] = {
  71.     // can add other tags here
  72.     TAG_DONE,0
  73. };
  74.  
  75. char perm[8] = {0, 1, 2, 3, 4, 5, 6, 7};    // bitplane order
  76.  
  77. PLANEPTR raster=0, temprast=0;        // 8 contiguous bitplanes
  78. struct BitMap bitmap_bm, tempbm;    // The full depth-8 bitmap
  79.  
  80. struct ExtNewScreen NewScreenStructure = {
  81.     0,0,
  82.     320,200,
  83.     7,
  84.     0,1,
  85.     NULL,
  86.     CUSTOMSCREEN+CUSTOMBITMAP+SCREENQUIET+NS_EXTENDED,
  87.     NULL,
  88.     NULL,
  89.     NULL,
  90.     &bitmap_bm,
  91.     (struct TagItem *)&TagArray
  92. };
  93.  
  94. struct NewScreen ns = {
  95.     0,0,                                // Left edge, Right edge
  96.     320,200,7,                        // Width, Height, Depth
  97.     1,2,                                // Detail pen, block pen
  98.     SPRITES,                            // Display modes
  99.     CUSTOMSCREEN,                        // Type
  100.     NULL,                            // Font
  101.     NULL,                            // Title
  102.     NULL,                            // Gadgets
  103.     NULL                                // Custom Bitmap
  104.     };
  105.  
  106. struct NewWindow NewWindowStructure1 = {
  107.     0,0,
  108.     320,200,
  109.     0,1,
  110.     NULL,
  111.     SIMPLE_REFRESH+BORDERLESS+NOCAREREFRESH,
  112.     NULL,
  113.     NULL,
  114.     NULL,
  115.     NULL,
  116.     NULL,
  117.     0,0,
  118.     0,0,
  119.     CUSTOMSCREEN
  120. };
  121.  
  122. /* Start of image data */
  123. UBYTE *vscreen=0;
  124.  
  125. /* The width and height of the image, including any magnification */
  126. int vwidth, vheight, theight;
  127.  
  128. /* The frame rate counter. Used by the -rr switch */
  129. int tv_counter = 0;
  130.  
  131. /* Optionally set by the X debugger. */
  132. int redraw_flag = 1;
  133.  
  134. static int bytesize;
  135.  
  136. long get_screen(void);
  137.  
  138. UBYTE colors[NUMCOLS];
  139.  
  140. extern int moudrv_x, moudrv_y, moudrv_but;
  141.  
  142.  
  143. #define CIAAPRA 0xBFE001
  144.  
  145. struct CIA *ciamou = (struct CIA *) CIAAPRA;
  146.  
  147. /*****************************************************************************/
  148.  
  149. /* Turns on the television. */
  150. /* returns: 1 for success, 0 for failure */
  151. int tv_on (int argc, char **argv)
  152. {
  153. int i;
  154.  
  155.     // Make sure necessary ROM libraries are open
  156.     IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",0);
  157.     if (IntuitionBase == NULL) return(0);    
  158.  
  159.     GfxBase=(struct GfxBase *) OpenLibrary("graphics.library",0);
  160.     if (GfxBase == NULL) return(0);
  161.  
  162.     if (Verbose) printf ("OK\n  Allocating screen buffer...");
  163.  
  164.     vscreen = (UBYTE *) AllocMem (64000, MEMF_PUBLIC|MEMF_CLEAR);
  165.  
  166.     if (!vscreen)
  167.     {
  168.         if (Verbose) printf ("Memory Allocation FAILED\n");
  169.         return (0);
  170.     }
  171.  
  172.     if (base_opts.video==1)
  173.     {
  174.         if ((win=OpenWindowTags(NULL,
  175.                             WA_Title, "Amiga v2600",
  176.                             WA_AutoAdjust,TRUE,
  177.                             WA_InnerWidth, 320, 
  178.                             WA_InnerHeight, 192,
  179.                             WA_DragBar, TRUE,
  180.                             WA_CloseGadget, TRUE,
  181.                             WA_DepthGadget,TRUE,
  182.                             WA_GimmeZeroZero, TRUE,
  183.                             WA_SmartRefresh, TRUE,
  184.                             WA_IDCMP,IDCMP_CLOSEWINDOW,
  185.                             TAG_DONE))==NULL) return(0);
  186.  
  187.         for (i=0; i<NUMCOLS; i++)
  188.         {
  189.             colors[i]=ObtainBestPen(win->WScreen->ViewPort.ColorMap,
  190.                         (colortable[i*2] & 0xff0000)<<8,
  191.                         (colortable[i*2] & 0x00ff00)<<16,
  192.                         (colortable[i*2] & 0x0000ff)<<24,
  193.                         OBP_Precision,PRECISION_EXACT,
  194.                         TAG_DONE);
  195.         }
  196.         rp=win->RPort;
  197.         InitBitMap(&tempbm, 8, 320, 200);
  198.         if ((temprast=(PLANEPTR)AllocRaster(320, 8*200))==NULL) return (0);
  199.         for(i=0; i<8; i++)
  200.         {
  201.             tempbm.Planes[i] = temprast + (perm[i] * RASSIZE (320, 200));
  202.         }
  203.         InitRastPort(&temprp);
  204.         temprp.BitMap=&tempbm;
  205.     }
  206.     else
  207.     {
  208.         if (get_screen()==0) return(0);
  209.         ShowTitle(scr, 0);
  210.         for (i=0; i<NUMCOLS; i++)
  211.         {
  212.             SetRGB32(&scr->ViewPort,i,
  213.                     (colortable[i*2] & 0xff0000)<<8,
  214.                     (colortable[i*2] & 0x00ff00)<<16,
  215.                     (colortable[i*2] & 0x0000ff)<<24);
  216.             colors[i]=i;
  217.         }
  218.         if (base_opts.video==2)
  219.         {
  220.             if(get_chunky_mem()==0) return(0);
  221.             if(get_signals())
  222.             {
  223.                 NewWindowStructure1.Screen = scr;
  224.                 if (get_window()==0) return(0);
  225.                 // initialize c2p converter
  226.                 c2p8_init (    vscreen,
  227.                             chunky_cmp,
  228.                             &rp->BitMap->Planes[0],
  229.                             1 << sigbit1,
  230.                             1 << sigbit2,
  231.                             64000,
  232.                             0,
  233.                             buff2,
  234.                             buff3,
  235.                             GfxBase);
  236.             }
  237.             else return(0);
  238.         }
  239.     }
  240.  
  241.     bytesize = 64000;
  242.  
  243.     /* Calculate the video width and height */
  244.     vwidth = tv_width * 2;
  245.     theight = tv_height + 8;
  246.     vheight = theight;
  247.  
  248.     /* Turn on the keyboard. Must be done after toplevel is created */
  249.     init_keyboard();
  250.  
  251.     if (Verbose) printf ("OK\n\b");
  252.     return (1);
  253. }
  254.  
  255. /*****************************************************************************/
  256.  
  257. /* Turn off the tv. Closes the X connection and frees the shared memory */
  258. void tv_off (void)
  259. {
  260.     if (Verbose) printf ("Switching off...\n");
  261.  
  262.     if (base_opts.video==2)
  263.     {
  264.         free_chunky_mem();
  265.         free_signals();
  266.     }
  267.  
  268.     if (base_opts.video!=0)
  269.     {
  270.         if (win) CloseWindow(win);
  271.     }
  272.  
  273.     if (base_opts.video==1)
  274.     {
  275.         if (temprast) FreeRaster (temprast, 320, 8*200);
  276.     }
  277.     else
  278.     {
  279.         if (scr) CloseScreen(scr);
  280.         if (raster) FreeRaster (raster, 320, 8 * 200);
  281.     }
  282.  
  283.     if (vscreen) FreeMem(vscreen, 64000);
  284.     if (GfxBase) CloseLibrary((struct Library *)GfxBase);
  285.     if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  286. }
  287.  
  288. /*****************************************************************************/
  289.  
  290. /* Displays the tv screen */
  291. void tv_display (void)
  292. {
  293.     /* Only display if the frame is a valid one. */
  294.     if (tv_counter % base_opts.rr == 0)
  295.     {
  296.         switch(base_opts.video)
  297.         {
  298.             case 0:
  299.                 WaitBOVP(&scr->ViewPort);
  300.                 chunky2planar(vscreen,raster);
  301.                 break;
  302.             case 1:
  303.                 WritePixelArray8(rp, 0, 0, 319, 191, vscreen, &temprp);
  304.                 if (message=(struct IntuiMessage *)GetMsg(win->UserPort))
  305.                 {
  306.                     if (message->Class==CLOSEWINDOW) exit(0);
  307.                 }
  308.                 break;
  309.             case 2:
  310.                 c2p8_go();
  311.         }
  312.     }
  313.     tv_counter++;
  314. }
  315.  
  316. /*****************************************************************************/
  317.  
  318. /* The Event code. */
  319. void tv_event (void)
  320. {
  321.     read_keyboard();
  322. }
  323.  
  324. /*****************************************************************************/
  325.  
  326. UBYTE tv_color (UBYTE b)
  327. {
  328.     return (UBYTE)(b >> 1);
  329. }
  330.  
  331. /*****************************************************************************/
  332.  
  333. long get_screen(void)
  334. {
  335.     long depth, ok = 0;
  336.  
  337.     InitBitMap(&bitmap_bm, 8, 320, 200);    // Full depth-8 bm
  338.  
  339.     // since c2p_020() needs 8 contiguous bitplanes, it is not
  340.     // possible to just use OpenScreen() or AllocBitmap() as they
  341.     // may give the bitplanes in a few chunks of memory (noncontiguous)
  342.  
  343.     if( raster = (PLANEPTR)AllocRaster (320, 8 * 200))
  344.     {
  345.         for(depth = 0; depth < 8; depth++)
  346.         {
  347.             bitmap_bm.Planes[depth] = raster + (perm[depth] * RASSIZE (320, 200));
  348.         }
  349.         
  350.         if(scr = OpenScreen( (struct NewScreen *) &NewScreenStructure))
  351.         {
  352.             SetRast(&scr->RastPort, 0);        // clear screen memory
  353.             WaitBlit();                    // wait until it's finished
  354.     
  355.             ok = 1;
  356.         }
  357.     }
  358.  
  359.     return(ok);
  360.  
  361. }
  362.  
  363. /*****************************************************************************/
  364.  
  365. void free_chunky_mem(void)
  366. {
  367.     if(buff3)
  368.         FreeVec(buff3);
  369.  
  370.     if(buff2)
  371.         FreeVec(buff2);
  372.  
  373.     if(chunky_cmp)
  374.         FreeVec(chunky_cmp);
  375. }
  376.  
  377. /*****************************************************************************/
  378.  
  379. void free_signals(void)
  380. {
  381.     if(sigbit1 != -1)
  382.     {
  383.         Wait (1 << sigbit1);    // wait for last c2p8 to finish pass 3
  384.         FreeSignal(sigbit1);
  385.         sigbit1 = -1;
  386.     }
  387.  
  388.     if(sigbit2 != -1)
  389.     {
  390.         Wait (1 << sigbit2);    // wait for last c2p8 to finish totally
  391.         FreeSignal(sigbit2);
  392.         sigbit2 = -1;
  393.     }
  394. }
  395.  
  396. /*****************************************************************************/
  397.  
  398. long get_chunky_mem(void)
  399. {
  400.     if((chunky_cmp = AllocVec(64000, MEMF_CLEAR+MEMF_ANY))==0) return (0);
  401.     if((buff2 = AllocVec(64000, MEMF_CLEAR+MEMF_CHIP))==0) return (0);
  402.     if((buff3 = AllocVec(64000, MEMF_CLEAR+MEMF_CHIP))==0) return (0);
  403.     return(1);
  404. }
  405.  
  406. /*****************************************************************************/
  407.  
  408. long get_signals(void)
  409. {
  410.     long ok = 0;
  411.  
  412.     if(-1 != (sigbit1 = AllocSignal(-1)))
  413.     {
  414.         SetSignal (1 << sigbit1, 1 << sigbit1); // Initial state is "finished"
  415.  
  416.         if(-1 != (sigbit2 = AllocSignal(-1)))
  417.         {
  418.             SetSignal (1 << sigbit2, 1 << sigbit2); // Initial state is "finished"
  419.  
  420.             ok = 1;
  421.         }
  422.     }
  423.  
  424.     return(ok);
  425.  
  426. }
  427.  
  428. /*****************************************************************************/
  429.  
  430. long get_window(void)
  431. {
  432.     long ok = 0;
  433.  
  434.     if (win = OpenWindow(&NewWindowStructure1))
  435.     {
  436.         rp = win->RPort;
  437.         ok = 1;
  438.     }
  439.  
  440.     return(ok);
  441.  
  442. }
  443.  
  444. /*****************************************************************************/
  445.  
  446. void moudrv_read(void)
  447. {
  448.     moudrv_x=win->MouseX;
  449.     moudrv_y=win->MouseY;
  450.     moudrv_but=!(ciamou->ciapra & 0x0040);
  451. }
  452.  
  453. void moudrv_init(void)
  454. {
  455. }
  456.  
  457. void moudrv_update(void)
  458. {
  459. }
  460.  
  461. void moudrv_close(void)
  462. {
  463. }
  464.