Allegro.cc - Online Community

Allegro.cc Forums » Allegro Development » Help Building SVN, and adding functions to allegro

This thread is locked; no one can reply to it. rss feed Print
Help Building SVN, and adding functions to allegro
Timorg
Member #2,028
March 2002

I have a few question about hacking allegro, and my circle thick function. (from this thread http://www.allegro.cc/forums/thread/591592/676194#target[/url])

Is this the correct way to build allegro from svn on linux?
----------------------------------------
chmod +x fix.sh
./fix.sf unix
autoconf
autoheader
./configure
make
sudo make install
----------------------------------------
I have a feeling that a "make depend" might be required somewhere, definitely if you "make veryclean"

How do I build svn on mingw? I have sed and sort in my mingw/bin directory, I can beat on it, but I can't seem to work out the issues, I still get this issue http://www.allegro.cc/forums/thread/591110/667403#target, so I patch the latest stable version, and work from that.

How do I add methods to the end of the vtable?
How do I set the driver method for circlethick?
How do I init the vtable for circlethick?

I think thats all my questions for the moment, I think some of them overlap.

-Tim

____________________________________________________________________________________________
"c is much better than c++ if you don't need OOP simply because it's smaller and requires less load time." - alethiophile
OMG my sides are hurting from laughing so hard... :D

GullRaDriel
Member #3,861
September 2003
avatar

Under mingw32, AFAIK :

misc/fixdll.sh
fix.bat mingw32
make depend
make

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

Evert
Member #794
November 2000
avatar

Quote:

I have a feeling that a "make depend" might be required somewhere, definitely if you "make veryclean"

The configure stage should take care of running "make depend" for you, but it doesn't hurt to run it manually after configure.

Quote:

How do I add methods to the end of the vtable?

You add the method to the end of the appropriate VTABLE struct.

Quote:

How do I set the driver method for circlethick?

You add a function pointer pointing to your function to the declration of the driver.

Quote:

How do I init the vtable for circlethick?

Add a vtable entry for it, in the driver struct, defined the function and make sure you update all drivers to the new format. Then add an inline function in draw.inl (I think) that wraps the call to the vtable function.

That said, your function only calls other basic Allegro primitives, so I don't really see a reason why this needs to be in a vtable? If it's with an eye to hardware acceleration, then the vtable wrapper should check if an accelerated function is available and call that, or do what this function does instead. No need to put it in a vtable in that case either.

Michael Jensen
Member #2,870
October 2002
avatar

Yeah, unless you have a reason to, and it's not just on a whim, I don't think you should be mucking with the vtables, you could accidently break binary compatibility or something.

Cool function though.

But you use sqrt a lot... Is it slow? -- I wouldn't be suprised if it was faster than mine.

Timorg
Member #2,028
March 2002

It uses the mathematical equation for a circle, which is heavy on square root

circle.png

b and a are set to 0, to simplify the equation, and are applied before the shape is drawn.

I need to use an integrative approach, which I hope to borrow from do_circle(...) :)

____________________________________________________________________________________________
"c is much better than c++ if you don't need OOP simply because it's smaller and requires less load time." - alethiophile
OMG my sides are hurting from laughing so hard... :D

Michael Jensen
Member #2,870
October 2002
avatar

I believe it's possible to draw a filled circle without using square root -- I'm not sure how allegro does it though.

Timorg
Member #2,028
March 2002

This problem is much more complicated than it appears on the surface, I knew it wasn't going to be simple, but the allegro do_circle, uses 8 lines of symmetry, which causes problem, I am getting better results with only 4 lines, I can't find an algorithm that doesn't use symmetry at all, that would make the job simpler, but the circle would still be drawn in 4 parts, and the outer parts don't match the inner parts, so you need to keep them in line with each other, only step to the new line if the other has.

I am determined to solve this. :)

____________________________________________________________________________________________
"c is much better than c++ if you don't need OOP simply because it's smaller and requires less load time." - alethiophile
OMG my sides are hurting from laughing so hard... :D

Michael Jensen
Member #2,870
October 2002
avatar

Yes, the circle algorithm uses 8 lines of symmetry (my comment earlier was about the filled circle function btw, not the actual circle function -- you can draw a filled circle without using sqrt...)

The 8 lines of symmetry approach is, AFAIK, the fastest way to make a computer compute the points in a circle. If you just need the points, use an array or something. And just add the points to it as generated by the 8 lines of symmetry algorithm to your array as it generates them.

