Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédente | ||
back2root:archives:denthor:part-07 [2021/09/02 11:05] – créée frater | back2root:archives:denthor:part-07 [2021/09/05 14:00] (Version actuelle) – [In Closing] frater | ||
---|---|---|---|
Ligne 360: | Ligne 360: | ||
< | < | ||
There they sit, the preschooler class encircling their mentor, the substitute teacher. | There they sit, the preschooler class encircling their mentor, the substitute teacher. | ||
- | "Now class, today we will talk about what you want to be when you grow up. Isn't that fun?" The teacher looks around and spots the child, silent, apart from the others and deep in thought. " | + | "Now class, today we will talk about what you want to be when you grow up. Isn't that fun?" |
- | Jonny looks around, confused, his train of thought disrupted. He collects himself, and stares at the teacher with a steady eye. "I want to code demos," | + | The teacher looks around and spots the child, silent, apart from the others and deep in thought. " |
+ | Jonny looks around, confused, his train of thought disrupted. He collects himself, and stares at the teacher with a steady eye. | ||
+ | "I want to code demos," | ||
+ | "I want to write something that will change peoples perception of reality. I want them to walk away from the computer dazed, unsure of their footing and eyesight." | ||
+ | "I want to write something that will reach out of the screen and grab them, making heartbeats and breathing slow to almost a halt." | ||
+ | "I want to write something that, when it is finished, they are reluctant to leave, knowing that nothing they experience that day will be quite as real, as insightful, as good. I want to write demos." | ||
Silence. The class and the teacher stare at Jonny, stunned. It is the teachers turn to be confused. Jonny blushes, feeling that something more is required. | Silence. The class and the teacher stare at Jonny, stunned. It is the teachers turn to be confused. Jonny blushes, feeling that something more is required. | ||
Ligne 389: | 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/ | ||