PDA

View Full Version : GraphicMotor without OpenGl and DirectX



Lalli
17-03-2008, 07:31 PM
Greetings Everyone.
Me and my friend here in Hungary are trying to make a game in TURBO pascal and assembly. The game would run in REAL mode and would use VESA resolutions 15 or 16 bit depth. But the problem is that we would NOT like to use Direct-X or OpenGL, we would like to make our own engine. I started to make the motor which enables us the use of basic functions and procedures like Putpixel, Line, Doublebuffering and so on. I have one trouble with it that I cannot use all the functions of VESA. I have an Ati Radeon 9600 XT videocard and my friend has an Nvidia Geforce ( do not know which version ) card and some VESA features are enabled on my card ( 4f07h function of int 10h ), which are disabled for his videocard. Or it is the opposite thing for 4f06h. I would like some help on how to make a simple graphic motorwhich works in both videocards.
( the main trouble is half of the VESA functions are not aviable in each others videocard, so we cannot make a code which puts a pixel on every type of videocards )
Thanks in advance for any comments.

?údv??zlet Mindenkinek!
?ân ?©s a bar?°tom egy saj?°t VAL?ìS m??d?? VESA 15-16 bites grafikai felbont?°sokat kezelni tud?? kis grafikai motort ??rn?°nk- azt?°n azzal egy saj?°t j?°t?©kot. A Direct-X et ?©s OpenGL-t nem haszn?°ln?°nk, Turbo Pascalban ?©s Assemblyben ??rn?°nk a motort. A probl?©ma az, hogy a nem mindegyik videok?°rty?°n m?ªk??dik a programunk. Pl a VESA 4f07 elj?°r?°sa ( int 10h ) az ?©n Ati Radeon 9600XT k?°rty?°mon meg, az ?µ Geforce k?°rty?°j?°n meg nem t?°mogatott. Ez a 4f06h-n?°l pl meg pont ford??tva. Ja ?©s n?°la 800*600-n?°l nagyobb felbont?°st nem is tud aktiv?°lni, pedig engedn?© az 1600*1280-t is. A motorba eredetileg egy putpixelt egy line elj?°r?°st ?©s k?©pmem??ri?°n bel?ºli ozg?°st tervezt?ºnk, de ha nekem m?ªk??dik, akkor neki nem. Ha valaki tud erre valami megold?°st, akkor az k?©rem jelezze nekem.
( sz??val a probl?©ma az, hogy m?©g egy pontot se tudunk kirakni, mert a szabv?°ny megengedi, hogy ne mindegyik funkci?? legyen t?°mogatott )
K??sz??net mindenkinek el?µre a hozz?°sz??l?°sok?©rt.

waran
17-03-2008, 08:16 PM
You are not trying this on any NTish Windows (NT, 2k, XP, 2003, Vista), are you?

cronodragon
17-03-2008, 08:42 PM
I would like some help on how to make a simple graphic motorwhich works in both videocards.

http://www.vesa.org/public/VBE/vbe3.pdf

Check page 17 of that document, it tell's you how to detect which functions are supported. :)

JSoftware
17-03-2008, 08:46 PM
Crono, vbe3 is not good to use as it still is almost unsupported on many newer cards even of the new generations.

Are you sure you know what you are doing. According to Ralf Brown's interrupt list, function 4f06 is get/set logical scanline length and 4f07 is also something with scanlines. Sounds rather funky to me. Are you sure this is what you want. Those commands should be well supported either way as they are part of the VBE 1.1 specification.

Try to show us some code

arthurprs
17-03-2008, 09:25 PM
maybe you can use http://math.ubbcluj.ro/~sberinde/wingraph/

JSoftware
17-03-2008, 10:45 PM
maybe you can use http://math.ubbcluj.ro/~sberinde/wingraph/

He states that he's using realmode, aka 286, 16bit mode