(What's wrong with the 8 lines of symmetry approach anyway?)

Timorg
Member #2,028
March 2002

{"name":"circle_problem.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/e\/6\/e6d1cc9d24cbbbde07d4415a63545509.png","w":242,"h":195,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/e\/6\/e6d1cc9d24cbbbde07d4415a63545509"}circle_problem.png

The dark green edge of the inner circle is drawn heading upwards, and the blue arrow is being drawn downwards, so unless you want to save all the points, or fill the area recursively, I have a solution to fill this particular example, but it breaks when the inner radius and outer radius are too close together.

Edit: I have found a solution that works :) Just need to format the code all nice and make a patch

1void circlethick(BITMAP *bmp, int x, int y, int radius, int thickness, int color)
2{
3 int outer_radius, inner_radius;
4 int ocx, ocy, icx, icy = 0;
5 
6 int ow, osw, os;
7 int iw, isw, is;
8 
9 int or2, ir2;
10 int odd;
11 
12 int ic_alive = 1;
13 int current_line = -1;
14 
15 if (thickness <= 0)
16 return;
17 
18 if (thickness == 1) {
19 circle(bmp, x, y, radius, color);
20 return;
21 }
22 
23 odd = ((thickness + 1) % 2);
24 outer_radius = radius + ((thickness - odd) / 2);
25 inner_radius = radius - ((thickness - odd) / 2) - odd;
26 
27 or2 = outer_radius * outer_radius;
28 ir2 = inner_radius * inner_radius;
29 
30 ocx = 0;
31 ocy = outer_radius;
32 icx = 0;
33 icy = inner_radius;
34 
35 do {
36 
37 ow = ((ocx + 1) * (ocx + 1)) + (ocy * ocy) - or2;
38 osw = ((ocx + 1) * (ocx + 1)) + ((ocy - 1) * (ocy - 1)) - or2;
39 os = (ocx * ocx) + ((ocy - 1) * (ocy - 1)) - or2;
40 
41 if ( ow < 0) ow *= -1;
42 if (osw < 0) osw *= -1;
43 if ( os < 0) os *= -1;
44 
45 
46 if (ic_alive == 1) {
47 iw = ((icx + 1) * (icx + 1)) + (icy * icy) - ir2;
48 isw = ((icx + 1) * (icx + 1)) + ((icy - 1) * (icy - 1)) - ir2;
49 is = (icx * icx) + ((icy - 1) * (icy - 1)) - ir2;
50 
51 if ( iw < 0) iw *= -1;
52 if (isw < 0) isw *= -1;
53 if ( is < 0) is *= -1;
54/*
55 }
56 if (ic_alive == 1)
57 {
58*/
59 if (ocx < icx) {
60 if ((ow < osw) && (ow < os)) ocx++;
61 if ((osw < ow) && (osw < os)) { ocx++; ocy--; }
62 if ((os < ow) && (os < osw)) ocy--;
63 }
64 }
65 else {
66 if ((ow < osw) && (ow < os)) ocx++;
67 if ((osw < ow) && (osw < os)) { ocx++; ocy--; }
68 if ((os < ow) && (os < osw)) ocy--;
69 }
70 
71 
72 if (ocx > current_line) {
73 if (ic_alive == 1) {
74 hline(bmp, x - ocy, y - ocx, x - icy, color);
75 hline(bmp, x + ocy, y - ocx, x + icy, color);
76 hline(bmp, x - ocy, y + ocx, x - icy, color);
77 hline(bmp, x + ocy, y + ocx, x + icy, color);
78 }
79 else {
80 hline(bmp, x - ocy, y - ocx, x + ocy, color);
81 hline(bmp, x - ocy, y + ocx, x + ocy, color);
82 }
83 current_line = ocx;
84 }
85 
86 if(icy < 0)
87 ic_alive = 0;
88 
89 if (ic_alive == 1) {
90 if ((iw < isw) && (iw < is)) icx++;
91 if ((isw < iw) && (isw < is)) { icx++; icy--; }
92 if ((is < iw) && (is < isw)) icy--;
93 }
94 
95 } while (ocy > 0);
96 
97}

The big question now is how do I add that to allegro

I added

   AL_METHOD(void, circlethick, (struct BITMAP *bmp, int x, int y, int radius, int thickness, int color));

to gfx.h

I then added the above function to gfx.c, I then tried to add "circlethick" to the vtables, and it didnt work, I tried "_circlethick" and "_soft_circlethick", no luck.

1src/vtable15.c:85: warning: initialization from incompatible pointer type
2src/vtable15.c:86: warning: initialization from incompatible pointer type
3src/vtable15.c:87: warning: initialization from incompatible pointer type
4src/vtable15.c:89: warning: initialization from incompatible pointer type
5src/vtable15.c:90: warning: initialization from incompatible pointer type
6src/vtable15.c:91: warning: initialization from incompatible pointer type
7src/vtable15.c:92: warning: initialization from incompatible pointer type
8src/vtable15.c:93: warning: initialization from incompatible pointer type
9src/vtable15.c:94: warning: initialization from incompatible pointer type
10src/vtable15.c:96: error: `_soft_circlethick' undeclared here (not in a function
11)
12src/vtable15.c:96: error: initializer element is not constant
13src/vtable15.c:96: error: (near initialization for `__linear_vtable15.quad3d_f')
14 
15make: *** [obj/mingw32/alleg/vtable15.o] Error 1

I don't even have a clue about how to add the function to the drivers? Which is probably what the problem is.

Sorry for all the pita questions, but I will make a wiki page explaining how to add functions

____________________________________________________________________________________________
"c is much better than c++ if you don't need OOP simply because it's smaller and requires less load time." - alethiophile
OMG my sides are hurting from laughing so hard... :D

Michael Jensen
Member #2,870
October 2002
avatar

again, what evert said: you're not accessing hardware directly, you're only calling primitives (hline is the only one I see), so why does it need to be added to a vtable/driver/etc?

Timorg
Member #2,028
March 2002

I am only going with what was said in the other thread, if you could explain how to add a function without doing all that, it would be great.

____________________________________________________________________________________________
"c is much better than c++ if you don't need OOP simply because it's smaller and requires less load time." - alethiophile
OMG my sides are hurting from laughing so hard... :D

Evert
Member #794
November 2000
avatar

You don't need to modify the vtables to add functions to Allegro.
Simply declare the function in one of Allegro's headerfiles as appropriate (include/allegro/gfx.h, say, be sure to copy the way other functions are declared) and add it to one of the source files (again as appropriate).
It can always be added to the vtables later if it makes sense to do so.

Go to: