gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Expanding my event system from 32 to 64 bits

#171397 - headspin - Wed Nov 18, 2009 11:14 am

In my game I have a basic event system that turns bits on to trigger certain events. I use an enum to specify which event is which bit.

Code:
enum EventFlag
{
   EVENTFLAG_NONE = 0,
   EVENTFLAG_EVENT1 = BIT(0),
   EVENTFLAG_EVENT2 = BIT(1),
   ...
   EVENTFLAG_EVENT30 = BIT(29),
   EVENTFLAG_EVENT31 = BIT(30),
   EVENTFLAG_EVENT32 = BIT(31)
};


And I have a global 32 bit uint to store all these flags

Code:
uint m_eventFlags;


And to check if a certain event has occured I do

Code:
if ((eventFlags & m_eventFlags) == eventFlags)


Which just checks if the bits that are set match those needed to trigger the event.

Now I've realised I need to expand this beyond the 32 bits and it's too late for me to come up with a different method of doing things. What is the easiest way to expand this to be 64 bits? I tried using a uint64 instead and get an error in the enum

Code:
warning: left shift count >= width of type


Then I tried changing the enum to uint64

Code:
enum EventFlag : uint64


Then I get the error

Code:
warning: scoped enums only available with -std=c++0x or -std=gnu++0x


So then I added -std=c++0x to the compiler options and then get

Code:
error: enumerator value -0x00000000080000000 is too large for underlying type 'uint64'


And still get the "left shift count >= width of type" error. Will I need to split the flags into two 32-bit integers or perhaps a union? Any ideas on how to expand this without re-writing large chunks of the event system?
_________________
Warhawk DS | Manic Miner: The Lost Levels | The Detective Game

#171400 - sverx - Wed Nov 18, 2009 12:50 pm

mmm... replacing enums with defines?

#171404 - Cearn - Wed Nov 18, 2009 1:09 pm

0x00000000080000000 is 0x0_0000_0000_8000_0000. You may have one too many zeroes.

IIRC, you can also use the 'LL' extension for long long constants. I'm not sure what happens to the numbers if you don't.

#171405 - headspin - Wed Nov 18, 2009 1:34 pm

I checked and definately not putting in too many zeros. A guy suggested I try doing:

Code:
const static unit64 EVENTFLAG_NONE = 0;
const static unit64 EVENT_1 = BIT(1);


But I still get "warning: left shift count >= width of type" for everything above BIT(31). This seems really strange to me.
_________________
Warhawk DS | Manic Miner: The Lost Levels | The Detective Game

#171408 - headspin - Wed Nov 18, 2009 2:10 pm

Okay it's fixed with this modified macro

Code:
#define BIT64(n) (1LL << (n))

_________________
Warhawk DS | Manic Miner: The Lost Levels | The Detective Game

#171414 - ant512 - Wed Nov 18, 2009 4:27 pm

How about using a struct instead?

Code:

typedef struct {
    int event1 : 1;
    int event2 : 1;
    int event3 : 1;
    ...
    int event64 : 1;
} EventArgs;


To set an event:

Code:

EventArgs e;
e.event1 = 1;
e.event3 = 1;


To check an event:

Code:

if (e.event1 & e.event3) {
    // Some event has occurred involving 1 and 3
}


The struct is packed so that each component consumes just one bit. It should therefore get passed around as a 64-bit data structure. It's also far easier to work with - and more extensible - than a bitmask.

EDIT: Ah, didn't see that it's too late to change the approach. Still, one for next time maybe.

#171448 - headspin - Thu Nov 19, 2009 8:40 pm

I will definately try something like that in the future ant512 at the time I didn't think there would be more than 32 events.
_________________
Warhawk DS | Manic Miner: The Lost Levels | The Detective Game

#171697 - Lick - Mon Dec 14, 2009 10:56 pm

I'm curious, ant512, what happens if you do e.event1 = 1234; What will the compiler do?

(I don't have the tools installed to try myself).

update: I tried this at codepad:
Code:
struct Events {
  int e1 : 1;
  int e2 : 1;
};

int main () {
  Events ev;

  ev.e1 = 3;

  printf("%i, %i", ev.e1, ev.e2);
}

It prints 1, 0. Seems like only the bits allocated for ev1 are written to. It doesn't overwrite ev2.
_________________
http://licklick.wordpress.com