AllegroTimer Class trouble
iLSILENT

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:

1class AllegroTimer {
2public:
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 
13private:
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};

CGamesPlay
Quote:

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.

install_param_int_ex

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.

Kitty Cat

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 
9class Timer {
10protected:
11 unsigned long current_tic;
12 unsigned long usecs_per_tic;
13 struct timeval now, last;
14 
15public:
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 
64class Timer {
65protected:
66 DWORD current_tic;
67 DWORD clocks_per_tic;
68 DWORD now, last;
69 
70public:
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).

iLSILENT

thank you for your replies!
p.s. i never wrote "I'm dumb", it is probably a joke of the moderator...

CGamesPlay

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 :P Anyways, it was just terribly appropriate ;)

Richard Phipps

I'm dumb!

doh!

iLSILENT

eheheheh!
I'd suggest to make people read a disclaimer before subscrive this forum ;D
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 
8class 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 
37inline 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 
50inline 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 
67inline 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 
82inline 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 
95inline 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 
110inline 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!

Audric

[OT]CGamesPlay, how did YOU manage to write it then? ??? Even |o| is not quite the same...[/OT]

CGamesPlay

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:
<math>|{M_{no} - {{3*(2*M_{no} + 1000)  +45000} \over 6} - (3738 + M_{no})}| < 3354</math>
(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.

Jakub Wasilewski

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.

Thread #586954. Printed from Allegro.cc