Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » How to draw an opaque, screen-sized, black rectangle?

This thread is locked; no one can reply to it. rss feed Print
How to draw an opaque, screen-sized, black rectangle?
cameron
Member #8,219
January 2007

Hey all,

I have a game in development and to add a more professional touch I want it so when certain messages appear to the player, and when the user pauses the game, etc, the following should happen:

1. a black rectangle at 50% opacity should fill the entire screen
2. text should be displayed at 100% opacity on top of said rectangle
3. the game should pause until a key [P] is pressed

I have #3 done as the following:

        if (key[KEY_P]) { // pause 
                        if (pause == false) pause = true; rest(100);
                        //if (pause) pause = false; rest(100)
                        }
        
        if (pause) { 
                   while (!key[KEY_P]) {
                                   // paused!
                                   }
                   pause = false; rest(100);
                   }

how would i go about drawing a large black opaque rectangle though - i don't know how to do opacity in allegro!

thanks for your help, cameron

Kauhiz
Member #4,798
July 2004

Actually, you apparently don't want an opaque rectangle - opaque means 100% opacity ;). What you want is transcluency. Just look in the manual. A word of warning; trancluency is slow if you're using plain allegro! Since you're pausing the game you might get away with only doing the transcluent blit once, though, since the screen won't change.

---
It's Ridge Racer! RIIIIIDGE RAAAAACER!

gnolam
Member #2,030
March 2002
avatar

To be specific, look up

BTW, the rest()s in your code concern me. You're not doing your game timing with rest(), are you?

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

piccolo
Member #3,163
January 2003
avatar

try messin around with this stuff use a square spite or drawRectangle

 /* Some one time initialisation code. */
      COLOR_MAP global_trans_table;
      create_trans_table(&global_trans_table, my_palette,
       128, 128, 128, NULL);
      ...
      if (get_color_depth() == 8)
   color_map = &global_trans_table;
      else
   set_trans_blender(128, 128, 128, 128);



      draw_trans_sprite(buffer, ghost_sprite, x, y);

makeacol32
Converts an RGBA color into a 32-bit display pixel format.
Description
int makeacol32(int r, int g, int b, int a);
drawRectangle

1// draw a rectangle
2// since we use it three times in the editor, it would be nice to have
3// a function for it.
4void drawRectangle(BITMAP *bmp,int x, int y, int w,int h,int color, int style, int bgcolor)
5{
6 w--;
7 h--;
8 if (style==0)
9 {
10 vline(bmp,x,y,y+h,color);
11 vline(bmp,x+w,y,y+h,color);
12 hline(bmp,x,y,x+w,color);
13 hline(bmp,x,y+h,x+w,color);
14 }
15 if (style==1)
16 {
17 rectfill(bmp,x,y,x+w,y+h,bgcolor);
18 vline(bmp,x,y,y+h,color);
19 vline(bmp,x+w,y,y+h,color);
20 hline(bmp,x,y,x+w,color);
21 hline(bmp,x,y+h,x+w,color);
22 }
23 
24 
25 // this is for our dialog. This draws a box with rounded corners.
26 if (style==2)
27 {
28 arc(bmp,x+10,y+10,itofix(64),itofix(128),10,255);
29 arc(bmp,x+10,y+h-10,itofix(128),itofix(192),10,255);
30 arc(bmp,x+w-10,y+10,itofix(0),itofix(64),10,255);
31 arc(bmp,x+w-10,y+h-10,itofix(192),itofix(256),10,255);
32 
33 
34 hline(bmp,x+10,y,x+w-10,255);
35 hline(bmp,x+10,y+h,x+w-10,255);
36 vline(bmp,x,y+10,y+h-10,255);
37 vline(bmp,x+w,y+10,y+h-10,255);
38
39 floodfill(bmp,x+w/2,y+h/2,255);
40 
41 arc(bmp,x+10,y+10,itofix(64),itofix(128),8,bgcolor);
42 arc(bmp,x+10,y+h-10,itofix(128),itofix(192),8,bgcolor);
43 arc(bmp,x+w-10,y+10,itofix(0),itofix(64),8,bgcolor);
44 arc(bmp,x+w-10,y+h-10,itofix(192),itofix(256),8,bgcolor);
45 
46 
47 hline(bmp,x+10,y+2,x+w-10,bgcolor);
48 hline(bmp,x+10,y+h-2,x+w-10,bgcolor);
49 vline(bmp,x+2,y+10,y+h-10,bgcolor);
50 vline(bmp,x+w-2,y+10,y+h-10,bgcolor);
51 
52 floodfill(bmp,x+w/2,y+h/2,bgcolor);
53 }
54}

wow
-------------------------------
i am who you are not am i

gnolam
Member #2,030
March 2002
avatar

piccolo strikes again! Seriously, that's the clumsiest way to draw rectangles in Allegro that I've ever seen.

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

cameron
Member #8,219
January 2007

gnolam, yes, i am. this is my second game ever. (first was pong) i have a lot to learn.

piccolo i am confused as to how to use that.. (and why not just use rectfill() )

and thanks for all the help guys.

gnolam
Member #2,030
March 2002
avatar

Allegro FAQ to the rescue!

Implement that. Please. Friends don't let friends do rest() timing.

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

Kikaru
Member #7,616
August 2006
avatar

Exactly! Timed game loops saved two of my best games from the recycle bin! :D