arthurprs
18-03-2008, 02:19 AM
maybe you can use http://math.ubbcluj.ro/~sberinde/wingraph/

He states that he's using realmode, aka 286, 16bit mode

uhm, whats that :oops: ?

cronodragon
18-03-2008, 03:54 AM
Crono, vbe3 is not good to use as it still is almost unsupported on many newer cards even of the new generations.

That function support result is compatible with each version of VESA SVGA. Take a look at this documentation from 1991:



Super VGA BIOS Extension
Standard #VS911022
October 22, 1991
Document Version 1.0
VBE Version 1.2

...

6.1 Status Information

Every function returns status information in the AX register. The format of the status word is as follows:

AL == 4Fh: Function is supported
Al != 4Fh: Function is not supported
AH == 00h: Function call successful
AH == 01h: Function call failed


If it helps I wrote a SVBE unit in Turbo Pascal back in the 90's, it's mostly in assembler:

http://www.geocities.com/todo_simple.geo/programas/usvbe.zip




maybe you can use http://math.ubbcluj.ro/~sberinde/wingraph/

He states that he's using realmode, aka 286, 16bit mode

uhm, whats that :oops: ?

Real mode is the memory addressing mode used in DOS. The memory was segmented, and segments overlaped, it was a headache. Fortunately today we have another mode called flat mode, where memory is continuous.

Lalli
20-03-2008, 11:27 PM
First of all, thanks for all the replies.
Hell yeah. We are trying to make this on XP, but we tried it in dos too, but its the same.
The main problem is that on my friends videocard ( nvidia geforce 6800 ) we cannot put even a pixel out in higher VESA resolutions than 640*480.
The simplest code we tried was this and it did not work of course ( on his pc ):

asm
mov ax,4f02h
mov bx,11bh
int 10h
mov ax,0a000h
mov es,ax
mov cx,32768
xor di,di
mov ax,0ffffh
rep stosw
end;

But it still does not work. He has a blind screen.
--------
But my other problem is that the way cronodragon mentioned is a bit slow. Gonna post the unit in the next post.

Lalli
20-03-2008, 11:27 PM
First of all, thanks for all the replies.
Hell yeah. We are trying to make this on XP, but we tried it in dos too, but its the same.
The main problem is that on my friends videocard ( nvidia geforce 6800 ) we cannot put even a pixel out in higher VESA resolutions than 640*480.
The simplest code we tried was this and it did not work of course ( on his pc ):

asm
mov ax,4f02h
mov bx,11bh
int 10h
mov ax,0a000h
mov es,ax
mov cx,32768
xor di,di
mov ax,0ffffh
rep stosw
end;

But it still does not work. He has a blind screen.
--------
But my other problem is that the way cronodragon mentioned is a bit slow. Gonna post the unit in the next post.

Lalli
20-03-2008, 11:30 PM
First of all, thanks for all the replies.
Hell yeah. We are trying to make this on XP, but we tried it in dos too, but its the same.
The main problem is that on my friends videocard ( nvidia geforce 6800 ) we cannot put even a pixel out in higher VESA resolutions than 640*480.
The simplest code we tried was this and it did not work of course ( on his pc ):


asm
mov ax,4f02h
mov bx,11bh
int 10h
mov ax,0a000h
mov es,ax
mov cx,32768
xor di,di
mov ax,0ffffh
rep stosw
end;

But it still does not work. He has a blind screen.
--------
But my other problem is that the way cronodragon mentioned is a bit slow. I made a unit the same way, gonna post it in my next post...

Lalli
20-03-2008, 11:32 PM
Woops, sorry for the 3 same posts, but the site said that general error with sending message ( ?°ltal?°nos hiba - hungarian ver. )
So here is the unit:
unit Vesa2eng;

interface

{Detects all the resolutions which are 1024 wide and have 15/16 bit/pixel}
Procedure Init;

{Shifts the screens A and B}
{if you display the A screen, then you render on the B screen, then you
need to shift to display B and render on A}
Procedure Shift;

