home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Emulation / AmigaVGB / Amiga.c next >
C/C++ Source or Header  |  1996-09-23  |  11KB  |  421 lines

  1. /** VGB: portable GameBoy emulator ***************************/
  2. /**                                                         **/
  3. /**                           Amiga.c                       **/
  4. /**                                                         **/
  5. /** Amiga-specific graphics/joystick routines  drivers.     **/
  6. /**                                                         **/
  7. /** Copyright (C) Lars Malmborg 1996                        **/
  8. /** based on a version by Michael Boese & Matthias Bethke   **/
  9. /** and the Unix/X version.                                 **/
  10. /**                                                         **/
  11. /** Copyright (C) Marat Fayzullin 1994,1995,1996            **/
  12. /**               Elan Feingold   1995                      **/
  13. /**     You are not allowed to distribute this software     **/
  14. /**     commercially. Please, notify me, if you make any    **/
  15. /**     changes to this file.                               **/
  16. /*************************************************************/
  17.  
  18. #define REVISION "rev. 2"
  19. #define USE_XPAL  /* We are using XPal[] to determine colors */
  20.  
  21. /* Amiga includes */
  22. #include <proto/exec.h>
  23. #include <proto/dos.h>
  24. #include <proto/intuition.h>
  25. #include <proto/graphics.h>
  26. #include <proto/asl.h>
  27. #include <dos/rdargs.h>
  28. #include <exec/memory.h>
  29.  
  30. #include <ctype.h>
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <signal.h>
  35.  
  36. #ifdef CYBER
  37. #include <proto/cybergraphics.h>
  38. #include <cybergraphics/cybergraphics.h>
  39. #endif
  40.  
  41. void __inline AllocatePens(void);
  42.  
  43. #include "GB.h"
  44. #include "AmigaRawkeys.h"
  45.  
  46.  
  47. /** Various variables and short functions ********************/
  48. #define WIDTH_OFFS 8
  49. #define WIDTH  (160+2*WIDTH_OFFS)
  50. #define HEIGHT 144
  51.  
  52. char *Title = "Virtual GameBoy 0.7";
  53.  
  54. char *AmigaVersion="$VER: Virtual GameBoy Amiga 0.7 "REVISION" "__AMIGADATE__;
  55.  
  56. int  ExitFlag = 0;
  57.  
  58. byte *XBuf=NULL,*ZBuf=NULL;
  59. LONG XPal[12]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
  60.  
  61. struct Screen *scr=NULL;
  62. struct Window *win=NULL;
  63. struct RastPort *rp=NULL;
  64.  
  65. char ReqText[]= "Virtual Gameboy V0.7 by\n\
  66. Marat Fayzullin <fms@freeflight.com>\n\
  67. Amiga version "REVISION" "__AMIGADATE__" by\n\
  68. Lars Malmborg <glue@df.lth.se>\n\n\
  69. In-game keys:\n\
  70. Left Alt    or '+' on key pad   - 'A'\n\
  71. Left Shift  or '6' on key pad   - 'B'\n\
  72. Right Shift or '4' on key pad   - 'Select'\n\
  73. Return      or '5' on key pad   - 'Start'\n\
  74. Cursorkeys   - Joypad\n\n\
  75. ESC          - Quit emulation\n"
  76. #ifdef DEBUG
  77. "\
  78. F1           - Go into built-in debugger\n\
  79. F2           - Show LCD controller registers\n"
  80. F3           - Show sprite registers\n"
  81. #endif
  82. ; //Gremlins!
  83.  
  84. struct EasyStruct HelpReq =
  85. {
  86.     sizeof(struct EasyStruct),
  87.     0,
  88.     "VGB Amiga Help",
  89.     ReqText,
  90.     "OK"
  91. };
  92.  
  93. #ifndef CYBER
  94. struct RastPort temprp;
  95. /*
  96. struct BitMap tempbm;
  97. char tempp[WIDTH*8];
  98. */
  99. #endif
  100. BOOL ScaleUp;
  101. STRPTR PubScreen;
  102.  
  103. int InitMachine(void)
  104. {
  105.     int scale;
  106.     if (ScaleUp)
  107.         scale=2;
  108.     else
  109.         scale=1;
  110.  
  111.     if (scr = LockPubScreen(PubScreen))
  112.     {
  113.         if(win = OpenWindowTags(NULL,
  114.                     WA_Left,(scr->Width - scale*(WIDTH-2*WIDTH_OFFS))/2,
  115.                     WA_Top,(scr->Height - scale*HEIGHT)/2,
  116.                     WA_InnerWidth,scale*(WIDTH-2*WIDTH_OFFS),
  117.                     WA_InnerHeight,scale*HEIGHT,
  118.                     WA_Title,Title,
  119.                     WA_CloseGadget,TRUE,
  120.                     WA_DepthGadget,TRUE,
  121.                     WA_DragBar,TRUE,
  122.                     WA_SizeGadget,FALSE,
  123.                     WA_RMBTrap,TRUE,
  124.                     WA_Activate,TRUE,
  125.                     WA_IDCMP,IDCMP_RAWKEY|IDCMP_CLOSEWINDOW,
  126.                     WA_PubScreenName,PubScreen,
  127.                     TAG_END
  128.             ))
  129.         {
  130.             UnlockPubScreen(PubScreen,scr);
  131.             rp = win->RPort;
  132.             AllocatePens();
  133.             if(!(XBuf=AllocVec(sizeof(byte)*HEIGHT*WIDTH,MEMF_ANY))) return(0);
  134.             if(!(ZBuf=AllocVec(sizeof(byte)*2*WIDTH*HEIGHT/8,MEMF_ANY))) return(0);
  135.  
  136. #ifndef CYBER
  137.             // init temprp
  138.             CopyMem(rp,&temprp,sizeof(struct RastPort));
  139.             temprp.Layer=NULL;
  140.             if (!(temprp.BitMap=AllocBitMap(scale*(WIDTH-2*WIDTH_OFFS),1,rp->BitMap->Depth,0,NULL)))
  141.             {
  142.                 fprintf(stderr,"Error allocating temporary rastport.\n");
  143.                 return(0);
  144.             }
  145. #endif
  146.         }
  147.         else
  148.         {
  149.             fprintf(stderr,"Can't open window.\n");
  150.             return(0);
  151.         }
  152.     }
  153.     else
  154.     {
  155.         fprintf(stderr,"Screen not found.\n");
  156.         return(0);
  157.     }
  158.     return(1);
  159. }
  160.  
  161. /** TrashMachine *********************************************/
  162. /** Deallocate all resources taken by InitMachine().        **/
  163. /*************************************************************/
  164. void TrashMachine(void)
  165. {
  166.     int i;
  167. #ifndef CYBER
  168.     // release temprp
  169.     if (temprp.BitMap)
  170.         FreeBitMap(temprp.BitMap);
  171. #endif
  172.  
  173.     if (ZBuf)
  174.         FreeVec(ZBuf);
  175.     if (XBuf)
  176.         FreeVec(XBuf);
  177.     if (win)
  178.         CloseWindow(win);
  179.     for(i=0; i<12; i++)
  180.         if (XPal[i]!=-1)
  181.             ReleasePen(scr->ViewPort.ColorMap,XPal[i]);
  182. }
  183.  
  184.  
  185. /** PutImage *************************************************/
  186. /** Put an image on the screen.                             **/
  187. /*************************************************************/
  188. void PutImage(void)
  189. {
  190. #ifdef CYBER
  191.     // Render with cybergraphics.library
  192.     int scale;
  193.     if (ScaleUp)
  194.         scale=2;
  195.     else
  196.         scale=1;
  197.  
  198.     WritePixelArray(XBuf,WIDTH_OFFS,0,scale*WIDTH,rp,win->BorderLeft,win->BorderTop,scale*(WIDTH-2*WIDTH_OFFS),HEIGHT,RECTFMT_LUT8);
  199. #else
  200.     // Render with graphics.library
  201.     if (ScaleUp)
  202.     {
  203.         register int i;
  204.         for(i=0;i<144;i++)
  205.         {
  206.             UBYTE drawarray[2*(WIDTH-2*WIDTH_OFFS)];
  207.             register int n;
  208.             for (n=0;n<(WIDTH-2*WIDTH_OFFS);n++)
  209.             {
  210.                 drawarray[n*2]=(UBYTE)(XBuf[(i*WIDTH)+n+WIDTH_OFFS]);
  211.                 drawarray[n*2+1]=drawarray[n*2];
  212.             }
  213.             WritePixelLine8(rp,win->BorderLeft,win->BorderTop+i*2,2*(WIDTH-2*WIDTH_OFFS),drawarray,&temprp);
  214.             WritePixelLine8(rp,win->BorderLeft,win->BorderTop+i*2+1,2*(WIDTH-2*WIDTH_OFFS),drawarray,&temprp);
  215.         }
  216.     }
  217.     else
  218.     {
  219.         register int i;
  220.         for(i=0;i<144;i++)
  221.         {
  222.             WritePixelLine8(rp,win->BorderLeft,win->BorderTop+i,WIDTH-2*WIDTH_OFFS,(UBYTE*)(&XBuf[(i*WIDTH)+WIDTH_OFFS]),&temprp);
  223.         }
  224.     }
  225. }
  226.  
  227. /** Joystick *************************************************/
  228. /** Return the current joystick state.                      **/
  229. /*************************************************************/
  230. byte Joystick(void)
  231. {
  232. struct IntuiMessage *imsg;
  233. ULONG imsg_Class;
  234. UWORD Code;
  235. #ifdef DEBUG
  236. int J;
  237. #endif
  238. static byte JoyState=0xff;
  239.  
  240.         if(imsg = (struct IntuiMessage*)GetMsg(win->UserPort))
  241.         {
  242.             imsg_Class = imsg->Class;
  243.             Code  = imsg->Code;
  244.             ReplyMsg((struct Message*)imsg);
  245.             switch(imsg_Class)
  246.             {
  247.                 case IDCMP_CLOSEWINDOW:
  248.                     ExitFlag = 1;
  249.                     break;
  250.                 case IDCMP_RAWKEY:
  251.                     if(Code & 0x80)
  252.                     {
  253.                         switch(Code & 0x7f)
  254.                         {
  255. #ifdef DEBUG
  256.                             case KEY_F1:
  257.                                 Trace=!Trace;
  258.                                 break;
  259.                             case KEY_F2:
  260.                                 puts("\n*** REGISTERS: ***");        //F2 up
  261.                                 for(J=0xFF40;J<0xFF50;J++)
  262.                                     printf("(%Xh) = %Xh\n",J,RAM[J]);
  263.                                 printf("ISWITCH = %Xh\n",ISWITCH);
  264.                                 break;
  265.                     case KEY_F3:
  266.                                 puts("\n*** SPRITES: ***");
  267.                                 for(J=0xFE9C;J<0xFE9C+4*40;J+=4)
  268.                                 printf("SPRITE %d: %d,%d   Pat %d   Attr %d\n",(J-0xFE9C)/4,RAM[J+1],RAM[J],RAM[J+2],RAM[J+3]);
  269.                                 break;
  270. #endif
  271.                             case KEY_HELP:
  272.                                 EasyRequestArgs(win,&HelpReq,NULL,NULL);
  273.                                 break;
  274.                             case KEY_RETURN:    //start
  275.                             case KEY_P5:
  276.                                 JoyState|=0x80;
  277.                                 break;
  278.                             case KEY_RSHIFT:    //select
  279.                             case KEY_P4:
  280.                                 JoyState|=0x40;
  281.                                 break;
  282.                             case KEY_LSHIFT:    //B
  283.                             case KEY_P6:
  284.                                 JoyState|=0x20;
  285.                                 break;
  286.                             case KEY_LALT:        //A
  287.                             case KEY_PPLUS:
  288.                                 JoyState|=0x10;
  289.                                 break;
  290.                             case KEY_CDOWN:        //Down
  291.                                 JoyState|=0x08;
  292.                                 break;
  293.                             case KEY_CUP:            //Up
  294.                                 JoyState|=0x04;
  295.                                 break;
  296.                             case KEY_CLEFT:        //Left
  297.                                 JoyState|=0x02;
  298.                                 break;
  299.                             case KEY_CRIGHT:    //Right
  300.                                 JoyState|=0x01;
  301.                                 break;
  302.                         }
  303.                     }
  304.                     else
  305.                     {
  306.                         switch(Code)
  307.                         {
  308.                             case KEY_ESC:
  309.                                 ExitFlag = 1;
  310.                                 break;
  311.                             case KEY_RETURN:
  312.                             case KEY_P5:
  313.                                 JoyState&=0x7F;
  314.                                 break;
  315.                             case KEY_RSHIFT:
  316.                             case KEY_P4:
  317.                                 JoyState&=0xBF;
  318.                                 break;
  319.                             case KEY_LSHIFT:
  320.                             case KEY_P6:
  321.                                 JoyState&=0xDF;
  322.                                 break;
  323.                             case KEY_LALT:
  324.                             case KEY_PPLUS:
  325.                                 JoyState&=0xEF;
  326.                                 break;
  327.                             case KEY_CDOWN:
  328.                                 JoyState&=0xF7;
  329.                                 break;
  330.                             case KEY_CUP:
  331.                                 JoyState&=0xFB;
  332.                                 break;
  333.                             case KEY_CLEFT:
  334.                                 JoyState&=0xFD;
  335.                                 break;
  336.                             case KEY_CRIGHT:
  337.                                 JoyState&=0xFE;
  338.                                 break;
  339.                         }
  340.                     }
  341.                     break;
  342.             }
  343.         }
  344.  
  345.   if(ExitFlag)
  346.   { TrashGB();TrashMachine();exit(0); }
  347.  
  348.   return(JoyState);
  349. }
  350.  
  351. struct
  352. {
  353.     LONG r,g,b;
  354. } GB_Colors[12]={
  355.                     {0xff000000,0xff000000,0xff000000},{0x98000000,0x98000000,0x98000000},
  356.                     {0x58000000,0x58000000,0x58000000},{0x00000000,0x00000000,0x00000000},
  357.  
  358.                     {0xff000000,0xff000000,0xff000000},{0x98000000,0x98000000,0x98000000},
  359.                     {0x58000000,0x58000000,0x58000000},{0x00000000,0x00000000,0x00000000},
  360.  
  361.                     {0xff000000,0xff000000,0xff000000},{0x98000000,0x98000000,0x98000000},
  362.                     {0x58000000,0x58000000,0x58000000},{0x00000000,0x00000000,0x00000000}};
  363.  
  364. void SetColors(int mode, char* color)
  365. {
  366.     long tcol[4];
  367.     int i=0;
  368.     while (!isdigit(color[i])) i++;
  369.     sscanf(color,"%lx,%lx,%lx,%lx",&tcol[0],&tcol[1],&tcol[2],&tcol[3]);
  370.  
  371.     GB_Colors[mode+0].r=(tcol[0]&0x00ff0000)<<8;
  372.     GB_Colors[mode+0].g=(tcol[0]&0x0000ff00)<<16;
  373.     GB_Colors[mode+0].b=(tcol[0]&0x000000ff)<<24;
  374.  
  375.     GB_Colors[mode+1].r=(tcol[1]&0x00ff0000)<<8;
  376.     GB_Colors[mode+1].g=(tcol[1]&0x0000ff00)<<16;
  377.     GB_Colors[mode+1].b=(tcol[1]&0x000000ff)<<24;
  378.  
  379.     GB_Colors[mode+2].r=(tcol[2]&0x00ff0000)<<8;
  380.     GB_Colors[mode+2].g=(tcol[2]&0x0000ff00)<<16;
  381.     GB_Colors[mode+2].b=(tcol[2]&0x000000ff)<<24;
  382.  
  383.     GB_Colors[mode+3].r=(tcol[3]&0x00ff0000)<<8;
  384.     GB_Colors[mode+3].g=(tcol[3]&0x0000ff00)<<16;
  385.     GB_Colors[mode+3].b=(tcol[3]&0x000000ff)<<24;
  386. }
  387.  
  388. void AllocatePens(void)
  389. {
  390.     int i;
  391.     for(i=0; i<12; i++)
  392.     {
  393.         XPal[i] = ObtainBestPenA(scr->ViewPort.ColorMap,GB_Colors[i].r,GB_Colors[i].g,GB_Colors[i].b,NULL);
  394.     }
  395. }
  396.  
  397.  
  398. /*** SIOSend ****************************************************/
  399. /*** Send a byte onto the serial line.                        ***/
  400. /****************************************************************/
  401. byte SIOSend(register byte V) { return(0); }
  402.  
  403.  
  404. /*** SIOReceive *************************************************/
  405. /*** Receive a byte from the serial line. Returns 1 on        ***/
  406. /*** success, 0 otherwise.                                    ***/
  407. /****************************************************************/
  408. byte SIOReceive(register byte *V) { return(0); }
  409.  
  410.  
  411. /****************************************************************/
  412. /*** Write value into sound chip register (Reg #0 at FF10h).  ***/
  413. /****************************************************************/
  414. void Sound(byte R,byte V) { return; }
  415.  
  416.  
  417. /** Common.h ****************************************************/
  418. /** Parts of the drivers common for Unix/X and MSDOS.          **/
  419. /****************************************************************/
  420. #include "Common.h"
  421.