Mapping 3200x2400 into 800x600

Hello sdl,

like in subject.

right now, i am doing like this:

(using pixel rgba because of different bpp)
(using three tables because of… eer… making nights :wink: if you
have prerendered screen of scene in games such baldurs gate - when
you want make night you just exchange r with b values)

void UpdateScroll(long ofx, long ofy)
{
unsigned long ah1,ah2;
unsigned long offset_z;

    for (ah1=0;ah1<600;ah1++)
    {
            for (ah2=0;ah2<800;ah2++)
            {
                    offset_z=(3200*(ah1+ofy))+ofx+ah2;
                    SDL_pixelRGBA(background,ah2,ah1,vaddr_r[offset_z],
                            vaddr_g[offset_z], vaddr_b[offset_z],255);
            }
    }

}

screen init… isn’t it better to use hwsurface with doublebuf ? but
when i do, pixelrgba is extreme slow… any ideas why?

    screen = SDL_SetVideoMode(800, 600, 16,
                    (SDL_FULLSCREEN|SDL_SWSURFACE));

and mainloop looks like this:

    while (  klawiatura[SDLK_ESCAPE]!=SDL_PRESSED )
    {
            SDL_PollEvent(&event);
            SDL_BlitSurface(mouse_save,NULL,screen,&mouse_rect);    // bufor na ekran
            SDL_GetMouseState(&mouse_x, &mouse_y);

            mouse_rect.x=mouse_x; mouse_rect.y=mouse_y;
            mouse_rect.h=32; mouse_rect.w=32;

                    if (mouse_x<5&&offset_x>5)
                    {
                            offset_x-=50;
                            UpdateScroll(offset_x,offset_y);
                            SDL_BlitSurface(background,0,screen,0);
                    }

                    if (mouse_x>795&&offset_x<2400)
                    {
                            offset_x+=50;
                            UpdateScroll(offset_x,offset_y);
                            SDL_BlitSurface(background,0,screen,0);
                    }

                    if (mouse_y<5&&offset_y>5)
                    {
                            offset_y-=50;
                            UpdateScroll(offset_x,offset_y);
                            SDL_BlitSurface(background,0,screen,0);

                    }

                    if (mouse_y>595&&offset_y<1600)
                    {
                            offset_y+=50;
                            UpdateScroll(offset_x,offset_y);
                            SDL_BlitSurface(background,0,screen,0);
                    }

            SDL_BlitSurface(screen,&mouse_rect,mouse_save,NULL);    // tlo do bufora
            SDL_BlitSurface(mouse_cursor,NULL,screen,&mouse_rect);  // mysz na ekran

            SDL_UpdateRect(screen,0,0,0,0);

            SDL_PumpEvents();       // odswiez eventy
            klawiatura = SDL_GetKeyState(NULL);     // odswiez
    }

    mkey, any ideas, how to make it faster ? divide whole screen
    into little ie. 32x32 surfaces ? sound pity, isn't it ?-- 

Best regards,
firefox mailto:@palpetine

Okresl Swoje potrzeby - my znajdziemy oferte za Ciebie!
[ http://oferty.onet.pl ]

for example

El dt, 22-01-2002 a las 10:13, firefox escribi?:

Hello sdl,

  like in subject.

  right now, i am doing like this:

  (using pixel rgba because of different bpp)
  (using three tables because of... eer... making nights ;) if you
  have prerendered screen of scene in games such baldurs gate - when
  you want make night you just exchange r with b values)

void UpdateScroll(long ofx, long ofy)
{
        unsigned long ah1,ah2;
        unsigned long offset_z;

        for (ah1=0;ah1<600;ah1++)
        {
                for (ah2=0;ah2<800;ah2++)
                {
                       offset_z=(3200*(ah1+ofy))+ofx+ah2;
                        offset_z=(3200*(ah1+ofy))+ofx+ah2;
                        SDL_pixelRGBA(background,ah2,ah1,vaddr_r[offset_z],
                                vaddr_g[offset_z], vaddr_b[offset_z],255);
                }
        }

}

screen init... isn't it better to use hwsurface with doublebuf ? but
when i do, pixelrgba is extreme slow... any ideas why?

        screen = SDL_SetVideoMode(800, 600, 16,
                        (SDL_FULLSCREEN|SDL_SWSURFACE));
        