cameron
Member #8,219
January 2007

gnolam, i have implemented the counter as you suggested, still not sure what to do in relation to the black-transparency screen problem. i looked at the docu, i guess i just don't know enough about allegro and it's functions to mess with it yet.

thanks guys. oh, and what is the primary benefits to doing this counter over rest()?

gnolam
Member #2,030
March 2002
avatar

Quote:

gnolam, i have implemented the counter as you suggested, still not sure what to do in relation to the black-transparency screen problem. i looked at the docu, i guess i just don't know enough about allegro and it's functions to mess with it yet.

Well, what's the problem?

Quote:

thanks guys. oh, and what is the primary benefits to doing this counter over rest()?

The timer-based method actually works. rest() will, at best, work on one computer - yours.

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

Kikaru
Member #7,616
August 2006
avatar

Rest works like this:

//loop took 5 milliseconds
rest(20) //rest for 20 milliseconds
//total time: 25 milliseconds

Timed Loops work like this:

//loop took 5 milliseconds
while (timer < loop_start+20){}; //waits until it was been at least 20 
//milliseconds since the START of the loop
//total time: 20 milliseconds

LennyLen
Member #5,313
December 2004
avatar

Quote:

//loop took 5 milliseconds
rest(20) //rest for 20 milliseconds
//total time: 25 milliseconds

That's providing of course the loop takes 5 miliseconds, which it won't on all machines. Which is why you don't use rest() for timing.

cameron
Member #8,219
January 2007

thanks for the explanation. I'm now rest()-free.

il update you on the black screen thing tomorrow.. i'm off to bed.

Evert
Member #794
November 2000
avatar

Quote:

1. a black rectangle at 50% opacity should fill the entire screen

An old-school (and cheap) way of getting this effect is to use dithering: turn alternate pixels black in a checkerboard pattern. If your resolution is high enough, the difference is not noticable unless you look closely. You could even make this an option.

piccolo
Member #3,163
January 2003
avatar

that can be done something like this.

1 
2void do_trans(BITMAP *dest){
3 int color = makecol(0,0,0);
4 int fourth_width = dest->w/4;
5 for(int y = 0; y <= dest->h; ++y) {
6 unsigned short *pixel_ptr = (unsigned short *)dest->line[y];
7 int x = 0;
8 if( y & 1 ) {
9 ++x;
10 ++pixel_ptr;
11 }
12 for(; x <= fourth_width; ++x ) {
13 //*pixel_ptr = color;
14 pixel_ptr += 4;
15 }
16 }
17}

edited

wow
-------------------------------
i am who you are not am i

Evert
Member #794
November 2000
avatar

Nope - that masks out alternate scanlines (and can therefore be optimised considerably). That could also work to achieve the same effect though..

piccolo
Member #3,163
January 2003
avatar

yeah i fix the color from 255 0 255 to 0 0 0

wow
-------------------------------
i am who you are not am i

Arthur Kalliokoski
Second in Command
February 2005
avatar

A lot of the video cut scenes from mid-90's games such as Tomb Raider I used alternate scan lines to improve frame rate, it'd look much better with higher resolutions but still a bit dark. In other words, half the scan lines were black and built to stay that way.

They all watch too much MSNBC... they get ideas.

Kikaru
Member #7,616
August 2006
avatar

Quote:

That's providing of course the loop takes 5 milliseconds, which it won't on all machines. Which is why you don't use rest() for timing.

It's called an "example". ;)

LennyLen
Member #5,313
December 2004
avatar

Quote:

It's called an "example".

I'm aware of that. But your example doesn't explain very well why not to use rest().

ImLeftFooted
Member #3,935
October 2003
avatar

Anything wrong with taking a screenshot of the game, tinting it, and displaying that?

As for code that will do this... ugh.. (/me goes to lookup random source code...)

Alright found it. Heres some code i found in old code and (lucky you) rewritten for your uses!

// If howMuch is 1, dest is turned black.  If howMuch is 0, dest is left unchanged
void shade(BITMAP *dest, float howMuch)
{
    const int val = (int)(howMuch * 0xff);

    set_trans_blender(0xff, 0xff, 0xff, val);
    drawing_mode(DRAW_MODE_TRANS, 0, 0, 0);
    rectfill(dest, 0, 0, dest->w, dest->h, makeacol32(0xff, 0xff, 0xff, val));
    drawing_mode(DRAW_MODE_SOLID, 0, 0, 0);
}

Shesh I spend more time writing code in this little a.cc textbox then I do anywhere else.

Example usage:

.. blah draw to screen ..

shade(screen, .5);

.. blah draw pause crap to screen ..

gnolam
Member #2,030
March 2002
avatar

Quote:

Anything wrong with taking a screenshot of the game, tinting it, and displaying that?

It's much more work than just drawing a DRAW_MODE_TRANS rectfill() over the buffer?

[EDIT]

Quote:

rectfill(dest, 0, 0, dest->w, dest->h, makeacol32(0xff, 0xff, 0xff, val));

... and that alpha is completely unnecessary.

--
Move to the Democratic People's Republic of Vivendi Universal (formerly known as Sweden) - officially democracy- and privacy-free since 2008-06-18!

ImLeftFooted
Member #3,935
October 2003
avatar

The docs don't really say so I just put the alpha value everywhere I could. Never actually tested which one is actually used.

Go to: