Skip to main content
GameDev.net gamedev.net
🔒 Locked

Please help!

Started by pacman2003 Apr 27, 2003 at 1:00 AM 27 replies 2.2k views
Original Post
pacman2003
pacman2003
I am making a 2D side scroller game. Whenever the user moves left or right, the screen should scroll in that direction and it does. But when it does, it takes about 3/4 secs to do so as the whole screen is redrawn. i mean to say that the transition is not smooth. I am programming using Turbo C. Any ideas? Thanks and Regards! P.S. Please reply in simple English!
remi
remi
Be more specific

"...and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces."----------Scott Meyers, "Effective C++"
Hairybudda
Hairybudda
You never stated what API you were using. If its windows GDI its probably the problem. If its directx, im sorry, im not dx expert. If its gl, i can help
st0ned
pacman2003
pacman2003
I am programming under DOS. Basically the map is represented in a two-dimensional array. When the screen scrolls, my program runs through a 'for' loop which browses through each array element and prints what is represented in that array element.

This should give u an idea of what i am doing:


for (i = 0; i < 24; i++)
{
for (j = 0; j < 81; j++)
{
switch (map[ i ][ j ])
{
case 1: //draw wall
/*code here draws the wall, pixel by pixel using the 'putpixel ()' function*/
break ;

case 2: //draw water
/*code here draws a blue block using the 'putpixel ()' function*/
break ;

case 3: //...
}
} //end j
} //end i


This happens every time the screen scrolls. This whole process takes 3/4 seconds to redraw the screen. How can i avoid this? The screen scrolls every time u press left or right - it does not scroll only when u reach the left or right extreme end of the screen, like in some games. This makes it even more crucial to correct this mistake...

Warm regards.

[edited by - pacman2003 on April 28, 2003 5:19:20 AM]
Yann L
Yann L
The two outer loops are not really the problem. To get more speed, you should first get rid of the switch(), replace it by a direct index into a tilemap array. Or if you really need different function calls for each tiletype, use a function pointer table.

But your real problem is that part:
/*code here draws the wall, pixel by pixel using the ''putpixel ()'' function*/.

Ouch, putpixel...
RhoneRanger
RhoneRanger
Also, turbo C is causing the problem I would guess, since Turbo is win 16 programming.
TechleadEnilno, the Ultima 2 projectwww.dr-code.org/enilno
gamelife
gamelife
When you scroll you don't have to "redraw" the whole screen,
only the invalidated edges region are needed.
Use some fast methods to "move" the contents of your display buffer/memory first.

[edited by - gamelife on April 28, 2003 8:52:32 AM]
Hairybudda
Hairybudda
quote:
Original post by Anonymous Poster
LEARN OGL

Well i think putpixel and all that stuff is pretty slow!!
You shud move ahead with time and use a windows api (opengl or direct3d etc) , why the hell are you wasting ur time on the old dos 16 bit graphics which are more of a hack most of the times!!




This is an intelligent post. More helpful than anything i''ve ever seen.
You asshat.

Like the guy above said, is it definately not the bios function you''re using? I mean, instead of that, you can access linear video memory for mode 13h in dos at 0xA000 (its been a long time though, i may be mistaken). Make sure you''re drawing to a memory buffer and and do memory copies instead of plain putpixel to fill the screen. For fine particle effects like single pixels offset into video memory AFTER you''ve filled the memory buffer, but like i said, its been a while since i touched dos graphics.
And only draw ONLY the parts of the screen that have become visible helps too.
st0ned
Ilici
Ilici
learn some assembly

from what i see ur using textmode (right ?) then the segment for the data is 0xB800;
if ur using graphics mode its 0xA000;


  
void putpixel(unsigned x, unsigned y, unsigned col)
{
/* clip the pixel here */

unsigned offset = y * SCR_WIDHT + x;
asm {
mov bx, 0xA000;
mov bp, offset;
mov ax, col;
mov [bx:bp], ax;
// dunno if this is right it may be

// mov bx:[bp], ax (its been a long time)

}
}

unsigned setmode(unsigned mode)
{
unsigned errcode;
asm {
//load registers with the right stuff (dont remeber and i dont have the book with me

int 0x10;
//error code returned in ax (i think)

}

return errcode;
}

unsigned outputchar(char ch)
{
//there is a function in int 0x10 to do this but i dont remember which is it

}

anyways rewrite the putpixel, or draw entire lines at a time with memcpy into the framebuffer.

also u can use int 10h for some video stuff (setting display mode, getting info, etc)

u could use VESA which is a great improvement but it's ugly coding so use a library.

it can be quite fun to do DOS graphics and stuff like that and if u write them well they're gonna be fast.

then u can start coding some 3d stuff and if ur good enought u can make graphics like Yann's is DOS ;)




