Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Strange C++ and Allegro
#1
Can someone check out this code. I'm having some problems with the getangle function. No errors, but it just isn't working correctly.

Code:
#include <allegro.h>
#include <math.h>
#define DEGREES(x) int((x)/360.0*0xFFFFFF)
#define RADIANS(x) int((x)/2/M_PI*0xFFFFFF)
#include <stdlib.h>

void init(int wdth, int hght, int cdepth, int fscreen);
float getAng(int x1, int y1, int x2, int y2);
void deinit();

int main() {
    init(640,480,16,0);
    BITMAP *buffer = create_bitmap(640, 480);
    
    
    BITMAP *Aimer = load_bitmap("Aimer.tga",0);
    BITMAP *Player= load_bitmap("Player.tga",0);
  
    int px=320;
    int py=240;
    float x;
    while (!key[KEY_ESC]) {
       clear(buffer);
      
       /* put your code here */
    
        
       pivot_sprite(buffer,Player,px,py,32,32,ftofix(getAng(px,py,mouse_x,mouse_y)));
       x-=.1;
      
       draw_sprite(buffer, Aimer,mouse_x-Aimer->w/2, mouse_y-Aimer->h/2);
       line(buffer,px,py,mouse_x,mouse_y,makecol(255,0,0));
        
       blit(buffer, screen, 0, 0, 0, 0, buffer->w, buffer->h);    
    }

    deinit();
    return 0;
}
END_OF_MAIN()

void init(int wdth, int hght, int cdepth, int fscreen) {
    int depth, res;
    allegro_init();
    set_color_depth(cdepth);
    if (fscreen == 0)
    {
        res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, wdth, hght, 0, 0);
    }else
    {
        res = set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, wdth, hght, 0, 0);
    }  
    if (res != 0) {
        allegro_message(allegro_error);
        exit(-1);
    }

    install_timer();
    install_keyboard();
    install_mouse();
    /* add other initializations here */
    
}
float getAng(int x1, int y1, int x2, int y2)
{
    float FaceRadians= atan2 (y2 - y1, x2 - x1);
    float FaceDegrees = FaceRadians * 180 / M_PI;
    return FaceDegrees+90;
}
void deinit() {
    clear_keybuf();
    /* add other deinitializations here */
}

Quote:pivot_sprite(buffer, Player, px, py, 32, 32, ftofix(getAng(px,py,mouse_x,mouse_y)));

the red part is the thing I believe is causing problems because allegro needed fixed angle but because I'm very new to C++, I am not sure how to fix this issue! I am trying to make the Player graphic rotate so it always faces the mouse. Again, I'd be very happy if anyone could give me a little help.:wtnod:
Reply
#2
Perhaps you are forgetting to convert degrees to radians and vice versa?
.14159265358979323846264338327950288419716939937510582709445
Glarplesnarkleflibbertygibbertygarbethparkentalelelangathaffendoinkadonkeydingdonkaspamahedron.
Reply
#3
"fixed" is just a method to store numbers with decimals. Fixed point arithmetic is faster than floating point arithmetic, 'cause you don't have to do special stuff to add, substract, multiply or divide two fixed point numbers: they work exactly as integers.

A Fixed Point number, in binary form, has the number divided in two sections, just like 18.45 is divided in 18: integer and 45: decimal, but in base 2.

Allegro FIX data type is in fact a 32 bits integer which 16 lower bits are considered as the "decimal" part and the 16 upper ones are considered as the "integer" part. so if, for example, you have a 0xFFB0EAB1 as a fixed point number, you are representing in fact 0xFFB0.EAB1, but internally it is in fact an integer number so operating with it is fast.

This FIX data type allows for a 1/65536 precission, meaning that the smaller number you can represent (in absolute value, I mean) is 1/65536 (which would be 0x0000.0001). "1.0" in FIX is in fact 65536 (this is, 0x0001.0000).

I used this technique in Jill for QB to avoid floats. I just had every coordinate multiplied by 128 so I gained 1/128 precission.

Internally, what allegro does to convert a 16 bits integer to a 32 bits "Fix" value is just multiplying by 65536 (or Shl 16). To convert back from Fix to integer it just divides again by 65536 (or Shr 16).

That means that in every allegro function that expects an fix, you have to pass a fix, i.e. you have to use a converter. ftofix converts from floats to fix, adn the getAng function returns a float, so that bit is correct. I think that maybe it is the formulae which is screwed, but I can't tell you right now as I can't test the code here.

Anyway, there's no point on working in float then converting to fix (well, appart from the functions needing a fix value). Why don't you work directly in fixed point math? Or do you need more than a 1/65536 of precission?
SCUMM (the band) on Myspace!
ComputerEmuzone Games Studio
underBASIC, homegrown musicians
[img]http://www.ojodepez-fanzine.net/almacen/yoghourtslover.png[/i
Reply
#4
Thanks na_th_an for telling me some tips. I wasn't sure what a fixed angle was until now. 8) So I will try to learn a little more about c++ so I can make necessary changes.

About the formula and why it doesn't work. I copied that exactly out of a function that worked in another c++ program, but didn't use fixed angles. that's why i thought it might be that. I've also used that formula in fb, flash, etc. all without a problem. :???:
Reply
#5
Don't forget that Allegro functions that expect an angle (such as pivot_sprite) want it in Allegro's special measurement (different from radians or degrees) where 255 = 360 degrees or 2*PI radians.

See the "Fixed point trig" section of the Fixed point math routines page of the Allegro docs for more information.
Reply
#6
Thanks DrV (What's your real name again?). I will check that out if I get some spare time this evening.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)