home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / GRAPHICS / PLASMA3.ZIP / PLASMA.C < prev    next >
Text File  |  1994-02-05  |  14KB  |  496 lines

  1. /*
  2.     Plasma by Jan Mller & Erik Hansen.    (& rewrite by Karl Weller)
  3.  
  4.        It was compiled in Borland c++, in ANSI mode, using the HUGE memory model.
  5.     Feel free to use it as you desire, you may even name it after your
  6.     grandmother. We don't care.
  7.        The reason why we made it? Well... First of all we wanted to make some
  8.     plasma, just for fun. But when we had finished it turned out to be much
  9.     faster than the plasma we have seen in intros, demos etc...
  10.     Normally the color-cells are 2x4 4x4 or even larger, the 2x4 cell-plasma
  11.     was awfully slow, bot ours ain't, even though it is 2x2 cells.
  12.        Well how can that be???                        ^^^^^^^^^
  13.     Our secret lies in the plasma-calculation!
  14.     (I assume you have guessed that    part already)
  15.     We simply calculate as much as possible before we start showing the goddies.
  16.     The table 'Tab1' is a simple table (320x200 yields 64k) with the distance
  17.     from (x,y) to the center (rounded off to char by simple overflow). The second
  18.     table 'Tab2' is similar to 'Tab1', except we molested it with sine.
  19.     In the mainloop we calculate a body (160x100) by accessing the two tables
  20.     with different pairs of (x,y) and add them.
  21.     (see for yourself in 'CalculateBody')
  22.     And KaPoW. We have the fastest plasma...
  23.     (i.e. the fastest we have ever seen.(on a 486)) If I am not correct then please notify me.
  24.  
  25.     If you have any questions, comments or whips, then we would be happy to answer.
  26.  
  27.     Contact us trough E-Mail:
  28.  
  29.     fwiffo@daimi.aau.dk
  30.  
  31.             or
  32.  
  33.     martino@daimi.aau.dk
  34.  
  35.     (If you can optimize it (e.g. write it in asm) we would be very interested
  36.      to see the results!)
  37.  
  38. Modified by: Karl Weller CI$ 74620,2112
  39. to work with all VGA screens and eliminate startup calculations!
  40.  
  41. Final version uses VGA 320x256 x 4 pages (kind of like MODE-X)
  42.  
  43. 02-04-94 (KAW) Final tweaking of program! finish vga page swapping & got
  44.                palette cycling working again (faster)!
  45.                
  46. */
  47. #include <stdio.h>
  48. #include <stdlib.h>
  49. #include <memory.h>
  50. #include <conio.h>
  51. #include <math.h>
  52. #include <fcntl.h>
  53. #include <io.h>
  54. #include <dos.h>
  55. #define uchar unsigned char
  56. #define ulong unsigned long
  57. #define uint unsigned int
  58. #define box_w 160
  59. #define box_h 100
  60. double pi=3.141592654;
  61. //-------------------------------------------------
  62. uchar far *body;    // buffer for the bitmap body
  63. //char far *body = (char far *)0xa0000000;
  64. extern uchar tab1[];            // table one for thr plasma
  65. extern uchar tab2[];            // table two for the plasma
  66. extern unsigned char far pal[];             // palette
  67. unsigned char pal2[800];
  68.  
  69. //-------------------------------------------------
  70.  
  71. void SetMode(char mode)
  72. {
  73.     _asm {
  74.         mov ah,0x00
  75.         mov al,mode
  76.         int 0x10
  77.     }
  78. }
  79. char GetMode(void )
  80. {
  81.     char mode;
  82.  
  83.     _asm {
  84.         mov ah,0x0f
  85.         int 0x10
  86.         mov mode,al
  87.     }
  88.     return (mode);
  89. }
  90.  
  91. void waitvrt(void )
  92. {
  93.     _asm {
  94.         mov dx,0x3da  ; wait for retrace
  95. bra1:
  96.         in  al,dx
  97.         and al,8
  98.         jnz bra1
  99. bra2:
  100.         in  al,dx
  101.         and al,8
  102.         jz bra2
  103.     }
  104. }
  105.  
  106. void setpal(void) {
  107.     unsigned int sg,of;
  108.     char far *p = (char far *)pal2;
  109.     
  110.     sg = FP_SEG(p);
  111.     of = FP_OFF(p);
  112.  
  113.     _asm {
  114.         push ds
  115.         push es
  116.         push si
  117.         push di
  118.         pushf
  119.         
  120.         cld
  121.         mov    cx,sg
  122.         mov    si,of
  123.         mov    dx,03C8h    ;port address of DAC register
  124.         mov    bx,0        ;first register to update
  125.         mov    ax,bx
  126.         cli
  127.         out    dx,al        ;start with this DAC
  128.  
  129.         inc    dx        ;port address where RGB info is written
  130.         mov    ds,cx
  131.         mov    cx,256    ;number of DAC registers to update
  132. setdacloop:
  133.         lodsb
  134.         out    dx,al
  135.         lodsb
  136.         out    dx,al
  137.         lodsb
  138.         out    dx,al
  139.         loop    setdacloop
  140.         sti
  141.         
  142.         popf
  143.         pop di
  144.         pop si
  145.         pop es
  146.         pop ds
  147.  
  148.     }
  149. }
  150.  
  151. static double r=1.0/6.0*3.141592654,g=3.0/6.0*3.141592654,b=5.0/6.0*3.141592654;
  152.  
  153. int palcnt = 1;
  154. int pald = 1;
  155. void CalculateColors()
  156. {
  157.     int i=0,j,k,l;
  158.     
  159. #if 0
  160.     double u,v;
  161.     while(i<256)
  162.     {
  163.         u=2*pi/256*i;
  164. //#define mycol(u,a) (max(0.0,cos((u)+(a))))*63 // try this line instead
  165. #define mycol(u,a) (cos((u)+(a))+1)*31
  166.         pal[i*3] = mycol(u,r);
  167.         pal[i*3+1] = mycol(u,g);
  168.         pal[i*3+2] = mycol(u,b);
  169. /*
  170.         SetPal(i,mycol(u,r),mycol(u,g),mycol(u,b));
  171. */
  172.         i++;
  173.     }
  174. /*
  175.     waitvrt();
  176.     setpal();
  177. */
  178.     r+=0.05;
  179.     g-=0.05;
  180.     b+=0.1;
  181. #else
  182.     memcpy(pal2,pal+(palcnt*768),768);
  183.     palcnt += pald;
  184.     if (palcnt < 1) {
  185.         pald = 1;
  186.         palcnt = 2;
  187.     }
  188.     else if (palcnt >= 49) {
  189.         pald = -1;
  190.         palcnt = 48;
  191.     }
  192. #endif
  193. }
  194.  
  195. void CalculateBody(unsigned x1,unsigned y1,unsigned x2,unsigned y2,unsigned x3,unsigned y3,unsigned x4,unsigned y4,unsigned roll)
  196. {
  197.     unsigned int i=0,j,x=0,t1,t2,t3,t4;
  198.     uchar b,c;
  199.  
  200.     while(i<box_h) {
  201.         j=0;
  202.         t1 = 320*(i+y1)+x1;
  203.         t2 = 320*(i+y2)+x2;
  204.         t3 = 320*(i+y3)+x3;
  205.         t4 = 320*(i+y4)+x4;
  206.         while(j<box_w) {        // this is the heart of the plasma
  207.             b= tab1[t1++]+roll+tab2[t2++]+tab2[t3++]+tab2[t4++];
  208.             c= tab1[t1++]+roll+tab2[t2++]+tab2[t3++]+tab2[t4++];
  209.             body[x] = body[x+80] = body[x+16000] = body[x+16080] = b;
  210.             body[x+32000] = body[x+48000] = body[x+32080] = body[x+48080] = c;
  211.             j+=2;
  212.             x++;
  213.         }
  214.         x+=80;
  215.         i++;
  216.     }
  217. }
  218.  
  219.  
  220. void outdisp(int page)
  221. {
  222.     unsigned char far *addr = (unsigned char far*) (0xA0000000+(0x8000000*page) );
  223.     unsigned int sg,of,ad;
  224.     sg = FP_SEG(body);
  225.     of = FP_OFF(body);
  226.     ad = FP_SEG(addr);
  227.     
  228.     outp(0x3C4, 2);  /* point Sequence Controller to Map Mask reg.   */
  229.     outp(0x3C5,1);     
  230.     _asm {
  231.         push ds
  232.         push es
  233.         push si
  234.         push di
  235.  
  236.         mov cx,sg
  237.         mov dx,of
  238.         mov ax,ad    ; destination screen address.
  239.         mov es,ax        ; into ES
  240.         xor ax,ax
  241.         mov di,ax
  242.         mov si,dx
  243.         mov ds,cx
  244.         mov cx,8000
  245.  
  246.         rep movsw  ; move image to screen 
  247.         pop di
  248.         pop si
  249.         pop es
  250.         pop ds
  251.     }
  252.  
  253. //    memcpy(addr,body,16000);
  254.     outp(0x3C4, 2);  /* point Sequence Controller to Map Mask reg.   */
  255.     outp(0x3C5,2);     
  256.     _asm {
  257.         push ds
  258.         push es
  259.         push si
  260.         push di
  261.  
  262.         mov cx,sg
  263.         mov dx,of
  264.         add dx,16000
  265.         mov ax,ad    ; destination screen address.
  266.         mov es,ax        ; into ES
  267.         xor ax,ax
  268.         mov di,ax
  269.         mov si,dx
  270.         mov ds,cx
  271.         mov cx,8000
  272.  
  273.         rep movsw  ; move image to screen 
  274.         pop di
  275.         pop si
  276.         pop es
  277.         pop ds
  278.     }
  279. //    memcpy(addr,body+(unsigned)16000,16000);
  280.     outp(0x3C4, 2);  /* point Sequence Controller to Map Mask reg.   */
  281.     outp(0x3C5,4);     
  282.     _asm {
  283.         push ds
  284.         push es
  285.         push si
  286.         push di
  287.  
  288.         mov cx,sg
  289.         mov dx,of
  290.         add dx,32000
  291.         mov ax,ad    ; destination screen address.
  292.         mov es,ax        ; into ES
  293.         xor ax,ax
  294.         mov di,ax
  295.         mov si,dx
  296.         mov ds,cx
  297.         mov cx,8000
  298.  
  299.         rep movsw  ; move image to screen 
  300.         pop di
  301.         pop si
  302.         pop es
  303.         pop ds
  304.     }
  305. //    memcpy(addr,body+(unsigned)32000,16000);
  306.     outp(0x3C4, 2);  /* point Sequence Controller to Map Mask reg.   */
  307.     outp(0x3C5,8);     
  308.     _asm {
  309.         push ds
  310.         push es
  311.         push si
  312.         push di
  313.  
  314.         mov cx,sg
  315.         mov dx,of
  316.         add dx,48000
  317.         mov ax,ad    ; destination screen address.
  318.         mov es,ax        ; into ES
  319.         xor ax,ax
  320.         mov di,ax
  321.         mov si,dx
  322.         mov ds,cx
  323.         mov cx,8000
  324.  
  325.         rep movsw  ; move image to screen 
  326.  
  327.         pop di
  328.         pop si
  329.         pop es
  330.         pop ds
  331.     }
  332. //    memcpy(addr,body+(unsigned)48000,16000);
  333. }
  334.  
  335. int _cdecl main(void)
  336. {
  337.     double circle1=0,circle2=0,circle3=0,circle4=0,circle5=0,circle6=0,circle7=0,circle8=0;
  338.     unsigned int x1,y1,x2,y2,x3,y3,x4,y4,roll=0,bh,bw;
  339.     unsigned int fnd,j,i=0;
  340.     int which=1;
  341.     char oldmode;
  342.  
  343.     oldmode=GetMode();
  344.  
  345.     body = malloc((unsigned)65000);
  346.     memset(body,0,(unsigned int)65000);
  347.  
  348.     SetMode(19);
  349.     _asm {
  350.         mov dx, 3CEh                    ; Tell the Graphics Controller
  351.         mov al, 5                       ; to change the graphics mode
  352.         out dx, al                      ; (register 5) to use linear
  353.         inc dx                          ; addresses instead of seperating
  354.         in al, dx                       ; the odd and even addresses.
  355.         and al, 11101111b               ;
  356.         out dx, al                      ;
  357.         dec dx                          ;
  358.  
  359.         mov al, 6                       ; Tell the Graphics Controller
  360.         out dx, al                      ; to change the misc. register
  361.         inc dx                          ; (register 6) to use linear
  362.         in al, dx                       ; addresses instead of seperating
  363.         and al, 11111101b               ; the odd and even addresses.
  364.         out dx, al                      ;
  365.  
  366.         mov dx, 3C4h                    ; Tell the Sequencer Controller
  367.         mov al, 4                       ; to change the memory mode
  368.         out dx, al                      ; (register 4) to disable chain4
  369.         inc dx                          ; mode, and allow linear
  370.         in al, dx                       ; processing on a bitplane.
  371.         and al, 11110111b               ;
  372.         or al, 4                        ;
  373.         out dx, al                      ;
  374.  
  375.         mov ax, 0A000h                  ; Clear the screen.
  376.         mov es, ax                      ;
  377.         xor di, di                      ;
  378.         mov ax, di                      ;
  379.         mov cx, 8000h                   ;
  380.         rep stosw                       ;
  381.  
  382.         mov dx, 3D4h                    ; Tell the CRT Controller to
  383.         mov al, 14h                     ; change the underline location
  384.         out dx, al                      ; (register 14h) to turn off
  385.         inc dx                          ; the double word mode.
  386.         in al, dx                       ;
  387.         and al, 10111111b               ;
  388.         out dx, al                      ;
  389.         dec dx                          ;
  390.  
  391.         mov al, 17h                     ; Tell the CRT Controller to
  392.         out dx, al                      ; change the mode control
  393.         inc dx                          ; (register 17h) to switch
  394.         in al, dx                       ; to byte mode.
  395.         or al, 01000000b                ;
  396.         out dx, al                      ;
  397.     }
  398.  
  399.     bh = box_h/2;
  400.     bw = box_w/2;
  401.     while(1)
  402.     {
  403.         CalculateColors();
  404.         setpal();
  405.         circle1+=0.01416666666666;
  406.         circle2-=0.01666666666666;
  407.         circle3+=0.050;
  408.         circle4-=0.03333333333333;
  409.         circle5+=0.06666666666666;
  410.         circle6-=0.0250;
  411.         circle7+=0.05833333333333;
  412.         circle8-=0.00833333333333;
  413.         x2=(bw)+(bw)*sin(circle1);
  414.         y2=(bh)+(bh)*cos(circle2);
  415.         x1=(bw)+(bw)*cos(circle3);
  416.         y1=(bh)+(bh)*sin(circle4);
  417.         x3=(bw)+(bw)*cos(circle5);
  418.         y3=(bh)+(bh)*sin(circle6);
  419.         x4=(bw)+(bw)*cos(circle7);
  420.         y4=(bh)+(bh)*sin(circle8);
  421.         CalculateBody(x1,y1,x2,y2,x3,y3,x4,y4,roll+=5);
  422.         if (which++ % 2) {
  423.             outdisp(1);
  424.             _asm {
  425.                 mov dx,0x3da  ; wait for retrace
  426. bra1:
  427.                 in  al,dx
  428.                 and al,8
  429.                 jnz bra1
  430. bra2:
  431.                 in  al,dx
  432.                 and al,8
  433.                 jz bra2
  434.  
  435.                 mov dx,0x3d4
  436.                 mov ax,0x800c
  437.                 out dx,ax
  438.             }
  439. //            outpw(0x3D4, 0x800C);              /* Flip to other page, */
  440.         }
  441.         else {
  442.             outdisp(0);
  443.             if (kbhit()) break;
  444.             _asm {
  445.                 mov dx,0x3da  ; wait for retrace
  446. bra1a:
  447.                 in  al,dx
  448.                 and al,8
  449.                 jnz bra1a
  450. bra2a:
  451.                 in  al,dx
  452.                 and al,8
  453.                 jz bra2a
  454.  
  455.                 mov dx,0x3d4
  456.                 mov ax,0x0c
  457.                 out dx,ax
  458.             }
  459. //            outpw(0x3D4, 0x0C);              /* Flip to other page, */
  460.         }
  461.     }
  462.     while(kbhit()) getch();
  463.     free(body);
  464. /************************************/
  465. /* A Clean ending is a nice ending! */
  466. /* (K.W.)                           */
  467. /************************************/
  468.     memset(body,0,(unsigned)64000);
  469.     for(i=0;i<256;++i) {
  470.         if (kbhit()) break;
  471.         fnd=0;
  472.         for(j=0;j<771;++j) {
  473.             if (pal2[j]>=2) {
  474.                 pal2[j]-=2;
  475.                 ++fnd;
  476.             }
  477.         }
  478.         waitvrt();
  479.         setpal();                 /* fade the pal */
  480.         if (!fnd) break;
  481.     }
  482.     memset(pal2,0,771);
  483.     waitvrt();
  484.     setpal();                 /* blank the pal */
  485.     waitvrt();
  486.     outpw(0x3D4, 0x0C);            
  487.     outdisp(1);               /* blank page 1 */
  488.     outpw(0x3D4, 0x800C);        
  489.     outdisp(0);               /* blank page 0 */
  490.     outpw(0x3D4, 0x0C);
  491.  
  492.     SetMode(oldmode);
  493.     waitvrt();
  494.     return 0;
  495. }
  496.