{This is a simple clearscreen func, c is the color you wish to clear with}
Procedure Clear(c:word);

{I think I do not have to comment this}
procedure Putpixel(X,Y,Color:word);

{A simple line procedure based on the putpixel above}
Procedure Line(x1,y1,x2,y2:integer;color:word);

{it mixes the tree color parts into a 16 bit number}
Function RGB(r,g,b:byte):word;

{it puts out a w width h height picture from the memory to (x,y)}
procedure Putimage(x,y,w,h:integer;src:pointer);

{its the same as putimage, but you can set a transparent color too}
procedure PutimageT(x,y,w,h:integer;src:pointer;transp:word) ;

{its a simple getimage, the reversed version of putimage}
procedure getimage(x,y,w,h:integer;src:pointer);assembler;

implementation

type PModes = ^TModes;
TModes = array[0..8191] of word;
PVesainfo = ^TVesainfo;
TVesainfo = record
sign : array[0..3] of char; { 'VESA' }
version : word; { Version stored in a BCD format }
oemname : pchar; { pointer to the name of the card }
res : longint; { reserved }
modes : PModes; { pointer to the list of resolutions }
res2 : array[0..237] of byte; { reserved }
end;
PModeinfo = ^TModeinfo;
TModeinfo = record
attr : word; {a m¢d attrib£tumai}
aattr : byte; {az A ablak attrib£tumai}
battr : byte; {a B ablak attrib£tumai}
lapoz : word; {legkisebb lapoz¬†si egys‚g kB-ban}
winsize : word; {ablak m‚rete kB-ban}
sega : word; {az A ablak szegmensc¬?me}
segb : word; {a B ablak szegmensc¬?me}
winproc : procedure; {ablakkezel” rutin cime $4f05}
logszel : word; {k‚p logikai sz‚less‚ge byteokban}
w : word;{a k‚p sz‚less‚ge pixel/karakterben}
h : word; {a k‚p magass¬†ga pixel/karakterben}
charx : byte; {a bet¬Å sz‚less‚ge karakterben}
chary : byte; {a bet magass ga karakterben}
bitpl : byte; {a bitplane-ek sz ma}
bitpix : byte; {egy pixelhez tartoz¢ bitek sz ma}
banknum : byte; {a m¢dban haszn lt bankok sz ma}
memtip : byte; {a m¢d mem¢ria modellje}
bmeret : byte; {egy bank m‚rete kB-ban}
lapnum : byte; {a m¢dban haszn lhat¢ lapok sz ma}
res : byte; {fenntartva}
{------------------- VESA 1.2 --------------------}
rmaszk : byte; {h ny bitnyi piros van}
rpos : byte; {honnan kezd”dik a piros}
gmaszk : byte; {h¬†ny bitnyi z”ld van}
gpos : byte; {honnan kezd”dik a z”ld}
bmaszk : byte; {h¬†ny bitnyi k‚k van}
bpos : byte; {honnan kezd”dik a k‚k}
resmaszk: byte; {fenntartott 'szin' m‚rete}
respos : byte;{fenntartott 'szin' honnan kezd”dik}
DACinfo : byte; {direct DAC m¢d inform ci¢k}
res2 : array[0..214] of byte; {fenntartva}
end;

var BankNr : array[0..47] of word;
Bank : word;
Vesainfo : Tvesainfo;
Modeinfo : Tmodeinfo;
eltol : word; {this variable stores the amount of lines which
makes an offset in the videomemory}

procedure Bankfunc;far; assembler;
asm
mov ax,4F05h
xor bx,bx
push dx
int 10h
pop dx
mov ax,4F05h
mov bx,1
int 10h
end;

procedure SetBank(B:word);assembler;
asm
pusha
lea bx,BankNR
mov di,B
mov Bank,di
shl di,1
mov dx,[bx+di]
call BankFunc
popa
end;

