Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentesRévision précédente | |||
back2root:archives:denthor:part-07 [2021/09/02 11:10] – [In Closing] frater | back2root:archives:denthor:part-07 [2021/09/05 14:00] (Version actuelle) – [In Closing] frater | ||
---|---|---|---|
Ligne 394: | Ligne 394: | ||
</ | </ | ||
+ | ==== Code Source ==== | ||
+ | === PASCAL === | ||
+ | <code pascal> | ||
+ | (*****************************************************************************) | ||
+ | (* *) | ||
+ | (* TUT7.PAS - VGA Trainer Program 7 (in Pascal) | ||
+ | (* *) | ||
+ | (* "The VGA Trainer Program" | ||
+ | (* was limited to Pascal only in its first run. All I have done is taken *) | ||
+ | (* his original release, translated it to C++, and touched up a few things. | ||
+ | (* I take absolutely no credit for the concepts presented in this code, and *) | ||
+ | (* am NOT the person to ask for help if you are having trouble. | ||
+ | (* *) | ||
+ | (* Program Notes : This program demonstrates animation. | ||
+ | (* | ||
+ | (* | ||
+ | (* *) | ||
+ | (* Author | ||
+ | (* *) | ||
+ | (*****************************************************************************) | ||
+ | {$X+} | ||
+ | USES crt; | ||
+ | CONST VGA = $a000; | ||
+ | Type Toastinfo = Record | ||
+ | | ||
+ | | ||
+ | | ||
+ | END; | ||
+ | icon = Array [1..30*48] of byte; { This is the size of our pictures } | ||
+ | | ||
+ | | ||
+ | CONST frame1 : icon = ( | ||
+ | 0, | ||
+ | 7, | ||
+ | 5, | ||
+ | 0, | ||
+ | 5, | ||
+ | 5, | ||
+ | 0, | ||
+ | 7, | ||
+ | 8, | ||
+ | 9, | ||
+ | 1, | ||
+ | 1, | ||
+ | 0, | ||
+ | 0, | ||
+ | 7, | ||
+ | 7, | ||
+ | 1, | ||
+ | 1, | ||
+ | 0, | ||
+ | 0, | ||
+ | 2, | ||
+ | 2, | ||
+ | 1, | ||
+ | 4, | ||
+ | 0, | ||
+ | 0, | ||
+ | 9, | ||
+ | 9, | ||
+ | 1, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | ); | ||
+ | frame2 : icon = ( | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 9, | ||
+ | 1, | ||
+ | 1, | ||
+ | 0, | ||
+ | 0, | ||
+ | 2, | ||
+ | 5, | ||
+ | 1, | ||
+ | 1, | ||
+ | 0, | ||
+ | 0, | ||
+ | 5, | ||
+ | 2, | ||
+ | 1, | ||
+ | 4, | ||
+ | 0, | ||
+ | 0, | ||
+ | 5, | ||
+ | 9, | ||
+ | 1, | ||
+ | 1, | ||
+ | 0, | ||
+ | 0, | ||
+ | 5, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | ); | ||
+ | frame3 : icon = ( | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 9, | ||
+ | 1, | ||
+ | 1, | ||
+ | 0, | ||
+ | 5, | ||
+ | 1, | ||
+ | 2, | ||
+ | 1, | ||
+ | 1, | ||
+ | 7, | ||
+ | 5, | ||
+ | 2, | ||
+ | 2, | ||
+ | 1, | ||
+ | 4, | ||
+ | 0, | ||
+ | 0, | ||
+ | 9, | ||
+ | 9, | ||
+ | 1, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | ); | ||
+ | VAR Virscr : VirtPtr; | ||
+ | VirScr2 : VirtPtr; | ||
+ | Vaddr : word; { The segment of our virtual screen} | ||
+ | Vaddr2 : Word; { The segment of our 2nd virt. screen} | ||
+ | ourpal : Array [0..255, | ||
+ | toaster : Array [1..10] of toastinfo; { The toaster info } | ||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure SetMCGA; | ||
+ | BEGIN | ||
+ | asm | ||
+ | | ||
+ | | ||
+ | end; | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure SetText; | ||
+ | BEGIN | ||
+ | asm | ||
+ | | ||
+ | | ||
+ | end; | ||
+ | END; | ||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure Cls (Col : Byte; Where: | ||
+ | { This clears the screen to the specified color } | ||
+ | BEGIN | ||
+ | asm | ||
+ | push es | ||
+ | mov cx, 32000; | ||
+ | mov | ||
+ | xor di,di | ||
+ | mov | ||
+ | mov ah,al | ||
+ | rep stosw | ||
+ | pop es | ||
+ | End; | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure Putpixel (X,Y : Integer; Col : Byte; where: | ||
+ | { This puts a pixel on the screen by writing directly to memory. } | ||
+ | BEGIN | ||
+ | Asm | ||
+ | push ds | ||
+ | push es | ||
+ | mov | ||
+ | mov es,ax | ||
+ | mov | ||
+ | mov | ||
+ | push bx {; and this again for later} | ||
+ | mov bx, dx {; bx = dx} | ||
+ | mov dh, dl {; dx = dx * 256} | ||
+ | xor dl, dl | ||
+ | shl bx, 1 | ||
+ | shl bx, 1 | ||
+ | shl bx, 1 | ||
+ | shl bx, 1 | ||
+ | shl bx, 1 | ||
+ | shl bx, 1 {; bx = bx * 64} | ||
+ | add dx, bx {; dx = dx + bx (ie y*320)} | ||
+ | pop | ||
+ | add bx, dx {; finalise location} | ||
+ | mov di, bx | ||
+ | {; es:di = where to go} | ||
+ | xor al,al | ||
+ | mov ah, [Col] | ||
+ | mov | ||
+ | pop es | ||
+ | pop ds | ||
+ | End; | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | procedure WaitRetrace; | ||
+ | { This waits for a vertical retrace to reduce snow on the screen } | ||
+ | label | ||
+ | l1, l2; | ||
+ | asm | ||
+ | mov dx,3DAh | ||
+ | l1: | ||
+ | in al,dx | ||
+ | and al,08h | ||
+ | jnz l1 | ||
+ | l2: | ||
+ | in al,dx | ||
+ | and al,08h | ||
+ | jz l2 | ||
+ | end; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure Pal(Col, | ||
+ | { This sets the Red, Green and Blue values of a certain color } | ||
+ | Begin | ||
+ | asm | ||
+ | mov dx,3c8h | ||
+ | mov al,[col] | ||
+ | out dx,al | ||
+ | inc dx | ||
+ | mov al,[r] | ||
+ | out dx,al | ||
+ | mov al,[g] | ||
+ | out dx,al | ||
+ | mov al,[b] | ||
+ | out dx,al | ||
+ | end; | ||
+ | End; | ||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure GetPal(Col : Byte; Var R,G,B : Byte); | ||
+ | { This gets the Red, Green and Blue values of a certain color } | ||
+ | Var | ||
+ | | ||
+ | Begin | ||
+ | asm | ||
+ | mov dx,3c7h | ||
+ | mov al,col | ||
+ | out dx,al | ||
+ | |||
+ | add dx,2 | ||
+ | |||
+ | in al,dx | ||
+ | mov [rr],al | ||
+ | in al,dx | ||
+ | mov [gg],al | ||
+ | in al,dx | ||
+ | mov [bb],al | ||
+ | end; | ||
+ | r := rr; | ||
+ | g := gg; | ||
+ | b := bb; | ||
+ | end; | ||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure SetUpVirtual; | ||
+ | { This sets up the memory needed for the virtual screen } | ||
+ | BEGIN | ||
+ | GetMem (VirScr, | ||
+ | vaddr := seg (virscr^); | ||
+ | GetMem (VirScr2, | ||
+ | vaddr2 := seg (virscr2^); | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure ShutDown; | ||
+ | { This frees the memory used by the virtual screen } | ||
+ | BEGIN | ||
+ | FreeMem (VirScr, | ||
+ | FreeMem (VirScr2, | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | procedure flip(source, | ||
+ | { This copies the entire screen at " | ||
+ | begin | ||
+ | asm | ||
+ | push ds | ||
+ | mov ax, [Dest] | ||
+ | mov es, ax | ||
+ | mov ax, [Source] | ||
+ | mov ds, ax | ||
+ | xor si, si | ||
+ | xor di, di | ||
+ | mov cx, 32000 | ||
+ | rep movsw | ||
+ | pop ds | ||
+ | end; | ||
+ | end; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure putico(X, | ||
+ | { This puts an icon, EXCEPT it's color 0 (black) pixels, onto the screen | ||
+ | " | ||
+ | label | ||
+ | _Redraw, _DrawLoop, _Exit, _LineLoop, _NextLine, _Store, _NoPaint; | ||
+ | |||
+ | asm | ||
+ | push ds | ||
+ | push es | ||
+ | lds | ||
+ | mov | ||
+ | mov | ||
+ | _Redraw: | ||
+ | push ax | ||
+ | mov | ||
+ | mov es,ax | ||
+ | |||
+ | mov ax, bx {; ax = bx x = y} | ||
+ | mov bh, bl {; y = y * 256 bx = bx * 256} | ||
+ | xor bl, bl | ||
+ | shl ax, 1 | ||
+ | shl ax, 1 | ||
+ | shl ax, 1 | ||
+ | shl ax, 1 | ||
+ | shl ax, 1 | ||
+ | shl ax, 1 {; y = y * 64 ax = ax * 64} | ||
+ | add bx, ax {; y = (y*256) + (Y*64) | ||
+ | |||
+ | pop | ||
+ | |||
+ | |||
+ | add ax, bx {; finalise location} | ||
+ | mov di, ax | ||
+ | |||
+ | mov | ||
+ | xor ch,ch | ||
+ | mov | ||
+ | cld | ||
+ | push ax | ||
+ | mov ax,cx | ||
+ | _DrawLoop: | ||
+ | push di { store y adr. for later } | ||
+ | mov | ||
+ | _LineLoop: | ||
+ | mov | ||
+ | or bl,bl | ||
+ | jnz | ||
+ | _NoPaint: | ||
+ | inc si | ||
+ | inc di | ||
+ | loop | ||
+ | jmp _NextLine | ||
+ | _Store: | ||
+ | movsb | ||
+ | loop _LineLoop | ||
+ | _NextLine: | ||
+ | pop di | ||
+ | dec dl | ||
+ | jz _Exit | ||
+ | add | ||
+ | jmp | ||
+ | _Exit: | ||
+ | pop ax | ||
+ | pop es | ||
+ | pop ds | ||
+ | end; | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure Funny_line(a, | ||
+ | { This procedure draws a line from a,b to c,d on screen " | ||
+ | each pixel it plots, it increments a color counter for the next pixel. | ||
+ | you may easily alter this to be a normal line procedure, and it will | ||
+ | be quite a bit faster than the origional one I gave you. This is | ||
+ | because I replaced all the reals with integers. } | ||
+ | |||
+ | function sgn(a: | ||
+ | begin | ||
+ | if a>0 then sgn:=+1; | ||
+ | if a<0 then sgn:=-1; | ||
+ | if a=0 then sgn:=0; | ||
+ | end; | ||
+ | var i, | ||
+ | count: | ||
+ | begin | ||
+ | | ||
+ | u:= c - a; | ||
+ | v:= d - b; | ||
+ | d1x:= SGN(u); | ||
+ | d1y:= SGN(v); | ||
+ | d2x:= SGN(u); | ||
+ | d2y:= 0; | ||
+ | m:= ABS(u); | ||
+ | n := ABS(v); | ||
+ | IF NOT (M>N) then | ||
+ | BEGIN | ||
+ | d2x := 0 ; | ||
+ | d2y := SGN(v); | ||
+ | m := ABS(v); | ||
+ | n := ABS(u); | ||
+ | END; | ||
+ | s := m shr 1; | ||
+ | FOR i := 0 TO m DO | ||
+ | BEGIN | ||
+ | putpixel(a, | ||
+ | inc (count); | ||
+ | if count=101 then count:=50; | ||
+ | s := s + n; | ||
+ | IF not (s<m) THEN | ||
+ | BEGIN | ||
+ | s := s - m; | ||
+ | a:= a + d1x; | ||
+ | b := b + d1y; | ||
+ | END | ||
+ | ELSE | ||
+ | BEGIN | ||
+ | a := a + d2x; | ||
+ | b := b + d2y; | ||
+ | END; | ||
+ | end; | ||
+ | END; | ||
+ | |||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure SetUpScreen; | ||
+ | { This procedure sets up the static background to be used in the program } | ||
+ | |||
+ | CONST circ : Array [1..5,1..5] of byte = | ||
+ | ((0, | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | VAR x, | ||
+ | loop1, | ||
+ | |||
+ | BEGIN | ||
+ | pal (1, | ||
+ | pal (2, | ||
+ | pal (3, | ||
+ | pal (4, | ||
+ | pal (5, | ||
+ | pal (6, | ||
+ | pal (7,3,27,3); | ||
+ | pal (8, | ||
+ | pal (9, | ||
+ | pal (10, 0, 0,40); | ||
+ | pal (11, | ||
+ | pal (12, | ||
+ | pal (13, | ||
+ | |||
+ | For loop1:=50 to 100 do | ||
+ | pal (loop1, | ||
+ | |||
+ | For loop1:=0 to 255 do | ||
+ | | ||
+ | |||
+ | For loop1:=0 to 319 do | ||
+ | Funny_line (0, | ||
+ | For loop1:=0 to 199 do | ||
+ | Funny_line (0, | ||
+ | |||
+ | For loop1:=1 to 200 do BEGIN | ||
+ | x:=random (315); | ||
+ | y:=random (195); | ||
+ | For loop2:=1 to 5 do | ||
+ | For loop3:=1 to 5 do | ||
+ | if circ [loop2, | ||
+ | putpixel (x+loop2, | ||
+ | END; | ||
+ | flip (vaddr, | ||
+ | { on which we have done all our graphics, onto the } | ||
+ | { screen you see, VGA } | ||
+ | flip (vaddr, | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure rotatepal; | ||
+ | { This procedure rotates the colors between 50 and 100 } | ||
+ | VAR temp : Array [1..3] of byte; | ||
+ | loop1: | ||
+ | BEGIN | ||
+ | Move(OurPal[100], | ||
+ | Move(OurPal[50], | ||
+ | Move(Temp, | ||
+ | For loop1:=50 to 100 do | ||
+ | pal (loop1, | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure ScreenTrans (x,y:word); | ||
+ | { This is a small procedure to copy a 30x30 pixel block from coordinates | ||
+ | x,y on the virtual screen to coordinates x,y on the true vga screen } | ||
+ | BEGIN | ||
+ | asm | ||
+ | push ds | ||
+ | push es | ||
+ | mov | ||
+ | mov es,ax | ||
+ | mov | ||
+ | mov ds,ax | ||
+ | mov | ||
+ | mov | ||
+ | push bx {; and this again for later} | ||
+ | mov bx, dx {; bx = dx} | ||
+ | mov dh, dl {; dx = dx * 256} | ||
+ | xor dl, dl | ||
+ | shl bx, 1 | ||
+ | shl bx, 1 | ||
+ | shl bx, 1 | ||
+ | shl bx, 1 | ||
+ | shl bx, 1 | ||
+ | shl bx, 1 {; bx = bx * 64} | ||
+ | add dx, bx {; dx = dx + bx (ie y*320)} | ||
+ | pop | ||
+ | add bx, dx {; finalise location} | ||
+ | mov di, bx {; es:di = where to go} | ||
+ | mov si, di | ||
+ | mov al,60 | ||
+ | mov bx, 30 { Hight of block to copy } | ||
+ | @@1 : | ||
+ | mov cx, 24 { Width of block to copy divided by 2 } | ||
+ | rep movsw | ||
+ | add | ||
+ | add | ||
+ | dec bx | ||
+ | jnz @@1 | ||
+ | |||
+ | pop es | ||
+ | pop ds | ||
+ | end; | ||
+ | { I wrote this procedure late last night, so it may not be in it's | ||
+ | most optimised state. Sorry :-)} | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure NewToaster; | ||
+ | { This adds a new toaster to the screen } | ||
+ | VAR loop1: | ||
+ | BEGIN | ||
+ | loop1:=0; | ||
+ | repeat | ||
+ | inc (loop1); | ||
+ | if not (toaster[loop1].active) then BEGIN | ||
+ | toaster[loop1].x: | ||
+ | toaster[loop1].y: | ||
+ | toaster[loop1].active: | ||
+ | toaster[loop1].frame: | ||
+ | toaster[loop1].speed: | ||
+ | loop1:=10; | ||
+ | END; | ||
+ | until loop1=10; | ||
+ | END; | ||
+ | |||
+ | |||
+ | {ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ} | ||
+ | Procedure Fly; | ||
+ | { This is the procedure where we move and put the toasters } | ||
+ | VAR loop1, | ||
+ | ch:char; | ||
+ | BEGIN | ||
+ | For loop1:=1 to 10 do | ||
+ | toaster[loop1].active: | ||
+ | ch:=#0; | ||
+ | NewToaster; | ||
+ | Repeat | ||
+ | if keypressed then BEGIN | ||
+ | ch: | ||
+ | if ch=' | ||
+ | if ch=' | ||
+ | loop1:=0; | ||
+ | repeat | ||
+ | inc (loop1); | ||
+ | if toaster[loop1].active then BEGIN | ||
+ | screentrans (toaster[loop1].x, | ||
+ | toaster [loop1].active: | ||
+ | loop1:=10; | ||
+ | END; | ||
+ | until loop1=10; | ||
+ | END; | ||
+ | END; | ||
+ | for loop1:=1 to 10 do | ||
+ | if toaster[loop1].active then BEGIN | ||
+ | screentrans (toaster[loop1].x, | ||
+ | { Restore the backgrond the toaster was over } | ||
+ | dec (toaster[loop1].x, | ||
+ | inc (toaster[loop1].y, | ||
+ | { Move the toaster } | ||
+ | if (toaster[loop1].x< | ||
+ | toaster[loop1].active: | ||
+ | NewToaster; | ||
+ | END; | ||
+ | { When toaster reaches the edge of the screen, render it inactive | ||
+ | and bring a new one into existance. } | ||
+ | END; | ||
+ | for loop1:=1 to 10 do | ||
+ | if toaster[loop1].active then BEGIN | ||
+ | CASE toaster [loop1].frame of | ||
+ | | ||
+ | | ||
+ | 2,4 : putico (toaster[loop1].x, | ||
+ | END; | ||
+ | toaster[loop1].frame: | ||
+ | if toaster [loop1].frame=5 then toaster[loop1].frame: | ||
+ | { Draw all the toasters on the VGA screen } | ||
+ | END; | ||
+ | waitretrace; | ||
+ | flip (vaddr, | ||
+ | rotatepal; | ||
+ | Until ch=#27; | ||
+ | END; | ||
+ | |||
+ | |||
+ | BEGIN | ||
+ | Randomize; | ||
+ | SetupVirtual; | ||
+ | ClrScr; | ||
+ | writeln (' | ||
+ | writeln ('The program will firstly generate an arb background screen to a'); | ||
+ | writeln (' | ||
+ | writeln ('to move across the screen. Note that the background will be restored' | ||
+ | writeln (' | ||
+ | writeln ('by hitting " | ||
+ | writeln ('use, usually the better the routine looks. Because of space' | ||
+ | writeln (' | ||
+ | writeln; | ||
+ | writeln ('The toasters were drawn by Fubar (Pieter Buys) in Autodesk Animator.' | ||
+ | writeln ('I wrote a small little program to convert them into CONSTANTS. See'); | ||
+ | writeln ('the main text to find out how to load up AA CEL files directly.' | ||
+ | writeln; | ||
+ | writeln; | ||
+ | Write (' | ||
+ | Readkey; | ||
+ | SetMCGA; | ||
+ | SetupScreen; | ||
+ | the VGA screen } | ||
+ | Fly; { Make the toasters fly around the screen } | ||
+ | SetText; | ||
+ | ShutDown; | ||
+ | Writeln ('All done. This concludes the seventh sample program in the ASPHYXIA' | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln ('For discussion purposes, I am also the moderator of the Programming' | ||
+ | Writeln (' | ||
+ | Writeln ('The numbers are available in the main text. You may also write to me at:'); | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln (' | ||
+ | Writeln ('I hope to hear from you soon!' | ||
+ | Writeln; Writeln; | ||
+ | Write | ||
+ | Readkey; | ||
+ | END. | ||
+ | </ | ||
+ | |||
+ | === C === | ||
+ | |||
+ | <code c> | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // TUTPROG7.CPP - VGA Trainer Program 7 (in Turbo C++ 3.0) // | ||
+ | // // | ||
+ | // "The VGA Trainer Program" | ||
+ | // was limited to only Pascal in its first run. All I have done is taken // | ||
+ | // his original release, translated it to C++ and touched up a few things. // | ||
+ | // I take absolutely no credit for the concepts presented in this code and // | ||
+ | // am NOT the person to ask for help if you are having trouble. | ||
+ | // // | ||
+ | // Program Notes : This program demonstrates animation. | ||
+ | // | ||
+ | // | ||
+ | // // | ||
+ | // If you are compiling this program from within the // | ||
+ | // Turbo C++ environment, | ||
+ | // | ||
+ | // 132 or greater. | ||
+ | // with the code a bit, I suggest raising this to about // | ||
+ | // 150 just to be on the safe side. You don't have to // | ||
+ | // worry about this if you are compiling command line. // | ||
+ | // // | ||
+ | // Just for reference, this is what I use: // | ||
+ | // // | ||
+ | // tcc tut7 -mc -a -G -2 -O // | ||
+ | // // | ||
+ | // The Compact memory model (-mc) seems to provide the // | ||
+ | // best results for this tutorial. | ||
+ | // | ||
+ | // and lots of data. // | ||
+ | // // | ||
+ | // Author | ||
+ | // Translator | ||
+ | // // | ||
+ | // Last Modified : January 6, 1995 // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | // // | ||
+ | // INCLUDE FILES // | ||
+ | // // | ||
+ | |||
+ | #include < | ||
+ | // farcalloc() | ||
+ | #include < | ||
+ | // clrscr(), getch(), kbhit() | ||
+ | #include < | ||
+ | // FP_SEG, geninterrupt() | ||
+ | #include < | ||
+ | // cout, memmove() | ||
+ | #include < | ||
+ | // abs(), exit(), randomize(), | ||
+ | |||
+ | // // | ||
+ | // TYPEDEFS // | ||
+ | // // | ||
+ | |||
+ | typedef unsigned char byte; | ||
+ | typedef unsigned int word; | ||
+ | |||
+ | // // | ||
+ | // TOASTER DATA // | ||
+ | // // | ||
+ | |||
+ | const byte FRAME1[] = { | ||
+ | 0, | ||
+ | 7, | ||
+ | 5, | ||
+ | 0, | ||
+ | 5, | ||
+ | 5, | ||
+ | 0, | ||
+ | 7, | ||
+ | 8, | ||
+ | 9, | ||
+ | 1, | ||
+ | 1, | ||
+ | 0, | ||
+ | 0, | ||
+ | 7, | ||
+ | 7, | ||
+ | 1, | ||
+ | 1, | ||
+ | 0, | ||
+ | 0, | ||
+ | 2, | ||
+ | 2, | ||
+ | 1, | ||
+ | 4, | ||
+ | 0, | ||
+ | 0, | ||
+ | 9, | ||
+ | 9, | ||
+ | 1, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | }; | ||
+ | |||
+ | const byte FRAME2[] = { | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 9, | ||
+ | 1, | ||
+ | 1, | ||
+ | 0, | ||
+ | 0, | ||
+ | 2, | ||
+ | 5, | ||
+ | 1, | ||
+ | 1, | ||
+ | 0, | ||
+ | 0, | ||
+ | 5, | ||
+ | 2, | ||
+ | 1, | ||
+ | 4, | ||
+ | 0, | ||
+ | 0, | ||
+ | 5, | ||
+ | 9, | ||
+ | 1, | ||
+ | 1, | ||
+ | 0, | ||
+ | 0, | ||
+ | 5, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | }; | ||
+ | |||
+ | const byte FRAME3[] = { | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 9, | ||
+ | 1, | ||
+ | 1, | ||
+ | 0, | ||
+ | 5, | ||
+ | 1, | ||
+ | 2, | ||
+ | 1, | ||
+ | 1, | ||
+ | 7, | ||
+ | 5, | ||
+ | 2, | ||
+ | 2, | ||
+ | 1, | ||
+ | 4, | ||
+ | 0, | ||
+ | 0, | ||
+ | 9, | ||
+ | 9, | ||
+ | 1, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | 0, | ||
+ | }; | ||
+ | |||
+ | // // | ||
+ | // CONSTANTS // | ||
+ | // // | ||
+ | |||
+ | const VGA = 0xa000; | ||
+ | const ICON = 30*48; | ||
+ | const NUMTOASTERS = 10; // The maximum number of toasters we have | ||
+ | const NUMCIRCLES = 200; // The number of little circles on the screen | ||
+ | const TRUE = 1; | ||
+ | const FALSE = 0; | ||
+ | |||
+ | // // | ||
+ | // FUNCTION PROTOTYPES // | ||
+ | // // | ||
+ | |||
+ | // GENERAL VIDEO TOOLS | ||
+ | void SetMCGA | ||
+ | void SetText | ||
+ | void Cls (byte Col, word Where); | ||
+ | void Putpixel | ||
+ | void WaitRetrace (); | ||
+ | void Pal (byte Col, byte R, byte G, byte B); | ||
+ | void GetPal | ||
+ | |||
+ | // MID-LEVEL FUNCTIONS | ||
+ | void SetUpVirtual(); | ||
+ | void ShutDown | ||
+ | void Flip (word source, word dest); | ||
+ | void Putico | ||
+ | void Funny_line | ||
+ | int sgn (int a); | ||
+ | void SetUpScreen (); | ||
+ | void Rotatepal | ||
+ | void ScreenTrans (word x, word y); | ||
+ | void NewToaster | ||
+ | void Fly (); | ||
+ | |||
+ | // // | ||
+ | // STRUCTURES // | ||
+ | // // | ||
+ | |||
+ | struct Toastinfo { | ||
+ | int x; | ||
+ | int y; | ||
+ | word | ||
+ | word | ||
+ | byte | ||
+ | }; | ||
+ | |||
+ | // // | ||
+ | // GLOBAL VARIABLE DECLARATIONS // | ||
+ | // // | ||
+ | |||
+ | byte far *Virscr1=NULL, | ||
+ | word Vaddr1, Vaddr2; | ||
+ | byte ourpal[256][3]; | ||
+ | Toastinfo toaster[NUMTOASTERS]; | ||
+ | |||
+ | |||
+ | /////////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // MAIN FUNCTION | ||
+ | // // | ||
+ | /////////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void main() { | ||
+ | |||
+ | randomize(); | ||
+ | SetUpVirtual(); | ||
+ | |||
+ | clrscr(); | ||
+ | cout | ||
+ | << " | ||
+ | << "The program will firstly generate an arb background screen to a\n" | ||
+ | << " | ||
+ | << "to move across the screen. Note that the background will be restored\n" | ||
+ | << "after the toaster has passed over it. You may add or remove toasters\n" | ||
+ | << "by hitting "" | ||
+ | << "use, usually the better the routine looks. Because of space\n" | ||
+ | << " | ||
+ | cout | ||
+ | << "The toasters were drawn by Fubar (Pieter Buys) in Autodesk Animator.\n" | ||
+ | << "I wrote a small little program to convert them into CONSTANTS. See\n" | ||
+ | << "the main text to find out how to load up AA CEL files directly.\n\n\n"; | ||
+ | cout << "Hit any key to continue..."; | ||
+ | getch(); | ||
+ | |||
+ | SetMCGA(); | ||
+ | SetUpScreen(); | ||
+ | Fly(); | ||
+ | SetText(); | ||
+ | ShutDown(); | ||
+ | |||
+ | cout | ||
+ | << "All done. This concludes the seventh sample program in the ASPHYXIA\n" | ||
+ | << " | ||
+ | << " | ||
+ | << " | ||
+ | << "For discussion purposes, I am also the moderator of the Programming\n" | ||
+ | << " | ||
+ | << "The numbers are available in the main text. You may also write to me at:\n" | ||
+ | << " | ||
+ | << " | ||
+ | << " | ||
+ | << " | ||
+ | << "I hope to hear from you soon!\n\n\n"; | ||
+ | cout << "Hit any key to exit..."; | ||
+ | getch(); | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // SetMCGA() - This function gets you into 320x200x256 mode. // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void SetMCGA() { | ||
+ | _AX = 0x0013; | ||
+ | geninterrupt (0x10); | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // SetText() - This function gets you into text mode. // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void SetText() { | ||
+ | _AX = 0x0003; | ||
+ | geninterrupt (0x10); | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // Cls() - This clears the screen at location Where to color Col // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void Cls(byte Col, word Where) { | ||
+ | asm { | ||
+ | push es // save ES | ||
+ | mov cx, 32000 // this is our loop counter. | ||
+ | // | ||
+ | // | ||
+ | // | ||
+ | mov es, [Where] | ||
+ | xor di, di // zero out DI | ||
+ | mov al, [Col] // move color to AL | ||
+ | mov ah, al // move color to AH (Remember, will be moving | ||
+ | // | ||
+ | rep | ||
+ | // | ||
+ | pop | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // Putpixel() - This puts a pixel on the screen by writing directly to // | ||
+ | // memory. | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void Putpixel (word X, word Y, byte Col, word Where) { | ||
+ | asm { | ||
+ | push ds // save DS | ||
+ | push es // save ES | ||
+ | mov ax, [Where] | ||
+ | mov es, ax // set ES to segment of Where | ||
+ | mov bx, [X] // set BX to X | ||
+ | mov dx, [Y] // set DX to Y | ||
+ | push bx // save BX (our X value) | ||
+ | mov bx, dx // now BX and DX are equal to Y | ||
+ | mov dh, dl // copy DL to DH (multiply Y by 256) | ||
+ | xor dl, dl // zero out DL | ||
+ | shl bx, 6 // shift BX left 6 places (multiply Y by 64). | ||
+ | add dx, bx // add BX to DX (Y*64 + Y*256 = Y*320) | ||
+ | pop | ||
+ | add bx, dx // add BX to DX (Y*320 + X). this gives you | ||
+ | // | ||
+ | mov di, bx // move the offset to DI | ||
+ | xor al, al // zero out AL | ||
+ | mov ah, [Col] // move value of Col into AH | ||
+ | mov | ||
+ | pop | ||
+ | pop | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // WaitRetrace() - This waits until you are in a Verticle Retrace. | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void WaitRetrace() { | ||
+ | |||
+ | asm mov dx,0x03DA | ||
+ | |||
+ | l1: asm { | ||
+ | in al,dx; | ||
+ | and | ||
+ | jnz l1; | ||
+ | } | ||
+ | l2: asm { | ||
+ | in al,dx; | ||
+ | and | ||
+ | jz l2; | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // Pal() - This sets the Red, Green, and Blue values of a certain color. | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void Pal (byte Col, byte R, byte G, byte B) { | ||
+ | asm { | ||
+ | mov dx, 0x3C8 // load DX with 3C8 (write pallette function) | ||
+ | mov al, [Col] // move color to AL | ||
+ | out dx, al // write DX to the VGA (tell VGA that we want to | ||
+ | // | ||
+ | inc | ||
+ | mov al, [R] // move Red to AL | ||
+ | out dx, al // write DX to VGA (tell VGA that we want to use | ||
+ | // | ||
+ | mov al, [G] // move Green to AL | ||
+ | out dx, al // write DX to VGA | ||
+ | mov al, [B] // move Blue to AL | ||
+ | out dx, al // write DX to VGA | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // GetPal() - This reads the values of the Red, Green, and Blue values of // | ||
+ | // a certain color. | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void GetPal (byte Col, byte &R, byte &G, byte &B) { | ||
+ | |||
+ | byte rr,gg,bb; | ||
+ | |||
+ | asm { | ||
+ | mov dx, 0x03C7 | ||
+ | mov al, [Col] // move color to AL | ||
+ | out dx, al // write DX to the VGA (tell VGA that we want to | ||
+ | // | ||
+ | add dx, 2 // load DX with 3C9 (read RGB colors) | ||
+ | in al, dx // read Red to AL | ||
+ | mov | ||
+ | in al, dx // read Green to AL | ||
+ | mov | ||
+ | in al, dx // read Blue to AL | ||
+ | mov | ||
+ | } | ||
+ | |||
+ | R = rr; | ||
+ | G = gg; | ||
+ | B = bb; | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // SetUpVirtual() - This sets up the memory needed for the virtual screen. // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void SetUpVirtual() { | ||
+ | |||
+ | Virscr1 = (byte far *) farcalloc(64000, | ||
+ | Virscr2 = (byte far *) farcalloc(64000, | ||
+ | |||
+ | // always check to see if enough memory was allocated | ||
+ | if ((Virscr1 == NULL) || (Virscr2 == NULL)) { | ||
+ | SetText(); | ||
+ | cout << " | ||
+ | free(Virscr1); | ||
+ | // deallocate the first. | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | Vaddr1 = FP_SEG(Virscr1); | ||
+ | Vaddr2 = FP_SEG(Virscr2); | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // ShutDown() - This frees the memory used by the virtual screen. | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void ShutDown() { | ||
+ | |||
+ | // free(Virscr1); | ||
+ | // free(Virscr2); | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // Flip() - This copies the entire screen at " | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void Flip(word source, word dest) { | ||
+ | asm { | ||
+ | push ds // save DS | ||
+ | mov ax, [dest] | ||
+ | mov es, ax // set ES to point to destination | ||
+ | mov ax, [source] // copy segment of source to AX | ||
+ | mov ds, ax // set DS to point to source | ||
+ | xor si, si // zero out SI | ||
+ | xor di, di // zero out DI | ||
+ | mov cx, 32000 // set our counter to 32000 | ||
+ | rep | ||
+ | // | ||
+ | pop | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // Putico() - This puts an icon, EXCEPT it's color 0 (black) pixels, onto // | ||
+ | // the screen " | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void Putico(word X, word Y, const byte *sprt, word Where) { | ||
+ | asm { | ||
+ | push ds // save DS | ||
+ | push es // save ES | ||
+ | lds si, [sprt] | ||
+ | mov ax, X // set AX equal to X | ||
+ | mov bx, Y // set BX equal to Y | ||
+ | } | ||
+ | _Redraw: asm { | ||
+ | push ax // save AX (X coordinate) | ||
+ | mov ax, [Where] | ||
+ | mov es, ax // set ES to segment of Where | ||
+ | mov ax, bx // set AX to BX (X) | ||
+ | mov bh, bl // copy BL to BH (multiply Y by 256) | ||
+ | xor bl, bl // zero out BL | ||
+ | shl ax, 6 // multiply AX by 64 (Y * 64) | ||
+ | add bx, ax // add AX to BX (Y*64 + Y*256 = Y*320) | ||
+ | pop | ||
+ | add ax, bx // add BX to AX (Y*320 + X). this gives you | ||
+ | // | ||
+ | mov di, ax // move the offset to DI | ||
+ | mov dl, 30 // set DL to height of sprite | ||
+ | xor ch, ch // zero out CH | ||
+ | mov cl, 48 // set CL to width of sprite | ||
+ | cld // clear direction flag. if you did not do this, | ||
+ | // | ||
+ | push ax // save AX (offset in memory where you draw) | ||
+ | mov ax, cx // set AX to CX (width) | ||
+ | } | ||
+ | _DrawLoop: asm { | ||
+ | push di // save DI (offset in memory where you draw) | ||
+ | mov cx, ax // set CX to AX (width) | ||
+ | } | ||
+ | _LineLoop: asm { // DRAW THE DATA | ||
+ | mov | ||
+ | // load byte of data from sprite to BL | ||
+ | or bl, bl // no effect, but triggers zero flag | ||
+ | jnz | ||
+ | // | ||
+ | // | ||
+ | // | ||
+ | // | ||
+ | } // | ||
+ | |||
+ | _NoPaint: asm { // SKIP OVER COLOR 0 | ||
+ | inc | ||
+ | inc | ||
+ | loop _LineLoop | ||
+ | // | ||
+ | jmp | ||
+ | } | ||
+ | _Store: asm { // COPY THE DATA | ||
+ | movsb // move the byte that DS:SI is pointing to into | ||
+ | // | ||
+ | loop _LineLoop | ||
+ | } // not 0 (end of line) | ||
+ | |||
+ | _NextLine: asm { // START A NEW LINE | ||
+ | pop | ||
+ | dec | ||
+ | jz _Exit // when DL equals 0, you are done drawing the sprite | ||
+ | add di, 320 // if not end of sprite, add 320 to DI so that we | ||
+ | // | ||
+ | jmp | ||
+ | } // line | ||
+ | |||
+ | _Exit: asm { // WE ARE DONE DRAWING THE SPRITE | ||
+ | pop | ||
+ | pop | ||
+ | pop | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // sgn() - This function is used by Line() to determine the sign of a long // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | int sgn (int a) { | ||
+ | |||
+ | if (a > 0) return +1; | ||
+ | if (a < 0) return -1; | ||
+ | return 0; | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // Funny_line() - This function draws a line from a,b, to c,d on screen | ||
+ | // " | ||
+ | // color counter for the next pixel. | ||
+ | // this to be a normal line function, and it will be quite // | ||
+ | // a bit faster than the original one I gave you. This is // | ||
+ | // because I replaced all the floats with integers. | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void Funny_line (int a, int b, int c, int d, word where) { | ||
+ | |||
+ | int i, | ||
+ | |||
+ | count = 50; | ||
+ | u = c - a; // u = x2 - x1 (change in x) | ||
+ | v = d - b; // v = y2 - y1 (change in y) | ||
+ | |||
+ | d1x = sgn(u); | ||
+ | d1y = sgn(v); | ||
+ | |||
+ | d2x = sgn(u); | ||
+ | d2y = 0; // d2y = 0 | ||
+ | m = abs(u); | ||
+ | n = abs(v); | ||
+ | |||
+ | if (m <= n) { | ||
+ | d2x = 0; // d2x = 0 | ||
+ | d2y = sgn(v); | ||
+ | m = abs(v); | ||
+ | n = abs(u); | ||
+ | } | ||
+ | s = m / 2; // s = half of the change in x/y | ||
+ | |||
+ | for (i=0; | ||
+ | Putpixel(a, | ||
+ | count++; | ||
+ | if (count > 100) count = 50; // if color is out of bounds, reset | ||
+ | s += n; | ||
+ | if (s >= m) { | ||
+ | s -= m; | ||
+ | a += d1x; | ||
+ | b += d1y; | ||
+ | } | ||
+ | else { | ||
+ | a += d2x; | ||
+ | b += d2y; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // SetUpScreen() - This procedure sets up the static background to be used // | ||
+ | // in the program. | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void SetUpScreen() { | ||
+ | |||
+ | int x, | ||
+ | const byte circ[5][5] = {{ 0,10,10,10, 0}, | ||
+ | | ||
+ | | ||
+ | | ||
+ | { 0,10,10,10, 0}}; | ||
+ | |||
+ | // set the pallette for the toasters and some other things | ||
+ | Pal (1 ,22,22,22); | ||
+ | Pal (2 ,45,45,45); | ||
+ | Pal (3 ,59,59,59); | ||
+ | Pal (4 ,63,63,27); | ||
+ | Pal (5 ,39,63, 3); | ||
+ | Pal (6 ,51,39, 3); | ||
+ | Pal (7 , 3,27, 3); | ||
+ | Pal (8 ,15,39,15); | ||
+ | Pal (9 ,35,35,35); | ||
+ | Pal (10, 0, 0,40); | ||
+ | Pal (11, | ||
+ | Pal (12, | ||
+ | Pal (13, | ||
+ | |||
+ | // set pallette colors 50-100 to blue values between 13 and 63 | ||
+ | for (loop1 = 50; loop1 < 101; loop1++) | ||
+ | Pal (loop1, | ||
+ | |||
+ | // put a copy of the pallette into ourpal[] | ||
+ | for (loop1 = 0; loop1 < 256; loop1++) | ||
+ | GetPal (loop1, | ||
+ | |||
+ | // draw funny lines | ||
+ | for (loop1 = 0; loop1 < 320; loop1++) | ||
+ | Funny_line (0, | ||
+ | for (loop1 = 0; loop1 < 200; loop1++) | ||
+ | Funny_line (0, | ||
+ | |||
+ | // draw circles | ||
+ | for (loop1 = 0; loop1 < 200; loop1++) { | ||
+ | x = random (315); | ||
+ | y = random (195); | ||
+ | for (loop2 = 0; loop2 < 5; loop2++) | ||
+ | for (loop3 = 0; loop3 < 5; loop3++) | ||
+ | // don't plot a pixel if its color is 0 | ||
+ | if (circ[loop2][loop3] != 0) | ||
+ | Putpixel(x+loop2, | ||
+ | } | ||
+ | |||
+ | // Copy the entire screen at Vaddr1, our virtual screen on which we have | ||
+ | // done all our graphics, onto the screen you see, VGA. | ||
+ | Flip (Vaddr1, | ||
+ | // also make a copy of the virtual screen to Vaddr2 | ||
+ | Flip (Vaddr1, | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // Rotatepal() - This function rotates the colors between 50 and 100. // | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void Rotatepal() { | ||
+ | |||
+ | byte temp[3]; | ||
+ | int loop1; | ||
+ | |||
+ | memmove(temp, | ||
+ | memmove(ourpal[51], | ||
+ | memmove(ourpal[50], | ||
+ | for (loop1 = 50; loop1 < 101; loop1++) | ||
+ | Pal (loop1, | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // ScreenTrans() - This is a small function to copy a 30x30 pixel block // | ||
+ | // from coordinates x,y on the Vaddr1 to // | ||
+ | // | ||
+ | // // | ||
+ | // ERROR, from Vaddr1 to Vaddr2 | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void ScreenTrans (word x, word y) { | ||
+ | asm { | ||
+ | push ds // save DS | ||
+ | push es // save ES | ||
+ | mov | ||
+ | mov | ||
+ | mov | ||
+ | mov | ||
+ | mov | ||
+ | mov | ||
+ | push bx // save x coordinate | ||
+ | mov bx, dx // copy y coordinate to BX | ||
+ | mov dh, dl // multiply y*256 | ||
+ | xor dl, dl // zero out DL | ||
+ | shl bx, 6 // multiply y*64 | ||
+ | add dx, bx // add y*64 to y*256 to get y*320 | ||
+ | pop | ||
+ | add bx, dx // finalize the location | ||
+ | mov di, bx // set DI to offset of Virtual Screen 1 | ||
+ | mov si, di // set SI to offset of Virtual Screen 2 | ||
+ | mov | ||
+ | mov bx, 30 // set BX to height of block | ||
+ | } | ||
+ | _loop1: asm { | ||
+ | mov cx, 24 // set CX to width of block divided by 2 | ||
+ | rep | ||
+ | // | ||
+ | add | ||
+ | add | ||
+ | dec | ||
+ | jnz | ||
+ | pop | ||
+ | pop | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // NewToaster() - This adds a new toaster to the screen. | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void NewToaster() { | ||
+ | |||
+ | int loop1 = 0; | ||
+ | |||
+ | do { | ||
+ | if (toaster[loop1].active == FALSE) { | ||
+ | toaster[loop1].x = random(200)+70; | ||
+ | toaster[loop1].y = 0; | ||
+ | toaster[loop1].active = TRUE; | ||
+ | toaster[loop1].frame = 1; | ||
+ | toaster[loop1].speed = random(3)+1; | ||
+ | loop1 = 10; | ||
+ | } | ||
+ | loop1++; | ||
+ | } while (loop1 < NUMTOASTERS); | ||
+ | |||
+ | } | ||
+ | |||
+ | |||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | // // | ||
+ | // Fly() - This is the function where we move and put the toasters. | ||
+ | // // | ||
+ | ///////////////////////////////////////////////////////////////////////////// | ||
+ | |||
+ | void Fly() { | ||
+ | |||
+ | int loop1, | ||
+ | char ch; | ||
+ | |||
+ | for (loop1 = 0; loop1 < NUMTOASTERS; | ||
+ | toaster[loop1].active = FALSE; | ||
+ | |||
+ | ch = ' | ||
+ | NewToaster(); | ||
+ | |||
+ | do { | ||
+ | // if a key is pressed... | ||
+ | |||
+ | if (kbhit()) { | ||
+ | ch = getch(); | ||
+ | // if ' | ||
+ | if (ch == ' | ||
+ | // if ' | ||
+ | if (ch == ' | ||
+ | loop1 = 0; // start with toaster 0 | ||
+ | do { | ||
+ | // if the loop1 toaster is active | ||
+ | if (toaster[loop1].active == TRUE) { | ||
+ | // draw the toaster on the screen | ||
+ | ScreenTrans(toaster[loop1].x, | ||
+ | // then make it false | ||
+ | toaster[loop1].active = FALSE; | ||
+ | // break out of the loop | ||
+ | loop1 = 10; | ||
+ | } | ||
+ | // check the next toaster | ||
+ | loop1++; | ||
+ | } while (loop1 < NUMTOASTERS); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // if no key was pressed... | ||
+ | |||
+ | for (loop1 = 0; loop1 < NUMTOASTERS; | ||
+ | if (toaster[loop1].active == TRUE) { | ||
+ | // Restore the background the toaster was over | ||
+ | ScreenTrans(toaster[loop1].x, | ||
+ | // Move the toaster | ||
+ | toaster[loop1].x -= toaster[loop1].speed; | ||
+ | toaster[loop1].y += toaster[loop1].speed; | ||
+ | // When toaster reaches the edge of the screen, render it inactive | ||
+ | // and bring a new one into existance. | ||
+ | if ((toaster[loop1].x < 0) || (toaster[loop1].y > 170)) { | ||
+ | toaster[loop1].active = FALSE; | ||
+ | NewToaster(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // Draw all of the toasters | ||
+ | for (loop1 = 0; loop1 < NUMTOASTERS; | ||
+ | // ... but only if they are active | ||
+ | if (toaster[loop1].active == TRUE) | ||
+ | switch (toaster[loop1].frame) { | ||
+ | case 1: Putico(toaster[loop1].x, | ||
+ | case 2: Putico(toaster[loop1].x, | ||
+ | case 3: Putico(toaster[loop1].x, | ||
+ | case 4: Putico(toaster[loop1].x, | ||
+ | } | ||
+ | // increment the current frame of the toaster | ||
+ | toaster[loop1].frame += 1; | ||
+ | // reset the frame if it gets to 5 | ||
+ | if (toaster[loop1].frame == 5) toaster[loop1].frame = 1; | ||
+ | } | ||
+ | |||
+ | WaitRetrace(); | ||
+ | Flip(Vaddr1, | ||
+ | Rotatepal(); | ||
+ | |||
+ | // if the key pressed above was 0 (escape key) then read the escape code | ||
+ | if (ch == 0) ch = getch(); | ||
+ | |||
+ | } while (ch != 27); // if the escape code was 27 (escape key) then exit | ||
+ | |||
+ | } | ||
+ | </ | ||
<nspages back2root/ | <nspages back2root/ | ||