and mainloop looks like this:

        while (  klawiatura[SDLK_ESCAPE]!=SDL_PRESSED )
        {
                SDL_PollEvent(&event);
                SDL_BlitSurface(mouse_save,NULL,screen,&mouse_rect);    // bufor na ekran
                SDL_GetMouseState(&mouse_x, &mouse_y);

                mouse_rect.x=mouse_x; mouse_rect.y=mouse_y;
                mouse_rect.h=32; mouse_rect.w=32;

                        if (mouse_x<5&&offset_x>5)
                        {
                                offset_x-=50;
                                UpdateScroll(offset_x,offset_y);
                                SDL_BlitSurface(background,0,screen,0);
                        }

                        if (mouse_x>795&&offset_x<2400)
                        {
                                offset_x+=50;
                                UpdateScroll(offset_x,offset_y);
                                SDL_BlitSurface(background,0,screen,0);
                        }

                        if (mouse_y<5&&offset_y>5)
                        {
                                offset_y-=50;
                                UpdateScroll(offset_x,offset_y);
                                SDL_BlitSurface(background,0,screen,0);

                        }

                        if (mouse_y>595&&offset_y<1600)
                        {
                                offset_y+=50;
                                UpdateScroll(offset_x,offset_y);
                                SDL_BlitSurface(background,0,screen,0);
                        }

                SDL_BlitSurface(screen,&mouse_rect,mouse_save,NULL);    // tlo do bufora
                SDL_BlitSurface(mouse_cursor,NULL,screen,&mouse_rect);  // mysz na ekran

                SDL_UpdateRect(screen,0,0,0,0);

                SDL_PumpEvents();       // odswiez eventy
                klawiatura = SDL_GetKeyState(NULL);     // odswiez
        }

        mkey, any ideas, how to make it faster ? divide whole screen
        into little ie. 32x32 surfaces ? sound pity, isn't it ?-- 
Best regards,
 firefox                          mailto:palpetine at poczta.onet.pl




-- 

Okresl Swoje potrzeby - my znajdziemy oferte za Ciebie!
[ http://oferty.onet.pl ]


_______________________________________________
SDL mailing list
SDL at libsdl.org

http://www.libsdl.org/mailman/listinfo/sdl

sorry for the last message

offset_z=(3200*(ah1+ofy))+ofx+ah2;

could be

offset_z=ah1+ofy;
offset_z=(offset_z<<11 + offset_z<<10 + offset_z<<7) + ofx + ah2;

but the optimizer compiler could be make it already

also you can move 3200*(ah1+ofy) to the first for (ah1) and calculate it
only at every line (after every second for ah2)

why not use a SDL_Surface for vaddr_r, vaddr_g, vaddr_b and simply blit
it on the background surface?

or the final solution, assembler :slight_smile:

El dt, 22-01-2002 a las 10:27, samsaga2 escribi?:

for example 

El dt, 22-01-2002 a las 10:13, firefox escribi?: 

    Hello sdl,
    
      like in subject.
    
      right now, i am doing like this:
    
      (using pixel rgba because of different bpp)
      (using three tables because of... eer... making nights ;) if you
      have prerendered screen of scene in games such baldurs gate - when
      you want make night you just exchange r with b values)
    
    void UpdateScroll(long ofx, long ofy)
    {
            unsigned long ah1,ah2;
            unsigned long offset_z;
    
            for (ah1=0;ah1<600;ah1++)
            {
                    for (ah2=0;ah2<800;ah2++)
                    {
                            offset_z=(3200*(ah1+ofy))+ofx+ah2;
                            SDL_pixelRGBA(background,ah2,ah1,vaddr_r[offset_z],
                                    vaddr_g[offset_z], vaddr_b[offset_z],255);
                    }
            }
    
    }
    
    screen init... isn't it better to use hwsurface with doublebuf ? but
    when i do, pixelrgba is extreme slow... any ideas why?
    
            screen = SDL_SetVideoMode(800, 600, 16,
                            (SDL_FULLSCREEN|SDL_SWSURFACE));
            
    and mainloop looks like this:
    
            while (  klawiatura[SDLK_ESCAPE]!=SDL_PRESSED )
            {
                    SDL_PollEvent(&event);
                    SDL_BlitSurface(mouse_save,NULL,screen,&mouse_rect);    // bufor na ekran
                    SDL_GetMouseState(&mouse_x, &mouse_y);
    
                    mouse_rect.x=mouse_x; mouse_rect.y=mouse_y;
                    mouse_rect.h=32; mouse_rect.w=32;
    
                            if (mouse_x<5&&offset_x>5)
                            {
                                    offset_x-=50;
                                    UpdateScroll(offset_x,offset_y);
                                    SDL_BlitSurface(background,0,screen,0);
                            }
    
                            if (mouse_x>795&&offset_x<2400)
                            {
                                    offset_x+=50;
                                    UpdateScroll(offset_x,offset_y);
                                    SDL_BlitSurface(background,0,screen,0);
                            }
    
                            if (mouse_y<5&&offset_y>5)
                            {
                                    offset_y-=50;
                                    UpdateScroll(offset_x,offset_y);
                                    SDL_BlitSurface(background,0,screen,0);
    
                            }
    
                            if (mouse_y>595&&offset_y<1600)
                            {
                                    offset_y+=50;
                                    UpdateScroll(offset_x,offset_y);
                                    SDL_BlitSurface(background,0,screen,0);
                            }
    
                    SDL_BlitSurface(screen,&mouse_rect,mouse_save,NULL);    // tlo do bufora
                    SDL_BlitSurface(mouse_cursor,NULL,screen,&mouse_rect);  // mysz na ekran
    
                    SDL_UpdateRect(screen,0,0,0,0);
    
                    SDL_PumpEvents();       // odswiez eventy
                    klawiatura = SDL_GetKeyState(NULL);     // odswiez
            }
    
            mkey, any ideas, how to make it faster ? divide whole screen
            into little ie. 32x32 surfaces ? sound pity, isn't it ?-- 
    Best regards,
     firefox                          mailto:palpetine at poczta.onet.pl
    
    
    
    
    -- 
    
    Okresl Swoje potrzeby - my znajdziemy oferte za Ciebie!
    [ http://oferty.onet.pl ]
    
    
    _______________________________________________
    SDL mailing list
    SDL at libsdl.org

http://www.libsdl.org/mailman/listinfo/sdl

Hello samsaga2,

Tuesday, January 22, 2002, 10:39:43 AM, you wrote:

s> sorry for the last message

s> offset_z=(3200*(ah1+ofy))+ofx+ah2;

s> could be

s> offset_z=ah1+ofy;
s> offset_z=(offset_z<<11 + offset_z<<10 + offset_z<<7) + ofx + ah2;

s> but the optimizer compiler could be make it already

s> also you can move 3200*(ah1+ofy) to the first for (ah1) and calculate it
s> only at every line (after every second for ah2)

s> why not use a SDL_Surface for vaddr_r, vaddr_g, vaddr_b and simply blit
s> it on the background surface?

hmmm? 3200x2400 surface ? did you count how many mem it use?

s> or the final solution, assembler :)–
Best regards,
firefox mailto:@palpetine


