PDA

View Full Version : Simple VGA window - Need help guys, Newbie.



cool-man
09-20-2003, 12:49 PM
#include<stdio.h>

#define WHITE 0xF

void set_mode(unsigned char mode)
{
_asm mov ah,00
_asm mov al,mode
_asm int 10h
}

void pset(long x,long y,unsigned char color)
{
_asm mov ah,0ch
_asm mov al,color
_asm mov edx,x
_asm mov edx,y
_asm int 10h
}


void main(void)
{
set_mode(0x13);
pset(10,10,WHITE);
}


I put this together after looking at the star field program, on the site, how do i get my window to stay put? a loop? i have visual c++ and borland c++ , so any help is helpful :D figures.

VirtualAce
09-20-2003, 04:52 PM
There is another starfield program on this site, I know because I wrote it and posted it somewhere. It is true 3D using a vector3D struct.

Here is some help with your problem. Asm blocks can be placed within braces instead of placing _asm or asm in front of every line.
Here is a small mode 13h VGA unit to get you started




//16 bit typedefs
typedef unsigned char BYTE;
typedef unsigned int WORD;
typedef unsigned long DWORD;

#define FALSE 0
#define TRUE 1
#define XYTOMEM(x,y) ((y<<8)+(y<<6)+x)

struct tagVGA
{
BYTE far *Screen;
BYTE far *Buffer;
BYTE far *Surface;
int BufferMode;
}VGA;

void SetMode(WORD mode);
void Pset(WORD x,WORD y,BYTE color);
void SetBufferMode(WORD newmode=TRUE);
void Flip(void);
void CLS(BYTE color);
void Line(WORD x,WORD y,WORD x2,WORD y2,BYTE color);

void SetMode(WORD mode)
{
asm {
mov ax,[mode]
int 10h
}
VGA.BufferMode=FALSE;
VGA.Screen=(BYTE far*)MK_FP(0xa000,0);
VGA.Buffer=new BYTE[64000L];
VGA.Surface=VGA.Screen;
}

void Pset(WORD x,WORD y,BYTE color)
{
VGA.Surface[XYTOMEM(x,y)]=color;
}


void SetBufferMode(WORD newmode)
{
switch(newmode)
{
case TRUE: VGA.Surface=VGA.Buffer;break;
case FALSE: VGA.Surface=VGA.Screen;break;
default: VGA.Surface=VGA.Screen;break;
}
}

void Flip(void)
{
//Does not check for screen refresh
BYTE far *Screen=VGA.Surface;
BYTE far *Buffer=VGA.Buffer;
asm {
push si
push di
push ds

les di,[Screen]
lds si,[Buffer]
mov cx,07D00h
rep movsw

pop ds
pop di
pop si
}
}

void CLS(BYTE color)
{
BYTE far *Surface=VGA.Surface;
asm {
les di,[Surface]
mov al,[color]
mov ah,[color]
mov cx,07D00h
rep stosb
}
}

void Line(WORD x,WORD y,WORD x2,WORD y2,BYTE color)
{
int eterm=0;
int diffx=x2-x;
int diffy=y2-y;
int yunit=320;
int xunit=1;
WORD offset=XYTOMEM(x,y);
int length=0;

if (diffx<0)
{
xunit=-xunit;
diffx=-diffx;
}
if (diffy<0)
{
yunit=-yunit;
diffy=-diffy;
}

if (diffx>diffy)
{
length=diffx+1;
for (int i=0;i<length;i++)
{
VGA.Surface[offset]=color;
offset+=xunit;
eterm+=diffx;
if (eterm>diffy)
{
eterm-=diffy;
offset+=yunit;
}
}
}
else
{
length=diffy+1;
for (i=0;i<length;i++)
{
VGA.Surface[offset]=color;
offset+=yunit;
eterm+=diffy;
if (eterm>0)
{
eterm-=diffx;
offset+=xunit;
}
}
}
}


If the line drawing algo does not work right then PM me - I coded this from memory and I always mess the line algo up.

Test the lines like this:

//Blue line from top left to center
Line(0,0,160,100,1);

//Red line from top right to center
Line(319,0,160,100,4);

//Green line from bottom left to center
Line(0,199,160,100,2);

//Yellow line from bottom right to center
Line(319,199,160,100,14);

If these lines are not right then the algo is messed up either on the x axis or the y.

Again, PM me if you have any probs.

VirtualAce
09-20-2003, 05:08 PM
Create a library out of the VGA module and then add this for the starfield. Do not add this to the VGA module because you want to be able to re-use the VGA module for other programs.





#include <stdlib.h>

struct point3D
{
double x;
double y;
double z;
};

#define NUMSTARS 200
#define MAXZ 50
#define VIEWDIST 320


point3D Stars[NUMSTARS];

void CreateStars(void);
void MoveStars(double speed);
void DisplayStars(void);

void CreateStars(void)
{
for (int i=0;i<NUMSTARS;i++)
{
Stars[i].x=-random(320)+random(640);
Stars[i].y=-random(200)+random(400);
Stars[i].z=random(MAXZ);
}
}

void MoveStars(double speed)
{
for (int i=0;i<NUMSTARS;i++)
{
double x=Stars[i].x;
double y=Stars[i].y;
double z=Stars[i].z;
z+=speed;
if (z<0 || z>MAXZ)
{
x=-random(320)+random(640);
y=-random(200)+random(400);
z=random(MAXZ);
}
Stars[i].x=x;
Stars[i].y=y;
Stars[i].z=z;
}
}

void DisplayStars(void)
{
for (int i=0;i<NUMSTARS;i++)
{
double x=Stars[i].x;
double y=Stars[i].y;
double z=Stars[i].z;
if (z==0.0) z=1.0;
int screenx=(x*VIEWDIST)/z;
int screeny=(y*VIEWDIST)/z;
if (screenx<0 || screenx>319 || screen y<0 || screeny>199)
{
Stars[i].x=-random(320)+random(640);
Stars[i].y=-random(200)+random(400);
Stars[i].z=random(MAXZ);
}
else VGA.Surface[XYTOMEM(screenx,screeny)]=15;
}
}

int main(void)
{
double shipspeed=2;
SetMode(0x13);
SetBufferMode();
CreateStars();
while (!kbhit())
{
CLS(0);
MoveStars(shipspeed);
DisplayStars();
}
return(0);
}




Again, if you have probs with the code or understanding what it does - PM me or post here.