home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 19 / CD_ASCQ_19_010295.iso / dos / prg / midas / examples / scrdemo.c < prev   
C/C++ Source or Header  |  1994-08-06  |  6KB  |  187 lines

  1. /*      SCRDEMO.C
  2.  *
  3.  * Demo about using Timer screen synchronization
  4.  *
  5.  * Copyright 1994 Petteri Kangaslampi and Jarno Paananen
  6.  *
  7.  * This file is part of the MIDAS Sound System, and may only be
  8.  * used, modified and distributed under the terms of the MIDAS
  9.  * Sound System license, LICENSE.TXT. By continuing to use,
  10.  * modify or distribute this file you indicate that you have
  11.  * read the license and understand and accept it fully.
  12. */
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <conio.h>
  17. #include <process.h>
  18. #include "midas.h"
  19.  
  20.  
  21. signed char     horizPan;               /* Horizontal Pixel Panning register
  22.                                            value */
  23. ushort          startAddr;              /* screen start address */
  24. ushort          scrSync;                /* screen synchronization value */
  25. int             panDir;                 /* panning direction - 0 = left,
  26.                                            1 = right */
  27.  
  28.  
  29.  
  30. /****************************************************************************\
  31. *
  32. * Function:     void preVR(void)
  33. *
  34. * Description:  Function that is called before Vertical Retrace. Sets the
  35. *               new screen start address
  36. *
  37. \****************************************************************************/
  38.  
  39. void preVR(void)
  40. {
  41. asm {
  42.         mov     bx,startAddr            /* bx = screen start address */
  43.  
  44.         mov     dx,03D4h                /* CRTC controller */
  45.         mov     al,0Ch                  /* Start Address High register */
  46.         mov     ah,bh                   /* screen start address high byte */
  47.         out     dx,ax                   /* set register value */
  48.  
  49.         mov     al,0Dh                  /* Start Address Low register */
  50.         mov     ah,bl                   /* screen start address low byte */
  51.         out     dx,ax                   /* set register value */
  52. }
  53. }
  54.  
  55.  
  56.  
  57. /****************************************************************************\
  58. *
  59. * Function:     void immVR(void)
  60. *
  61. * Description:  Function that is called immediately when Vertical Retrace
  62. *               starts. Sets the new Horizontal Pixel Panning value
  63. *
  64. \****************************************************************************/
  65.  
  66. void immVR(void)
  67. {
  68. asm {   mov     dx,03DAh                /* read Input Status #1 register to */
  69.         in      al,dx                   /* reset the Attribute Controller */
  70.                                         /* flip-flop */
  71.         mov     dx,03C0h                /* attribute controller */
  72.         mov     al,13h + 20h            /* Horizontal Pixel Panning register,
  73.                                            enable VGA palette */
  74.         out     dx,al                   /* select register */
  75.         mov     al,horizPan             /* Horizontal Pixel Panning value */
  76.         out     dx,al                   /* write panning value */
  77. }
  78. }
  79.  
  80.  
  81.  
  82.  
  83. /****************************************************************************\
  84. *
  85. * Function:     void inVR(void)
  86. *
  87. * Description:  Function that is called some time during Vertical Retrace.
  88. *               Calculates new Horizontal Pixel Panning and screen start
  89. *               address values
  90. *
  91. \****************************************************************************/
  92.  
  93. void inVR(void)
  94. {
  95.     /* Note! Although this function does not cause timer synchronization
  96.        errors if its execution takes too long, it may still cause errors
  97.        to playing tempo when playing with GUS. */
  98.  
  99.     if ( panDir == 0 )
  100.     {
  101.         /* pan display one pixel left: */
  102.  
  103.         horizPan++;                     /* next pixel */
  104.  
  105.         if ( horizPan == 9 )            /* is panning 9? */
  106.             horizPan = 0;               /* if yes, set it to 0 */
  107.         if ( horizPan == 8 )            /* is panning 8? */
  108.             startAddr++;                /* if yes, move to next character */
  109.  
  110.         if ( startAddr == 80 )          /* change direction after */
  111.             panDir = 1;                 /* scrolling one screen */
  112.     }
  113.     else
  114.     {
  115.         /* pan display one pixel right: */
  116.  
  117.         horizPan--;
  118.  
  119.         if ( horizPan == -1 )           /* is panning -1? */
  120.             horizPan = 8;               /* if yes, set it to 8 */
  121.         if ( horizPan == 7 )            /* is panning 7? */
  122.             startAddr--;                /* if yes, move to next character */
  123.  
  124.         if ( (startAddr == 0) && (horizPan == 8) )  /* change direction */
  125.             panDir = 0;                 /* after scrolling back one screen */
  126.     }
  127.  
  128.     /* note that charaters are actually 9 pixels wide on VGA */
  129. }
  130.  
  131.  
  132.  
  133. int main(int argc, char *argv[])
  134. {
  135.     mpModule    *mod;
  136.     int         error;
  137.  
  138.     /* argv[0] is the program name and argv[1] the module filename, the
  139.        rest are options which MIDAS should handle */
  140.  
  141.     /* if there are not enough arguments, show usage and exit: */
  142.     if  ( argc < 2 )
  143.     {
  144.         puts("Usage: SCRDEMO <filename> [MIDAS options]");
  145.         exit(EXIT_SUCCESS);
  146.     }
  147.  
  148.     /* get Timer screen synchronization value: */
  149.     if ( (error = tmrGetScrSync(&scrSync)) != OK )
  150.         midasError(errorMsg[error]);
  151.  
  152.     midasSetDefaults();                 /* set MIDAS defaults */
  153.     midasParseEnvironment();            /* parse MIDAS environment string */
  154.     midasParseOptions(argc-2, &argv[2]);    /* let MIDAS parse all options */
  155.     midasInit();                        /* initialize MIDAS Sound System */
  156.     mod = midasPlayModule(argv[1], 0);  /* load module and start playing */
  157.  
  158.     puts("Playing - type \"EXIT\" to stop.");
  159.  
  160.     horizPan = 8;
  161.     startAddr = 0;
  162.     panDir = 0;
  163.  
  164.     /* Synchronize Timer to screen. preVR() will be called before
  165.        Vertical Retrace, immVR() just after Vertical Retrace starts and
  166.        inVR() some time later during Vertical Retrace. */
  167.     if ( (error = tmrSyncScr(scrSync, &preVR, &immVR, &inVR)) != OK )
  168.         midasError(errorMsg[error]);
  169.  
  170.     /* jump to DOS shell: */
  171.     spawnl(P_WAIT, getenv("COMSPEC"), NULL);
  172.  
  173.     /* stop timer screen synchronization: */
  174.     tmrStopScrSync();
  175.  
  176.     /* reset panning and start address: (dirty but works) */
  177.     horizPan = 8;
  178.     startAddr = 0;
  179.     preVR();
  180.     immVR();
  181.  
  182.     midasStopModule(mod);               /* stop playing */
  183.     midasClose();                       /* uninitialize MIDAS */
  184.  
  185.     return 0;
  186. }
  187.