procedure SetBankNR;assembler;
asm
pusha
lea bx,BankNR
mov di,dx
mov Bank,di
shl di,1
mov dx,[bx+di]
call BankFunc
popa
end;

{Checks if there is a VBE present - if true, then it sets the VesaInfo record}
Function Vanevesa(var VI:tvesainfo):boolean;assembler;
asm
mov ax,4f00h
les di,VI
int 10h
cmp al,$4f
mov al,0
jne @vege
inc al
@vege:
end;

{Checks if the current videomode(mode) exits - if so then it sets Modeinfo}
Function Letezike(mode:word;var MI:tmodeinfo):boolean;assembler;
asm
mov ax,4f01h
mov cx,mode
les di,MI
int 10h
cmp al,$4f
mov al,0
jne @vege
inc al
@vege:
end;

{This sets the mode videomode}
Procedure Beallit(mode:word);assembler;
asm
mov ax,4f02h
mov bx,mode
int 10h
end;

{displays the videomemory from line iy}
Procedure Display(iy:word);assembler;
asm
mov ax,4f07h
mov bl,0
xor cx,cx
mov dx,iy
int 10h
end;

Procedure Init;
var gr:word;
i:integer;
okmod:array[0..99] of word; {the modes which are useful for us}
modok:shortint;
begin
If not Vanevesa(vesainfo)
then begin
Writeln('Not VESA compatible videocard. Program terminated. Have a nice day.');
halt;
end;
modok:=0;
for i:=0 to 99 do
okmod[i]:=0;
i:=0;
while vesainfo.modes^[i]<>$ffff do
begin
if letezike(vesainfo.modes^[i],Modeinfo) and (modeinfo.w=1024) and (modeinfo.h=768)
and ((modeinfo.bitpix=15) or (modeinfo.bitpix=16))
then begin
okmod[modok]:=vesainfo.modes^[i];
inc(modok);
end;
inc(i);
end;
dec(modok);
if modok=-1 then begin
Writeln('No 1024*768 resolutions found, which are 15 or 16 bit/pixel.');
halt;
end;
i:=-1;
repeat
inc(i);
letezike(okmod[i],modeinfo);
until (modeinfo.bitpix=16) or (i=modok);
if modeinfo.bitpix<>16 then begin
i:=-1;
repeat
inc(i);
letezike(okmod[i],modeinfo);
until (modeinfo.bitpix=15) or (i=modok);
if modeinfo.bitpix<>15 then begin
Writeln('Ok, I was wrong, there are no 1024*768 resolutions anyhow which are 15 or 16 bit/pixel.');
halt;
end;
end;
beallit(okmod[i]);
Gr:=(1024*longint(Modeinfo.Winsize)) div (1024*longint(Modeinfo.lapoz));
for i:=0 to 47 do
BankNr[i]:=i*Gr;
for i:=0 to 47 do
begin
SetBank(i);
asm
mov ax,0a000h
mov es,ax
xor di,di
mov cx,16384
db 66h
xor ax,ax
rep
db 66h
stosw
end;
end;
SetBank(0);
eltol:=0;
display(768);
end;

Procedure Shift;
begin
if eltol=0 then begin
eltol:=24;
display(0);
end
else begin
eltol:=0;
display(768);
end;
end;

Procedure Clear(c:word);
var i:word;
begin
for i:=eltol to 23+eltol do {clears only the memory which we render to}
begin
asm
mov dx,i
call setbanknr
mov ax,0a000h
mov es,ax
xor di,di
mov cx,16384
mov ax,c
push ax
db 66h
shl ax,16
pop ax
rep
db 66h
stosw
end;
end;
end;

