home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / games / gi / tapedev.c < prev    next >
C/C++ Source or Header  |  1993-11-18  |  9KB  |  358 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*   Main-Module   : Tape-Interface mit Game-Support & Self-Config          */
  4. /*                                                                          */
  5. /*   Version       : V1.00                                                  */
  6. /*                                                                          */
  7. /*   Date          :  3.1.93                                                */
  8. /*                                                                          */
  9. /*   Written       : RF                                                     */
  10. /*                                                                          */
  11. /*     Revision History :
  12.  
  13.         04.11.93    RF    Record und Play implementiert
  14.         07.11.93    RF    event-time statt letztem Zustand
  15.         18.11.93    RF    StopOnOverPlay eingebaut, BugFix bei decode von diagonal
  16.                                                                             */
  17. /*--------------------------------------------------------------------------*/
  18. #define INCL_PM
  19. #include <os2.h>
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <mem.h>
  24. #include <string.h>
  25. #include <gi.h>
  26. #include <spin.hpp>
  27.  
  28. #pragma hdrstop
  29.  
  30. #include <checkbox.hpp>
  31.  
  32. typedef struct
  33.     {
  34.     BOOL    init;
  35.  
  36.     // Instance Data
  37.     long    port;            // Port to monitor
  38.     } TAPECONFIG, *TAPECONFIGP;
  39.  
  40.  
  41. /*--------------------------------------------------------------------------*/
  42. /*---- Globals ----*/
  43. long                port;
  44. HFILE               file;
  45. unsigned _export    modeflag=0;        // 0=default 1=rec 2=play
  46. unsigned            mymode=0;        // Intern um festzustellen, wenn modus ändert
  47. unsigned _export    stoponover=0;
  48. long _export        event=0;
  49. long                   myevent=0;
  50. char   _export        filename[256] = { 0x00 };
  51. BOOL   _export        cfgpresent=FALSE;
  52. HWND   _export        globhwnd;
  53. long   _export        count=0;        // Tape-Counter
  54.  
  55. /*---- Globals for Config-Part ----*/
  56. HMODULE     module;
  57. HAB         hab;
  58. SPINBUTTON    sp;
  59.  
  60. /*---- Prototypings ----*/
  61. unsigned    FileState(unsigned);
  62. unsigned    Record     (PLAYERINFOP);
  63. unsigned    Play     (PLAYERINFOP);
  64.  
  65. /*---- Extern ----*/
  66. extern "C" {
  67. unsigned GIGetThreshold (unsigned fiidx);    // Nur für interne Zwecke !!
  68. }
  69.  
  70. /*--------------------------------------------------------------------------*/
  71. extern "C" {
  72. ULONG _dllmain (ULONG termflag, HMODULE modhandle)
  73.     {
  74.     if (!termflag)  // Init...
  75.         module = modhandle;
  76.  
  77.     return (TRUE);
  78.     }
  79. }
  80. /*--------------------------------------------------------------------------*/
  81. extern "C" {
  82. unsigned _export GetDataSize (void)
  83.     {
  84.     return (sizeof (TAPECONFIG));    // Oh, what a hack!
  85.     }
  86. }
  87. /*--------------------------------------------------------------------------*/
  88. extern "C" {
  89. unsigned _export  InitializeDLL (char __far16 *data)
  90.     {
  91.     ULONG           action;
  92.     TAPECONFIGP        tc;
  93.  
  94.     tc = (TAPECONFIGP)data;
  95.  
  96.     if (!tc->init)           // Create New Config
  97.         {
  98.         tc->init = TRUE;
  99.         tc->port = -1;        // Port muss einmal definiert werden...
  100.         }
  101.  
  102.     port = tc->port;
  103.  
  104.     return (NOERR);
  105.     }
  106. }
  107. /*--------------------------------------------------------------------------*/
  108. extern "C" {
  109. unsigned _export  Name (char __far16 *target)
  110.     {
  111.     strcpy (target, "Tape Recorder");
  112.     return (0);
  113.     }
  114. }
  115. /*--------------------------------------------------------------------------*/
  116. extern "C" {
  117. MRESULT    EXPENTRY dlgproc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  118.     {
  119.     int         i;
  120.     SWP         swp;
  121.  
  122.     switch (msg)
  123.         {
  124.         case WM_INITDLG:
  125.             hab=WinInitialize (0);
  126.             sp.Set (WinWindowFromID (hwnd, 101));
  127.             sp.SetLimits (100, 1);
  128.             sp.SetValue (port+1);
  129.             return (FALSE);
  130.         case WM_COMMAND:
  131.             switch (SHORT1FROMMP (mp1))
  132.                 {
  133.                 case DID_OK:
  134.                     sp.QueryValue (&port);
  135.                     port--;                        // Zero-Based !
  136.                     if (GIGetThreshold ((unsigned)port)==0)
  137.                         WinMessageBox (HWND_DESKTOP, hwnd, "Illegal Port.",
  138.                             "Tape: Fatal Error", 0, MB_OK | MB_ICONEXCLAMATION |
  139.                             MB_APPLMODAL);
  140.                     else
  141.                         WinDismissDlg (hwnd, TRUE);
  142.                     break;
  143.                 case DID_CANCEL:
  144.                     WinDismissDlg (hwnd, FALSE);
  145.                     break;
  146.                 }
  147.             break;
  148.         default:
  149.             return (WinDefDlgProc (hwnd, msg, mp1, mp2));
  150.         }
  151.     return (0L);
  152.     }
  153. }
  154. /*--------------------------------------------------------------------------*/
  155. extern "C" {
  156. unsigned _export  ConfigDLL (char __far16 *dd)
  157.     {
  158.     TAPECONFIGP    tc;
  159.  
  160.     tc = (TAPECONFIGP)dd;
  161.  
  162.     WinDlgBox (HWND_DESKTOP, HWND_DESKTOP, dlgproc, module, 100, NULL);
  163.  
  164.     tc->port = port;
  165.  
  166.     return (0);
  167.     }
  168. }
  169. /*--------------------------------------------------------------------------*/
  170. #pragma argsused
  171. extern "C" {
  172. unsigned _export  Threshold (char __far16 *dd)
  173.     {
  174.     return (GIGetThreshold ((unsigned)port));
  175.     }
  176. }
  177. /*--------------------------------------------------------------------------*/
  178. #pragma argsused
  179. extern "C" {
  180. unsigned _export  Direction (char __far16 *dd, char __far16 *de)
  181.     {
  182.     TAPECONFIGP        tc;
  183.     PLAYERINFOP     pi;
  184.     unsigned        ret;
  185.     ULONG            action;
  186.     unsigned        player;
  187.  
  188.     pi = (PLAYERINFOP)de;
  189.  
  190.     // Hat inzwischen der File-Mode geändert ?
  191.     if (myevent != event)
  192.         {
  193.         myevent = event;
  194.         if (mymode)            // das file war offen
  195.             DosClose (file);
  196.         if (modeflag==1)
  197.             {
  198.             if (count)    // write append
  199.                 {
  200.                 DosOpen (filename, &file, &action, 0, 0,
  201.                     OPEN_ACTION_OPEN_IF_EXISTS,
  202.                     OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_WRITEONLY,
  203.                     0);
  204.                 DosSetFilePtr (file, 0, 2, &action);
  205.                 }
  206.             else    // write new
  207.                 DosOpen (filename, &file, &action, 0, 0,
  208.                     OPEN_ACTION_REPLACE_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW,
  209.                     OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_WRITEONLY,
  210.                     0);
  211.             }
  212.         else if (modeflag==2)    // read
  213.             DosOpen (filename, &file, &action, 0, 0,
  214.                 OPEN_ACTION_OPEN_IF_EXISTS,
  215.                 OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_READONLY,
  216.                 0);
  217.         if (!file)
  218.             {
  219.             mymode = modeflag = 0;        // Fehler -> Stop
  220.             if (cfgpresent)
  221.                 WinPostMsg (globhwnd, WM_USER, 1, 0);
  222.             }
  223.         else
  224.             mymode = modeflag;
  225.         }
  226.  
  227.     if (modeflag == 2)        // Play
  228.         {
  229.         if (stoponover)
  230.             {
  231.             // Richtung vom Original-Device holen
  232.             player = pi->player;
  233.             pi->player = port;
  234.             GIGetDirection (pi);
  235.             pi->player = player;
  236.             if (pi->direction == DIRNONE)
  237.                 ret = Play (pi);
  238.             else
  239.                 {
  240.                 ret = 0;
  241.                 WinPostMsg (globhwnd, WM_USER, 1, 0);
  242.                 }
  243.             }
  244.         else
  245.             ret = Play (pi);
  246.         if (ret && cfgpresent)
  247.             WinPostMsg (globhwnd, WM_USER, 1, 0);
  248.         }
  249.  
  250.     if (modeflag != 2 || ret)
  251.         {
  252.         // Richtung vom Original-Device holen
  253.         player = pi->player;
  254.         pi->player = port;
  255.         GIGetDirection (pi);
  256.         pi->player = player;
  257.  
  258.         if (modeflag == 1)    // Record
  259.             {
  260.             ret = Record (pi);
  261.             if (ret && cfgpresent)
  262.                 WinPostMsg (globhwnd, WM_USER, 1, 0);
  263.             }
  264.         }
  265.  
  266.     return (0);
  267.     }
  268. }
  269. /*--------------------------------------------------------------------------*/
  270. unsigned Record (PLAYERINFOP pl)
  271.     {
  272.     char    v1, v2, d;
  273.     ULONG    ret;
  274.  
  275.     // Richtung & Buttons aufbereiten
  276.     d = (pl->direction+1)+5*(pl->diagonal+1)+25*(pl->buttons);
  277.  
  278.     // Analog-Daten ?
  279.     if (pl->analog)
  280.         {
  281.         if (pl->direction != DIRNONE)
  282.             {
  283.             v1 = - pl->dir[pl->direction];
  284.             if (DosWrite (file, &v1, sizeof (char), &ret) || ret != sizeof (char))
  285.                 return (1);
  286.             }
  287.         if (pl->diagonal != DIRNONE)
  288.             {
  289.             v2 = - pl->dir[pl->diagonal];
  290.             if (DosWrite (file, &v2, sizeof (char), &ret) || ret != sizeof (char))
  291.                 return (1);
  292.             }
  293.         }
  294.  
  295.     // Richtung & Buttons
  296.     if (DosWrite (file, &d, sizeof (char), &ret) || ret != sizeof (char))
  297.         return (1);
  298.  
  299.     count++;
  300.     if (cfgpresent)
  301.         WinPostMsg (globhwnd, WM_USER, 0, 0);
  302.  
  303.     return (0);
  304.     }
  305. /*--------------------------------------------------------------------------*/
  306. unsigned Play (PLAYERINFOP pl)
  307.     {
  308.     char    v1=0, v2=0, d;
  309.     ULONG    ret;
  310.  
  311.     // Daten lesen
  312.     if (DosRead (file, &d, sizeof (char), &ret) || ret != sizeof (char))
  313.         return (1);
  314.  
  315.     if (d < 0)        // Analog-Daten
  316.         {
  317.         v1 = -d;
  318.         if (DosRead (file, &d, sizeof (char), &ret) || ret != sizeof (char))
  319.             return (1);
  320.         if (d < 0)
  321.             {
  322.             v2 = -d;
  323.             if (DosRead (file, &d, sizeof (char), &ret) || ret != sizeof (char)
  324.                      ||d < 0)
  325.                 return (1);
  326.             }
  327.         }
  328.  
  329.     // Daten aufbereiten
  330.     pl->direction = (d%5)-1;
  331.     pl->diagonal  = ((d/5)%5)-1;
  332.     pl->buttons   = (d/25);
  333.  
  334.     pl->dir[0] = pl->dir[1] = pl->dir[2] = pl->dir[3] = 0;
  335.     pl->dir[4] = pl->buttons & 0x01;
  336.     pl->dir[5] = pl->buttons & 0x02;
  337.  
  338.     /*------------------------------------------------------*/
  339.     /* Damit bei der Umrechnung der dir[] in direction und  */
  340.     /* diagonal in GI direction stärker ist als diagonal,   */
  341.     /* muss threshold+1 für direction gegeben werden!        */
  342.     if (pl->direction != DIRNONE)
  343.         pl->dir[pl->direction] = pl->analog ? v1 : GIGetThreshold ((unsigned)port)+1;
  344.  
  345.     if (pl->diagonal & 0x04)
  346.         pl->diagonal = DIRNONE;
  347.     else
  348.         pl->dir[pl->diagonal]  = pl->analog ? v2 : GIGetThreshold ((unsigned)port);
  349.  
  350.     count++;
  351.     if (cfgpresent)
  352.         WinPostMsg (globhwnd, WM_USER, 0, 0);
  353.  
  354.     return (0);
  355.     }
  356. /*--------------------------------------------------------------------------*/
  357.  
  358.