home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Hack-Phreak Scene Programs
/
cleanhpvac.zip
/
cleanhpvac
/
TUT10NEW.ZIP
/
TUT10.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-02
|
15KB
|
391 lines
/////////////////////////////////////////////////////////////////////////////
// //
// TUTPROG10.CPP - VGA Trainer Program 10 (in Turbo C++ 3.0) //
// //
// "The VGA Trainer Program" was originally written by Denthor of //
// Asphyxia. It contained some nice pascal source and documentation. But //
// then Snowman came along. He saw disorder, he saw inefficiency, he //
// saw PASCAL. Denthor couldn't stop Snowman, so Snowman went on to //
// convert tha pascal source to C++. ...and the people were happy. //
// //
// Program Notes : This program presents the basics of Chain-4. //
// //
// Just for reference, this is the command line I use: //
// //
// tcc -mc -a -G -2 -O tut10.cpp //
// //
// The way things are set up, there is no need to compile //
// or link tut10.cpp and gfx2.cpp seperately. //
// //
// Author : Grant Smith (Denthor) - denthor@beastie.cs.und.ac.za //
// Translator : Christopher G. Mann - r3cgm@dax.cc.uakron.edu //
// //
// Last Modified : February 1, 1995 //
// //
/////////////////////////////////////////////////////////////////////////////
// //
// INCLUDE FILES //
// //
#include <conio.h>
// clrscr(), getch(), kbhit()
#include <iostream.h>
// cout
#include <stdlib.h>
// rand()
#include "gfx2.cpp"
// SetText(), WaitRetrace(), Pal::
// //
// TYPEDEFS //
// //
// unsigned chars are sissy
typedef unsigned char byte;
typedef unsigned int word;
// //
// CONSTANTS //
// //
const byte BIT[897] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,33,2,151,5,149,6,148,7,147,8,49,2,
95,8,49,4,93,9,49,3,93,4,2,3,49,4,92,4,3,3,48,4,92,4,3,4,48,4,91,4,4,
3,48,4,92,4,3,4,48,3,58,2,32,4,4,4,47,4,57,3,31,4,5,3,48,3,57,4,30,4,
5,4,47,3,57,5,29,4,6,4,46,4,57,4,29,4,7,3,47,3,58,2,30,4,7,4,46,4,90,
4,7,4,46,3,90,4,8,4,27,2,16,3,90,4,8,9,22,3,16,3,89,4,5,13,8,6,8,3,15,
3,90,4,2,15,6,10,6,3,16,3,6,1,21,1,9,2,7,1,21,6,14,18,9,5,2,4,5,4,1,4,
10,3,4,5,10,2,7,3,8,2,5,3,9,3,7,8,13,13,1,4,9,4,5,3,5,3,1,6,9,3,3,6,9,
4,5,4,8,3,3,4,9,3,6,9,11,10,6,4,8,4,6,3,4,11,8,3,2,7,9,5,4,4,9,3,2,4,
9,3,6,4,4,2,8,10,9,4,7,4,6,3,5,5,3,3,8,3,1,8,8,5,4,5,8,3,3,3,9,4,5,4,
5,2,5,10,12,4,7,3,5,5,4,5,4,3,7,3,1,4,1,3,9,4,5,4,9,3,2,3,10,3,6,3,5,
3,4,10,13,3,8,3,2,7,5,4,5,3,7,7,1,3,9,4,5,5,9,3,1,3,10,3,6,3,5,4,4,5,
1,4,12,4,8,3,2,5,6,4,5,4,6,6,2,4,8,4,5,5,10,6,10,4,5,4,5,3,5,2,3,4,13,
4,8,3,3,1,9,3,6,3,7,5,3,3,5,1,3,3,5,5,4,2,5,5,11,3,6,3,5,4,10,3,14,4,
8,3,12,3,6,4,6,5,3,3,5,2,2,4,4,6,4,2,5,5,6,1,3,4,5,3,6,3,10,4,14,4,5,
1,2,4,11,3,6,3,7,5,3,3,4,3,1,4,4,6,4,3,5,4,6,2,3,3,6,3,5,4,9,4,15,3,5,
2,3,4,9,3,6,4,7,4,3,3,5,2,2,3,4,7,3,3,6,3,6,3,2,4,5,4,5,3,10,3,15,4,4,
3,4,3,9,3,6,3,7,4,4,3,4,3,1,4,3,3,1,3,3,3,6,4,6,2,3,3,6,3,5,4,9,4,15,
4,4,3,4,4,7,3,6,4,7,4,3,3,4,3,2,3,3,3,2,3,2,4,5,5,5,3,2,4,6,3,5,4,8,4,
16,4,4,2,6,3,7,3,5,4,7,4,4,3,3,3,3,8,2,3,2,4,5,6,4,3,3,3,7,3,4,5,8,4,
16,4,4,2,6,3,6,3,5,4,8,3,5,8,3,9,2,3,1,4,6,6,3,3,4,3,7,3,3,6,7,4,17,4,
4,3,5,3,6,3,4,4,9,3,5,8,3,7,3,8,6,3,1,4,1,4,3,4,7,3,2,3,1,3,7,4,17,4,
4,3,5,3,5,11,9,3,6,7,4,6,4,7,6,3,2,8,4,3,8,7,2,3,6,4,18,3,5,4,3,4,5,
10,10,3,6,6,6,4,4,6,7,3,4,6,5,3,8,7,2,4,4,4,19,3,5,10,5,3,1,6,11,3,7,
3,16,5,7,4,4,5,6,3,8,6,3,5,3,4,19,3,6,9,5,3,18,2,25,5,9,3,6,3,7,2,10,
3,6,4,3,3,20,3,8,5,6,3,44,6,10,2,39,3,3,2,22,2,19,3,43,7,101,3,42,8,
102,3,41,4,1,4,101,4,39,5,2,3,102,3,39,4,4,3,102,3,38,4,4,4,101,3,38,
4,5,3,102,3,37,4,5,4,101,4,36,4,6,3,102,3,37,3,6,4,102,3,36,4,6,3,102,
3,37,3,6,3,103,3,37,3,5,4,102,4,37,3,4,4,103,3,38,10,104,3,38,9,105,2,
40,7,106,2,41,4,0};
// //
// FUNCTION PROTOTYPES //
// //
void InitChain4();
void C4PutPixel(word X, word Y, byte Col);
void Plane (byte Which);
void MoveTo (word X, word Y);
void Putpic (int x, int y);
void Play ();
// //
// GLOBAL VARIABLES //
// //
// Just for fun, change this to "const byte SIZE = 80" and try to run
// the program. It is generally a good programming practice to use
// contant variables when you know that the values should not change.
// However, this program uses lots of assembler. I guess that a constant
// byte is stored differently than just a normal byte. Go figure! :)
byte SIZE = 80; // Size = 40 = 1 across, 4 down
// Size = 80 = 2 across, 2 down
// Size = 160 = 4 across, 1 down
///////////////////////////////////////////////////////////////////////////////
// //
// MAIN FUNCTION //
// //
///////////////////////////////////////////////////////////////////////////////
void main() {
clrscr();
cout
<< "Hello there! Here is the tenth tutorial, on Chain-4! You will notice\n"
<< "that there are two files here : one contains all of our graphics\n"
<< "based routines, and one is the demo program.\n\n"
<< "In the demo program, we will do the necessary port stuff to get into\n"
<< "Chain-4. Once in Chain-4 mode, I will put down text saying ASPHYXIA\n"
<< "over the entire screen. After a key is pressed, the viewport will\n"
<< "bounce around, displaying the entire Chain-4 screen. The program will\n"
<< "end when [ESC] is pressed. The code here is really basic (except for\n"
<< "those port values), and should be very easy to understand.\n\n";
cout
<< "Yo, Snowman here. Frankly I'm tired of just converting these\n"
<< "bloody tutorials! :) I am going to start doing some ""creative""\n"
<< "things in these programs. The first deviant thing I'm doing is\n"
<< "flipping Denthor's snazzy logo so that <Asphyxia> is reversed.\n"
<< "Hey, we all got to break out and have fun sometime, right? :)\n\n";
cout << "Hit any key to continue ...";
getch();
InitChain4();
Play();
SetText();
cout
<< "All done. This concludes the tenth sample program in the ASPHYXIA\n"
<< "Training series. You may reach DENTHOR under the names of GRANT\n"
<< "SMITH/DENTHOR/ASPHYXIA on the ASPHYXIA BBS. I am also an avid\n"
<< "Connectix BBS user, and occasionally read RSAProg. E-mail me at :\n"
<< " smith9@batis.bis.und.ac.za\n"
<< "The numbers are available in the main text. You may also write to me at:\n"
<< " Grant Smith\n"
<< " P.O. Box 270\n"
<< " Kloof\n"
<< " 3640\n"
<< " Natal\n"
<< " South Africa\n"
<< "I hope to hear from you soon!\n\n";
cout << "Hit any key to exit ...";
getch();
}
/////////////////////////////////////////////////////////////////////////////
// //
// InitChain4() - This function gets you into Chain 4 mode. //
// Note: As soon as I find documentation, this function //
// will be better documented. - Snowman //
// //
/////////////////////////////////////////////////////////////////////////////
void InitChain4() {
asm {
mov ax, 0x13 // routine 13 = MCGA mode
int 0x10 // do it!
mov dx, 0x3C4 // Port 0x3C4 = Sequencer Address Register
mov al, 4 // Index 4 = memory mode
out dx, al // send it
inc dx // Port 0x3C5 ... here we set the mem mode
in al, dx
and al, not 0x08
or al, 0x04
out dx, al
mov dx, 0x3CE
mov al, 5
out dx, al
inc dx
in al, dx
and al, not 0x10
out dx, al
dec dx
mov al, 6
out dx, al
inc dx
in al, dx
and al, not 0x02
out dx, al
mov dx, 0x3C4
mov ax, (0x0F shl 8) + 2
out dx, ax
mov ax, 0xA000
mov es, ax
sub di, di
mov ax, 0x0000 // 0x8080
mov cx, 32768
cld
rep stosw // Clear garbage off the screen ...
mov dx, 0x3D4
mov al, 0x14
out dx, al
inc dx
in al, dx
and al, not 0x40
out dx, al
dec dx
mov al, 0x17
out dx, al
inc dx
in al, dx
or al, 0x40
out dx, al
mov dx, 0x3D4
mov al, 0x13
out dx, al
inc dx
mov al, [SIZE] // Size * 8 = Pixels across. Only 320 are visible
out dx, al
}
}
/////////////////////////////////////////////////////////////////////////////
// //
// C4PutPixel() - This puts a pixel on the chain 4 screen. //
// Note: As soon as I find documentation, this function //
// will be better documented. - Snowman //
// //
/////////////////////////////////////////////////////////////////////////////
void C4PutPixel(word X, word Y, byte Col) {
asm {
mov ax,[Y]
xor bx,bx
mov bl,[SIZE]
imul bx
shl ax,1
mov bx,ax
mov ax, [X]
mov cx, ax
shr ax, 2
add bx, ax
and cx, 00000011b
mov ah, 1
shl ah, cl
mov dx, 0x3C4 // Sequencer Register
mov al, 2 // Map Mask Index
out dx, ax
mov ax, 0xA000
mov es, ax
mov al, [Col]
mov es: [bx], al
}
}
/////////////////////////////////////////////////////////////////////////////
// //
// Plane() - This sets the plane to write to in Chain 4. //
// Note: As soon as I find documentation, this function //
// will be better documented. - Snowman //
// //
/////////////////////////////////////////////////////////////////////////////
void Plane (byte Which) {
asm {
mov al, 0x2
mov ah, 1
mov cl, [Which]
shl ah, cl
mov dx, 0x3C4 // Sequencer Register
out dx, ax
}
}
/////////////////////////////////////////////////////////////////////////////
// //
// MoveTo() - This moves to position X*4 on a chain 4 screen. //
// Note: As soon as I find documentation, this function //
// will be better documented. - Snowman //
// //
/////////////////////////////////////////////////////////////////////////////
void MoveTo (word X, word Y) {
word O = Y*SIZE*2+X;
asm {
mov bx, [O]
mov ah, bh
mov al, 0x0C
mov dx, 0x3D4
out dx, ax
mov ah, bl
mov al, 0x0D
mov dx, 0x3D4
out dx, ax
}
}
/////////////////////////////////////////////////////////////////////////////
// //
// Putpic() - This puts the picture at coordinates x,y on the chain-4 //
// screen. //
// //
/////////////////////////////////////////////////////////////////////////////
void Putpic (int x, int y) {
int loop1, loop2, cur=0;
word depth = 1;
// for every element of the picture data...
for (loop1=0; loop1<897; loop1++) {
for (loop2=0; loop2<BIT[loop1]; loop2++) {
// read the tut10.txt file for more information on what this does
if (cur != 0)
// take out the "155-" to make the logo face the right direction
C4PutPixel(155-(depth % 155)+x, (depth / 155)+y,(depth / 155));
depth++;
}
cur = (cur+1) % 2;
}
}
/////////////////////////////////////////////////////////////////////////////
// //
// Play() - The function that does it all... //
// //
/////////////////////////////////////////////////////////////////////////////
void Play() {
int loop1, loop2, xpos, ypos, xdir, ydir;
Pal PicPal[64];
char ch = 1;
// This sets up the pallette for the picture
for (loop1=1; loop1<63; loop1++) {
PicPal[loop1].PalSet(loop1,0,62-loop1);
PicPal[loop1].PalPut(loop1);
}
// This moves the view to the top left hand corner
MoveTo(0,0);
// This places the picture all over the chain-4 screen
for (loop1=0; loop1<4; loop1++)
for (loop2=0; loop2<6; loop2++)
Putpic(loop1*160, loop2*66);
getch();
// Random start positions/movements for the view
xpos = (rand() % 78) + 1;
ypos = (rand() % 198) + 1;
xdir = 1;
ydir = 1;
// Main loop (move around the Chain-4 Screen)
do {
if (kbhit()) ch = getch();
MoveTo(xpos, ypos);
// Take this out and watch the screen go crazy!
WaitRetrace();
xpos += xdir;
ypos += ydir;
// Hit a boundry, change direction
if ((xpos > 79) || (xpos < 1)) xdir *= -1;
if ((ypos > 199) || (ypos < 1)) ydir *= -1;
if (ch == 0) ch = getch();
} while (ch != 27); // if the escape code was 27 (escape key) then exit
}