<SPAN CLASS=editedby>[edited by - Ilici on April 29, 2003 3:41:06 PM]</SPAN>
pacman2003
pacman2003
Thanx a lot to everybody for replying!
The putpixel function i used to plot pixels is in the Turbo C library and its description doesnt mention whether or not it is a BIOS function. I am not using text mode. i initialized graphics mode by using ''initgraph ()''. I dont know assembly language and also what mode 13h is (is it just another mode like VGA, EGA, etc or something completely different?)

Though i am using Turbo C for DOS, i am running my programs on Win 2000 pro - will the address of the video buffer change bcoz of this? Directly manuplating the video buffer sounds like a great idea. I know pointers pretty well so manuplating memory directly shouldnt be a problem. Also what did Yann mean when he said ''replace the swtich statement and directly index the tilemap array''?

Thanx again and regards!
Ilici
Ilici
if u dont know assembly well u have an alternative

i dunno about turbo C but in borland C there is a function to call interrupts with a registers struct. its called int86.

search the net for the reference to int 0x10 (bios video services). using this will alow u to use more modes than initgraph() (not sure) but using VESA will definetly be a great improvement. there is a VESA library somewhere on programmersheaven.com.
i think that u can also do page flipping with int 0x10

u can also code the memory manipulation function using a pointer to the video segment 0xA000. dont worry about win2000, the memory for text and graphics mode 0xB800, and 0xA000 stays the same for backward compatibility.

as i said the fastest way to draw stuff is drawing along scan lines with memcpy.


ps. this theread brings back some memories



[edited by - Ilici on April 30, 2003 7:09:42 AM]
Ilici
Ilici
now that u got me interested again in the subject i found these sites

http://www.funducode.com/freec/Interrupt/Interrupt_no_10.htm


and


http://www.geocities.com/SiliconValley/Park/8933/vesalib.html
(there is a link to the Vesa library download at the bottom)

also


http://web.inter.nl.net/hcc/S.Weijgers/FreeVGA/vga/vgareg.htm
(for direct video card registers acces)

pacman2003
pacman2003
when u run a dos program in win 2000, is the video buffer unexposed?
AtelierVisca
AtelierVisca
quote:
Original post by pacman2003
when u run a dos program in win 2000, is the video buffer unexposed?


IIRC, DOS applications are handled by an emulator within Windows 2000. You cannot directly interact with the system via a DOS app. I imagine that, because of this, the video buffer is emulated for DOS apps and maps, with protection, to the appropriate information within the OS.

James
Ilici
Ilici
the video mem buffer should be the same in win2000 too because its not OS dependent its BIOS dependent and its been there since EGA and CGA so there should be no prob
pacman2003
pacman2003
You are right Ilici! I tied this and it worked when i ran my dos program on Win 2000. I will try graphics mode too and let u know the results.

 
#include <stdio.h>
#include <conio.h>

main ()
{
char far* ptr = (char far *) 0xb8000000;
int off = 0;
char chr = '0';
char col = 0x00;


for (off = 0; off < 3840; off+=2)
{
*(ptr+off) = chr;
*(ptr+off+1) = col;

chr++;

if (chr > '9')
{
chr = '0';
col++;
}
}

getch() ;
return 0;
}



Ilici, your links were very good too. Thanks to everybody else also who helped me!
Regards.

[edited by - pacman2003 on May 3, 2003 3:13:52 PM]
Ilici
Ilici
glad u found those links interesting.

about graphics mode:
here is the proc to change the mode (no #include <graphics.h>

void setmode(unsigned char mode)
{
asm {
mov ah, 0x00;
mov al, mode;
int 0x10;
}
}

unsigned char getmode()
{
unsigned char mode;
asm {
mov ah, 0x0F;
int 0x10;
mov mode, al;
}
return mode;
}

just copy them and ur done. they are int 10h bios functions.

an explanation of the modes is somewhere on those sites i suggested.

u''ll probably want to use mode 13h -> 320 x 200 x 8bpp paletized

first get a sense of what colours u''ll be using: make a function do display all the colours in the palette.

the palette has 16 pure colours, 16 shades of gray and three sets of gradients (bright, normal, dark)

how to translate an RGB value to a palette value i dont know.
pacman2003
pacman2003
ok this may sound stupid, but what does the ''int'' instruction do?
All i know abt it is that it is short for interrupt (is it?) What does this mean?

Warm Regards.
Hairybudda
Hairybudda
quote:
Original post by Anonymous Poster
''int'' means the size of the register of the processor. In the old DOS days, an int was 16-bits but now-a-days most processors have 32-bit ints.


Are you fucking stupid or something? Dont mislead people like that, int means to call an interrupt, and when you pass stuff into ax, thats like lining it up a paramater, and calling int is like calling a hard wired function. You can get a full list of interrupts and what they do online, all well documented, and you can get familiar with x86 asm fairly easy too, theres a lot of tutorials about. I''ll see what i can find, if you fancy some links?
st0ned

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.