Placisz raz - uzywasz caly czas!
http://www.onetmail.onet.pl/oferta

El dt, 22-01-2002 a las 11:10, firefox escribi?:

Hello samsaga2,

Tuesday, January 22, 2002, 10:39:43 AM, you wrote:

s> sorry for the last message


s> offset_z=(3200*(ah1+ofy))+ofx+ah2;

s> could be

s> offset_z=ah1+ofy;
s> offset_z=(offset_z<<11 + offset_z<<10 + offset_z<<7) + ofx + ah2;

s> but the optimizer compiler could be make it already

s> also you can move 3200*(ah1+ofy) to the first for (ah1) and calculate it
s> only at every line (after every second for ah2)

s> why not use a SDL_Surface for vaddr_r, vaddr_g, vaddr_b and simply blit
s> it on the background surface?

hmmm? 3200x2400 surface ? did you count how many mem it use?

a SDL_Surface with 32bits 3200x2400x4 about 30Mb

now, three tables 24bits (vaddr+vaddr_g+vaddr_b)x3200x2400 about 23Mb

but could be a SDL_Surface with 16bit, 3200x2400x2 about 15Mb

s> or the final solution, assembler :)-- 
Best regards,
 firefox                            mailto:palpetine at poczta.onet.pl




-- 
Placisz raz - uzywasz caly czas!
http://www.onetmail.onet.pl/oferta



_______________________________________________
SDL mailing list
SDL at libsdl.org

http://www.libsdl.org/mailman/listinfo/sdl

Hello samsaga2,

Tuesday, January 22, 2002, 11:40:27 AM, you wrote:

s> hmmm? 3200x2400 surface ? did you count how many mem it use?

s> a SDL_Surface with 32bits 3200x2400x4 about 30Mb

s> now, three tables 24bits (vaddr+vaddr_g+vaddr_b)x3200x2400 about 23Mb

s> but could be a SDL_Surface with 16bit, 3200x2400x2 about 15Mb

yes, but exchanging red value with blue value in realtime at 3200x2400
sounds tricky and will smooth downrate the speed.

lets concentrate on the other way - little surfaes ie 16x16, when
scrolling we simply add surfaces and remove surfaces, but… we
need… erg, 30000 surfaces, or 7500 when 32x32… hmmm, any ideas ?–
Best regards,
firefox mailto:@palpetine


