hi to all!
I'm trying to organize the allegro timer in an unique class in order to speed up programming with allegro. the target is: create a class so i just have to instantiate an AllegroTimer object in main like this:
AllegroTimer timer(eventual_bps);
I declared static the IncSpeedCounter method and the speed_counter property to get rid of the function pointer requested by install_int_ex, but when i try to instantiate an object of this class the compiler can't misteriously resolve some links. I'm using VC++8 and don't know if with other compilers this will work instead.
Suggestions, changes to the codes, ideas...are all welcome. Tnx!
P.S.: i'm dealing with Allegro sice yesterday (I'm dumb!) so i don't know if this can be accomplished in a easier and more convenient way.
This is the class:
1 | class AllegroTimer { |
2 | public: |
3 | //constructor |
4 | AllegroTimer(int beats = 60){ |
5 | this->bps = beats; |
6 | install_timer(); |
7 | install_int_ex(&AllegroTimer::IncSpeedCounter, BPS_TO_TIMER(this->bps)); |
8 | AllegroTimer::speed_counter = 0; |
9 | LOCK_VARIABLE(AllegroTimer::speed_counter); |
10 | LOCK_FUNCTION(&AllegroTimer::IncSpeedCounter); |
11 | } |
12 | |
13 | private: |
14 | int bps; |
15 | static volatile long speed_counter; |
16 | static void IncSpeedCounter(){ |
17 | AllegroTimer::speed_counter++; |
18 | } |
19 | END_OF_FUNCTION(&AllegroTimer::IncSpeedCounter) |
20 | }; |
I'm dumb! so i don't know if this can be accomplished in a easier and more convenient way.
At least you're honest
First, please read this and use [code] tags.
About the code:
IIRC one may only have one timer interrupt per function. However, you may use the install_param_int_ex function to have mulitples, just use the this variable as the parameter.
You will need to use an instance member (not a static member) to store the speed_counter, otherwise you will only be able to have one instance.
If you're using a class to run as a timer, you may want to think about using methods other than Allegro's timers, as they're rather innaccurate. For example, this timer class I have runs off gettimeofday on most systems, or timeGetTime on Windows (which is a bit more accurate than Allegro's timers). I could use QueryPerformanceFrequency/Counter, but I've been lazy on properly using the LARGE_INTGETER type.
1 | #ifndef TIMER_H |
2 | #define TIMER_H |
3 | |
4 | #include <allegro.h> |
5 | |
6 | #ifndef ALLEGRO_WINDOWS |
7 | #include <sys/time.h> |
8 | |
9 | class Timer { |
10 | protected: |
11 | unsigned long current_tic; |
12 | unsigned long usecs_per_tic; |
13 | struct timeval now, last; |
14 | |
15 | public: |
16 | // Starts the timer, generating 'speed' tics per second |
17 | void init(int speed) |
18 | { |
19 | current_tic = 0; |
20 | usecs_per_tic = 1000000 / speed; |
21 | reset(); |
22 | }; |
23 | |
24 | // Resets the timer, leaving the tic count alone |
25 | void reset() |
26 | { |
27 | gettimeofday(&last, NULL); |
28 | now = last; |
29 | }; |
30 | |
31 | // Store the current tic in _tic, and return the number of tics since the |
32 | // last call |
33 | unsigned long get_tics(unsigned long &_tic) |
34 | { |
35 | gettimeofday(&now, NULL); |
36 | unsigned long c = ((unsigned long)(now.tv_sec-last.tv_sec)*1000000 + |
37 | (unsigned long)(now.tv_usec-last.tv_usec)) / |
38 | usecs_per_tic; |
39 | |
40 | last.tv_usec += usecs_per_tic * c; |
41 | last.tv_sec += last.tv_usec/1000000; |
42 | last.tv_usec %= 1000000; |
43 | |
44 | current_tic += c; |
45 | _tic = current_tic; |
46 | return c; |
47 | }; |
48 | unsigned long get_tics() |
49 | { |
50 | unsigned long dummy; |
51 | return get_tics(dummy); |
52 | } |
53 | void rewind_tics(unsigned long val) |
54 | { |
55 | current_tic -= val; |
56 | } |
57 | }; |
58 | |
59 | #else |
60 | |
61 | #include <winalleg.h> |
62 | #include <mmsystem.h> |
63 | |
64 | class Timer { |
65 | protected: |
66 | DWORD current_tic; |
67 | DWORD clocks_per_tic; |
68 | DWORD now, last; |
69 | |
70 | public: |
71 | void init(int speed) |
72 | { |
73 | current_tic = 0; |
74 | clocks_per_tic = 1000 / speed; |
75 | reset(); |
76 | }; |
77 | |
78 | void reset() |
79 | { |
80 | last = timeGetTime(); |
81 | now = last; |
82 | }; |
83 | |
84 | unsigned long get_tics(unsigned long &_tic) |
85 | { |
86 | now = timeGetTime(); |
87 | DWORD c = (now-last) / clocks_per_tic; |
88 | |
89 | last += clocks_per_tic * c; |
90 | |
91 | current_tic += c; |
92 | _tic = current_tic; |
93 | return (unsigned long)c; |
94 | }; |
95 | unsigned long get_tics() |
96 | { |
97 | unsigned long dummy; |
98 | return get_tics(dummy); |
99 | } |
100 | |
101 | void rewind_tics(unsigned long val) |
102 | { |
103 | current_tic -= val; |
104 | } |
105 | }; |
106 | |
107 | #endif // _WIN32 |
108 | |
109 | #endif |
The init() method is used to start it ticking the specified amount of times per second. The reset() method is for if you've neglected to read the ticks and don't want to deal with a jump in time (like after pausing, or switching levels or something). The get_tics method returns the the number of times it's ticked since the last call, and optionally storing the total number of times it's ticked in the supplied unsigned long variable. The rewind ticks method is used if you want to back up, say after getting an unexpectedly large return value from get_tics and not wanting to handle them all right now, or if you want to fully reset the timer to 0 (along with calling the reset method).
thank you for your replies!
p.s. i never wrote "I'm dumb", it is probably a joke of the moderator...
Any time you type I'm dumb! in this forum, it is converted to "I'm dumb!". Never, ever, use the expression 'I'm dumb!'. It is terrible and will make everyone respectable hate you Anyways, it was just terribly appropriate
I'm dumb!
doh!
eheheheh!
I'd suggest to make people read a disclaimer before subscrive this forum
and maybe theese misunderstandigs won't happen.
Anyway.................. . .. . .I'm dumb! !
post continued:
ok, thanks for the help. i made it up with another timer class (quite good)
here is the code if anyone need it:
1 | #ifndef TIMER_H |
2 | #define TIMER_H |
3 | |
4 | #include <ctime> |
5 | #include <iostream> |
6 | #include <iomanip> |
7 | |
8 | class Timer { |
9 | friend std::ostream& operator<<(std::ostream& os, Timer& t); |
10 | |
11 | private: |
12 | bool running; |
13 | clock_t start_clock; |
14 | time_t start_time; |
15 | double acc_time; |
16 | |
17 | public: |
18 | // 'running' is initially false. A timer needs to be explicitly started |
19 | // using 'start' or 'restart' |
20 | Timer() : running(false), start_clock(0), start_time(0), acc_time(0) { } |
21 | |
22 | |
23 | void Start(const char* msg = 0); |
24 | void Restart(const char* msg = 0); |
25 | void Stop(const char* msg = 0); |
26 | double ElapsedTime(); |
27 | void PrintInfo(const char* msg = 0); |
28 | |
29 | }; // class timer |
30 | |
31 | //=========================================================================== |
32 | // Return the total time that the timer has been in the "running" |
33 | // state since it was first "started" or last "restarted". For |
34 | // "short" time periods (less than an hour), the actual cpu time |
35 | // used is reported instead of the elapsed time. |
36 | |
37 | inline double Timer::ElapsedTime(){ |
38 | time_t acc_sec = time(0) - start_time; |
39 | if (acc_sec < 3600) |
40 | return (clock() - start_clock) / (1.0 * CLOCKS_PER_SEC); |
41 | else |
42 | return (1.0 * acc_sec); |
43 | |
44 | } // Timer::ElapsedTime |
45 | |
46 | //=========================================================================== |
47 | // Start a timer. If it is already running, let it continue running. |
48 | // Print an optional message. |
49 | |
50 | inline void Timer::Start(const char* msg){ |
51 | // Print an optional message, something like "Starting timer t"; |
52 | if (msg) std::cout << msg << std::endl; |
53 | |
54 | // Return immediately if the timer is already running |
55 | if (running) return; |
56 | |
57 | // Set timer status to running and set the start time |
58 | running = true; |
59 | start_clock = clock(); |
60 | start_time = time(0); |
61 | |
62 | } // Timer::Start |
63 | |
64 | //=========================================================================== |
65 | // Turn the timer off and start it again from 0. Print an optional message. |
66 | |
67 | inline void Timer::Restart(const char* msg){ |
68 | // Print an optional message, something like "Restarting timer t"; |
69 | if (msg) std::cout << msg << std::endl; |
70 | |
71 | // Set timer status to running, reset accumulated time, and set start time |
72 | running = true; |
73 | acc_time = 0; |
74 | start_clock = clock(); |
75 | start_time = time(0); |
76 | |
77 | } // Timer::Restart |
78 | |
79 | //=========================================================================== |
80 | // Stop the timer and print an optional message. |
81 | |
82 | inline void Timer::Stop(const char* msg){ |
83 | // Print an optional message, something like "Stopping timer t"; |
84 | if (msg) std::cout << msg << std::endl; |
85 | |
86 | // Compute accumulated running time and set timer status to not running |
87 | if (running) acc_time += ElapsedTime(); |
88 | running = false; |
89 | |
90 | } // Timer::Stop |
91 | |
92 | //=========================================================================== |
93 | // Print out an optional message followed by the current timer timing. |
94 | |
95 | inline void Timer::PrintInfo(const char* msg){ |
96 | // Print an optional message, something like "Checking timer t"; |
97 | if (msg) std::cout << msg << " : "; |
98 | |
99 | std::cout << "Elapsed time [" << std::setiosflags(std::ios::fixed) |
100 | << std::setprecision(2) |
101 | << acc_time + (running ? ElapsedTime() : 0) << "] seconds\n"; |
102 | |
103 | } // Timer::PrintInfo |
104 | |
105 | //=========================================================================== |
106 | // Allow timers to be printed to ostreams using the syntax 'os << t' |
107 | // for an ostream 'os' and a timer 't'. For example, "cout << t" will |
108 | // print out the total amount of time 't' has been "running". |
109 | |
110 | inline std::ostream& operator<<(std::ostream& os, Timer& t){ |
111 | os << std::setprecision(2) << std::setiosflags(std::ios::fixed) |
112 | << t.acc_time + (t.running ? t.ElapsedTime() : 0); |
113 | return os; |
114 | } |
115 | |
116 | //=========================================================================== |
117 | |
118 | #endif // TIMER_H |
see ya!
[OT]CGamesPlay, how did YOU manage to write it then? Even |o| is not quite the same...[/OT]
If you take your member number and multiply it by two, then add 1000, then multiply this number by 3, then add 45 thousand, divide the whole thing by 6, and finally subtract 3738 plus your member number, you get your "censorship index" (I don't remember what exactly the moderator called it). Basically, if this number is within 3354 of your member number, you can use that phrase and all manner of swear words without being censored. The formula, once again:
(rearranged as an inequality for ease)
[append]
This is actually only a linear approximation of the actual formula. Admittedly, the real formula is simpler, but requires trigonometry, so I didn't post it. But this one works for most users.
Or, if you are one of the unfortunate users whose swearword index is bigger than 3354, you could try using empty i or b markers to break the word in two parts. But that's for sissies. Real men just register accounts until they get a preferable swearword index.