procedure Putpixel(X,Y,Color:word);assembler;
asm
mov di,Y
cmp di,0
jl @vege
cmp di,768
jnl @vege
mov di,X
cmp di,0
jl @vege
cmp di,1024
jnl @vege
shl di,1
mov ax,1024
shl ax,1
mul Y
add di,ax
adc dx,eltol
cmp dx,Bank
jz @x
call SetBankNR
@x:
mov ax,0a000h
mov ES,ax
mov ax,Color
stosw
@vege:
end;

Procedure Line(x1,y1,x2,y2:integer;color:word);
var dx,dy:integer;
m,n:shortint;
i,j:integer;
begin
dx:=abs(x2-x1);
dy:=abs(y2-y1);
putpixel(x1,y1,color);
if (dx<>0) or (dy<>0) then
begin
if x1<x2 then m:=1 else m:=-1;
if y1<y2>dy then
begin
i:=dx shr 1;
for j:=1 to dx do
begin
asm
mov ax,dy
add i,ax
end;
if dx<=i then
begin
dec(i,dx);
inc(y1,n);
end;
inc(x1,m);
Putpixel(x1,y1,color);
end;
end
else
begin
i:=dy shr 1;
for j:=1 to dy do
begin
inc(i,dx);
if dy<=i then
begin
dec(i,dy);
inc(x1,m);
end;
inc(y1,n);
Putpixel(x1,y1,color);
end;
end;
end;
end;

Function RGB(r,g,b:byte):word;
begin
if Modeinfo.bitpix=16
then RGB:=((r shl 6) + (g shl 1)) shl 5 + b
else RGB:=((r shl 5) + g) shl 5 + b;
end;

procedure putimage(x,y,w,h:integer;src:pointer);assembler;
var i:word;
asm
mov ax,0a000h
mov ES,ax
mov i,0
mov cx,h
@lines:
push cx
push x
mov cx,w
@pixels:
mov di,Y
cmp di,0
jl @kihagy
cmp di,768
jnl @kihagy
mov di,X
cmp di,0
jl @kihagy
cmp di,1024
jnl @kihagy
shl di,1
mov ax,2048
mul y
add di,ax
adc dx,eltol
call SetBankNR
push ds
lds si,src
add si,i
movsw
pop ds
@kihagy:
inc x
add i,2
loop @pixels
pop x
pop cx
inc y
loop @lines
end;

procedure putimaget(x,y,w,h:integer;src:pointer;transp:word) ;assembler;
var i:word;
asm
mov ax,0a000h
mov ES,ax
mov i,0
mov cx,h
@lines:
push cx
push x
mov cx,w
@pixels:
mov di,Y
cmp di,0
jl @kihagy
cmp di,768
jnl @kihagy
mov di,X
cmp di,0
jl @kihagy
cmp di,1024
jnl @kihagy
shl di,1
mov ax,2048
mul y
add di,ax
adc dx,eltol
call SetBankNR
push ds
lds si,src
add si,i
lodsw
pop ds
cmp ax,transp
jz @kihagy
mov ES:[di],ax
@kihagy:
inc x
add i,2
loop @pixels
pop x
pop cx
inc y
loop @lines
end;

procedure getimage(x,y,w,h:integer;src:pointer);assembler;
var i:word;
asm
mov ax,0a000h
mov ES,ax
mov i,0
mov cx,h
@lines:
push cx
push x
mov cx,w
@pixels:
mov di,X
shl di,1
mov ax,2048
mul y
add di,ax
adc dx,eltol
call SetBankNR
push ds
lds si,src
add si,i
mov ax,ES:[di]
mov DS:[si],ax
pop ds
inc x
add i,2
loop @pixels
pop x
pop cx
inc y
loop @lines
end;

end.

Lalli
20-03-2008, 11:47 PM
But the question is why doesn't that little code or any bigger code work at my friends pc or on integrated videocards, or on Nvidia cards. Windows can set a lot of resolutions on each of the videocards, but we cannot even put a pixel?
And if he goes to the desktop and looks at the display properties he can see, the Videocard is built in WITH a tvtuner card and it says for name: Winfast a400.