Placisz raz - uzywasz caly czas!
http://www.onetmail.onet.pl/oferta

Hello samsaga2,

Tuesday, January 22, 2002, 11:40:27 AM, you wrote:

s> hmmm? 3200x2400 surface ? did you count how many mem it use?

s> a SDL_Surface with 32bits 3200x2400x4 about 30Mb

s> now, three tables 24bits (vaddr+vaddr_g+vaddr_b)x3200x2400 about
23Mb

s> but could be a SDL_Surface with 16bit, 3200x2400x2 about 15Mb

yes, but exchanging red value with blue value in realtime at 3200x2400
sounds tricky and will smooth downrate the speed.

Yeah. Why not do it at load time? (“Heeeelp! My RAM!!” No worries; read
on… :slight_smile:

lets concentrate on the other way - little surfaes ie 16x16, when
scrolling we simply add surfaces and remove surfaces, but… we
need… erg, 30000 surfaces, or 7500 when 32x32… hmmm, any ideas ?

Well… What’s the problem? Are you doing something very special here?
(I might be missing the point…)

90% of all 2D games do it this way, and in in a way, nearly all 3D games
as well. (They use the same textures many times, sometimes applying real
time blending effects to simulate light, shadows and other effects.) The
trick is to view the “tiled map” desing as a form of data compression.
That is, reuse tile images - don’t use one tile for each square on the
map.

If simple, hard edge, square tiles are too much of an artistic
limitation, there are many, many other ways of doing it. The simplest way
is probably just using multiple map layers: A “background” layer
consisting of opaque tiles, and one or more “detail” layers with
colorkeyd or alpha blended tiles, that are combined with the background.

If that’s still too limited, allow the detail tiles to have pixel offsets
from the map grip positions, so you can use them as a form of sprites.

Note that you can actually pipe them through the same code as the "real"
sprites in you game, so you can have some “background” details actually
being rendered on top of movable sprites. For example, in a top-down view
game, you can have trees that your characters can walk under to some
extent. (Looks much nicer than the classical “thou shallt not work
inunder background details”, to keep the lack of depth from showing. :slight_smile:

Now, if things get too slow, and/or you want to do even heavier
rendering, like depth map based shadow casting and stuff, you can do all
rendering into a set of “cache tiles”, that you then blit to the screen.
Use the cache tiles -> screen blit as a form of simulated hardware
scrolling, and update buffer tiles only as needed to provide the cached
tiles set with the map areas that will show up on the screen. Kind of a
different way of implementing the “blit move or h/w scroll the screen,
and then update only the edges” algorithm.

Should also work very well with OpenGL, as it minimizes the texture
transfer bandwidth. (Normally, for software rendering on an OpenGL
display, you’d have to retransfer texture data corresponding to the whole
screen area every frame, but here you transfer only the areas that are
about to scroll into vision.)

Maybe it’s time I hacked a more advanced scrolling example, demonstrating
some of these techniques? (I’d really like to play some with it, but I
currently don’t really have a need for such an engine… :slight_smile:

//David Olofson — Programmer, Reologica Instruments AB

.- M A I A -------------------------------------------------.
| Multimedia Application Integration Architecture |
| A Free/Open Source Plugin API for Professional Multimedia |
----------------------------> http://www.linuxdj.com/maia -' .- David Olofson -------------------------------------------. | Audio Hacker - Open Source Advocate - Singer - Songwriter |-------------------------------------> http://olofson.net -'On Tuesday 22 January 2002 12:13, firefox wrote:

Hello David,

Wednesday, January 23, 2002, 5:45:24 PM, you wrote:

DO> Yeah. Why not do it at load time? (“Heeeelp! My RAM!!” No worries; read
DO> on… :slight_smile:

mkey, but right now i can tell you, that i want to scale the whole
area. it should looks like - you press right button, you got soft
scale, not by 2,4,6 or so on but soft zooming without image quality
lost. it’s kinda tricky.

DO> 90% of all 2D games do it this way, and in in a way, nearly all 3D games
DO> as well. (They use the same textures many times, sometimes applying real
DO> time blending effects to simulate light, shadows and other effects.) The
DO> trick is to view the “tiled map” desing as a form of data compression.
DO> That is, reuse tile images - don’t use one tile for each square on the
DO> map.

indeed, you are right, but… look ie on fallout tactics - single
mission is placed in one +/- 6400/4800 screen - looks how many
different tiles they use - what is better - tiles or prerendered map
is tricky question. especialy, when there is no two the same tiles on
one map.

DO> If simple, hard edge, square tiles are too much of an artistic
DO> limitation, there are many, many other ways of doing it. The simplest way
DO> is probably just using multiple map layers: A “background” layer
DO> consisting of opaque tiles, and one or more “detail” layers with
DO> colorkeyd or alpha blended tiles, that are combined with the background.

already checked. still slow. i am wondering if this is not sdl fault
:wink: just kidding, its always programmer fault :wink:

DO> Note that you can actually pipe them through the same code as the "real"
DO> sprites in you game, so you can have some “background” details actually
DO> being rendered on top of movable sprites. For example, in a top-down view
DO> game, you can have trees that your characters can walk under to some
DO> extent. (Looks much nicer than the classical “thou shallt not work
DO> inunder background details”, to keep the lack of depth from showing. :slight_smile:

yeah, but i want have several npc walking here and there, not only
like in baldur’s gate - i want 5 levels maps - 2 underground, one “on
the ground”, and two levels. that sounds tricky. i already have 3
levels and it takes … around 87megs…

DO> Now, if things get too slow, and/or you want to do even heavier
DO> rendering, like depth map based shadow casting and stuff, you can do all
DO> rendering into a set of “cache tiles”, that you then blit to the screen.
DO> Use the cache tiles -> screen blit as a form of simulated hardware
DO> scrolling, and update buffer tiles only as needed to provide the cached
DO> tiles set with the map areas that will show up on the screen. Kind of a
DO> different way of implementing the “blit move or h/w scroll the screen,
DO> and then update only the edges” algorithm.

indeed i use shading, lighting and 2d bumpmapping, blur, distort and
more . i am about to test few algho and ask you people again.

DO> Maybe it’s time I hacked a more advanced scrolling example, demonstrating
DO> some of these techniques? (I’d really like to play some with it, but I
DO> currently don’t really have a need for such an engine… :slight_smile:

yeah. i saw warcraft3 and wondering is there any reason for making
such 2d stuff, neither lightwave based opengl 3d terrain renderer.–
Best regards,
firefox mailto:@palpetine

Okresl Swoje potrzeby - my znajdziemy oferte za Ciebie!
[ http://oferty.onet.pl ]

A bit off-topic… any guess on how they did it? :wink:

I was wondering if WC3 is using 2D background the other day, since
I never saw a viewport change in any of its trailer, and the terrain
looks really like 2D tile stuff. Maybe Sam can confirm this? :slight_smile:

I happen to be investigating on this 3D on 2D stuff, but seems only
through special GL extension like buffer-region can I preseve the
z-buffer of a pre-rendered 2D scene. Somebody told me that DirectX
also supports buffer copy in some video cards, which I am not sure.
Games like Silver could be using some other tricks like drawing hidden
polygons instead of copying z-buffer at every frame.

But if you are just talking about 2D games, I guess multi-layered
tile is the most common way to do it. You can avoid redundant
redraw/update using some intelligent algorithm. I am yet to see
any 2D game with free-style zoom in/out minimap.

Regards,
.paul.On Mon, Jan 28, 2002 at 01:06:51PM +0100, firefox wrote:

yeah. i saw warcraft3 and wondering is there any reason for making
such 2d stuff, neither lightwave based opengl 3d terrain renderer.

Ok, this time back on topic:

The way to solve firefox’s original problem is to use
small size image instead of 3200x2400. If you don’t like
tiles, that is fine, you can cut your 3200x2400 into
20x15=300 square images each of 160x160.

  1. cut the images into squares, and make a rule for the
    filenames, such as bg-XX-YY.bmp, in which XX and YY being
    the indices.

  2. design a function that returns the X region and Y region
    of all screen visible tiles. For example, if your screen
    upperleft corner is at position (1234, 567) on your background,
    this function would return 7 to 13 for XX index, and 3 to 8
    for YY index.

  3. design a loader function for the squares. It keeps a cache
    of all squares within the XX and YY region, loads those not
    loaded, and frees those not in current visible region.

  4. now you have all visible squares in memory, and blit them
    on to the screen, using different srcrect and dstrect to
    achieve the scrolling effect.

This method has some loading issue when you scroll to square
boundaries, in the worse case you have to load 5 + 4 = 9
squares. This could appear a bit jerky. However, you may
improve it by using a separate thread to manage all squares
in the background, and load more squares before you actually
need them, somewhat like look-ahead. Of course this
is only good for relatively slow speed scrolling.

Indeed this is the method used in quite a lot of 2D games.
It virtually renders any size of backgrounds, and even scales
with your screen resolution.

Regards,
.paul.