arc4random() stopped working after project update, Thread 1: EXC_ARITHMETIC - cocos2d-iphone

I got a warning on xcode 6.0.1 that I needed to update my project, so I did...
...but then I got issues with arc4random() % instead
Everything was working fine before this update, but now I get the following message:
"Thread 1: EXC_ARITHMETIC (code = EXC_1386_DIV, Subcode = 0x0) and the game crashes.
I tried with arc4random_uniform but the game seems to "pause" and nothing happens. What I mean is that I could see that it entered the if(bType == pt || bType == pl) statement but there is seems to "pause" and loop endlessly.
any suggestions?
-(void)placeInGrid:(CGPoint)place pt:(int)pt pl:(int)pl amount:(int)amountOfbricks{
CCLOG(#"BRICKS:placeInGrid");
//CCLOG(#"pt %d", pt);
//CCLOG(#"pl %d", pl);
int bType = arc4random() % amountOfbricks;
//int bType = arc4random_uniform(amountOfbricks);
if(bType == pt || bType == pl){
CCLOG(#"bType == pt || bType == pl");
[self placeInGrid:place pt:pt pl:pl amount:amountOfbricks];
return;
}
else{
CCLOG(#"else");
CCSpriteBatchNode * b = (CCSpriteBatchNode *)[theGame getChildByTag:kSSheet];
mySprite = [CCSprite spriteWithBatchNode:b rect:[self setBrickType:bType]];
[b addChild:mySprite z:1];
self.bricksType =bType;
[self.mySprite setPosition:place];
}
}
UPDATE:
the if-else statement below looks for saved data at the beginning of the game, to see if it´s a saved game or a new game.
The problem as it seems, after the project update is that the game thinks that there is already saved data and it goes to the first if statement ( if(gameData)), causing amountofbricks to be equal to 0, instead of going into the else statement where amountofbricks is equal to 4.
I don´t know how to solve this issue.
if ([[GameManager sharedGameManager] isContinuePressed] == NO && [[GameManager sharedGameManager] isNewPressed] == YES) {
if(gameData){
CCLOG(#"gameData && isContinuePressed == NO && isNewPressed == YES");
//Set the local instance of myobject to the object held in the gameState filler with the key "myObject"
level = 1;
[[GameManager sharedGameManager] setHScore:[decoder decodeIntegerForKey:#"HighScore"]];
highscore = [[GameManager sharedGameManager] ReturnHScore];
countTime = 300;
AmountOfBricks = [[GameManager sharedGameManager] ReturnAmountOfBricks];
BeginningOfGame = YES;
CCLOG(#"AmountOfBricks %d", AmountOfBricks);
}
else{
CCLOG(#"!gameData && isContinuePressed == NO && isNewPressed == YES");
if([[GameManager sharedGameManager]isThereASavedGame] ==YES){
CCLOG(#"isThereASavedGame == YES");
score = 0;
highscore = [[GameManager sharedGameManager] ReturnHScore];
level = 1;
countTime = 300;
AmountOfBricks = 4;
BeginningOfGame = YES;
CCLOG(#"AmountOfBricks %d", AmountOfBricks);
}
else{
CCLOG(#"isThereASavedGame == NO");
score = 0;
highscore = 0;
level = 1;
countTime = 300;
AmountOfBricks = 4;
BeginningOfGame = YES;
CCLOG(#"AmountOfBricks %d", AmountOfBricks);
}
}
}
UPDATE: I found the issue.
the issue was in my game manager.m file.
NSMutableData *gameData;
NSKeyedUnarchiver *decoder = nil;
NSString *documentPath = [documentsDirectory stringByAppendingPathComponent: #"gameState.dat"];
gameData = [NSData dataWithContentsOfFile:documentPath];//before the update, I as using this line. was working perfectly. after the update I got a warning on this line "incompatible pointer" and xcode recommended to update to the line below but the line below started to return a zero value. which caused the game to crash.
//gameData = [NSMutableData dataWithData:[NSData dataWithContentsOfFile:documentPath]];

I wager amountOfBricks is 0. You can't modulo by 0 like you can't divide by 0.

Related

Omnet++ A cRuntimeError exception is about to be thrown std::length_error: basic_string::_M_create

so I get this error when i run my code
Error in module (TraCIDemoRSU11p) RSUExampleScenario.rsu[0].appl (id=8) at event #4000, t=45.40151998544: std::length_error: basic_string::_M_create.
TRAPPING on the exception above, due to a debug-on-errors=true configuration option. Is your debugger ready?
it shows that I have this issue at this line after looping multiple times
VehTD = *iteh2;
please be informed that I'm trying to remove from this vehicle list to another vehicle list and delete the moved items.
std::list<std::pair<std::string,std::string>>::const_iterator iteh2 = waitingList.begin();
for (std::list<std::pair<std::string,std::string>>::const_iterator iteh = waitingList.begin(); iteh != waitingList.end() && !waitingList.empty(); ){
iteh2 = iteh;
cout<<"Veh ID TF 1:";
cout<<VehTD.first<<endl;
cout<<VehTD.second<<endl;
VehTD = *iteh2;
cout<<"Veh ID TF 2:";
cout<<VehTD.first<<endl;
cout<<VehTD.second<<endl;
CompareResult3 = Locks(Locked,VehTD.second);
if(CompareResult3.second == 1 || CompareResult3.second == 2 ){
//remove from waiting and add to crossing
std::string ehk = "";
simtime_t VehicleT = simTime();
std::pair<std::pair<std::string, std::string>, simtime_t> VehicleWithTime;
crossingList.push_back(VehTD);
iteh2 = waitingList.erase(iteh2);
}
else{
++iteh;
}
}
}
I'm using Oment++ 5.0 and veins 4.4
I put a try and catch at this function, and it seems that the exception happens towards the end of the list.
Update:
I have this output:
WCounter 1
WCounter 2
Moving from waiting list Timer Function Exception
WCounter 1
WCounter 2
WCounter 3
Moving from waiting list Timer Function Exception
WCounter 1
WCounter 2
Moving from waiting list Timer Function Exception
The WCounter is a variable to show how many times it looped before having the exception at the point explained earlier.
based on request I added the locks function:
std::pair<std::list<std::string>,int> TraCIDemoRSU11p::Locks(std::list<std::string> alreadyLocked, std::string laneNo){
bool debugL;
//create variables for the lanes for easier use
try{
debugL = false;
zero = "171270266#0_0";
one = "171270266#0_1";
two = "-171270025#1_0";
three = "-171270025#1_1";
four = "-171270266#1_0";
five = "-171270266#1_1";
six = "171270025#0_0";
seven = "171270025#0_1";
//create lists of locks
Locks0 = Locks1 = Locks2 = Locks3 = Locks4 = Locks5 = Locks6 = Locks7 = RequestToLock = {};
CounterOfSimilarLanes = 0;
//set of 0 ,Locks0;
Locks0.push_back(zero);
Locks0.push_back(five);
Locks0.push_back(seven);
//set of 1 ,Locks1;
Locks1.push_back(one);
Locks1.push_back(three);
Locks1.push_back(six);
//set of 2 ,Locks2;
Locks2.push_back(one);
Locks2.push_back(two);
Locks2.push_back(seven);
//set of 3 ,Locks3;
Locks3.push_back(zero);
Locks3.push_back(three);
Locks3.push_back(five);
//set of 4 ,Locks4;
Locks4.push_back(one);
Locks4.push_back(three);
Locks4.push_back(four);
//set of 5 ,Locks5;
Locks5.push_back(two);
Locks5.push_back(five);
Locks5.push_back(seven);
//set of 6 ,Locks6;
Locks6.push_back(three);
Locks6.push_back(five);
Locks6.push_back(six);
//set of 7 ,Locks7;
Locks7.push_back(one);
Locks7.push_back(four);
Locks7.push_back(seven);
//This is the request to lock from the vehicle using its lane number
if (laneNo == zero ){
RequestToLock.insert(RequestToLock.end(),Locks0.begin(),Locks0.end());
}else if (laneNo == one){
RequestToLock.insert(RequestToLock.end(),Locks1.begin(),Locks1.end()) ;
}else if (laneNo == two){
RequestToLock.insert(RequestToLock.end(),Locks2.begin(),Locks2.end()) ;
}else if (laneNo == three){
RequestToLock.insert(RequestToLock.end(),Locks3.begin(),Locks3.end()) ;
}else if (laneNo == four){
RequestToLock.insert(RequestToLock.end(),Locks4.begin(),Locks4.end()) ;
}else if (laneNo == five){
RequestToLock.insert(RequestToLock.end(),Locks5.begin(),Locks5.end()) ;
}else if (laneNo == six){
RequestToLock.insert(RequestToLock.end(),Locks6.begin(),Locks6.end()) ;
}else if (laneNo == seven){
RequestToLock.insert(RequestToLock.end(),Locks7.begin(),Locks7.end()) ;
}
} //if the already locked from the controller is empty so we take the requested lock
catch(const std::exception &e){
cout<<"Preparing Locks Algorithm Exception"<<endl;
}
try{
if (alreadyLocked.empty()){
markOfLocks = 0;
alreadyLocked.insert(alreadyLocked.end(),RequestToLock.begin(),RequestToLock.end()) ;
Locked.insert(Locked.end(),RequestToLock.begin(),RequestToLock.end()) ;
if (debugL == true){
cout<<"First Lock in the locking algorithm"<<endl;
// dumplistLock(Locked);
}
ReturnOfLocks = make_pair(alreadyLocked,markOfLocks);
}else{ // if the already locked by the controller isnt empty, so we need to compare the request with it
//Search for similar items in the 2 lists
for(std::list<std::string>::/*const_*/iterator it_1 = alreadyLocked.begin();it_1 != alreadyLocked.end();)
{
for(std::list<std::string>::/*const_*/iterator it_2 = RequestToLock.begin(); it_2 != RequestToLock.end();)
{
if(*it_1 == *it_2)
{
++CounterOfSimilarLanes;
}
++it_2;
}
++it_1;
}
if (RequestToLock == alreadyLocked){
markOfLocks = 1;
Locked.clear();
Locked = {};
Locked.insert(Locked.end(),alreadyLocked.begin(),alreadyLocked.end()) ;
if (debugL == true){
cout<<"Same Lane"<<endl;
dumplistLock(Locked);
}
ReturnOfLocks = make_pair(alreadyLocked,markOfLocks);
}else if(CounterOfSimilarLanes == 0){ //if the request is concurrent meaning totally different locks
markOfLocks = 2;
//alreadyLocked.insert(alreadyLocked.end(),RequestToLock.begin(),RequestToLock.end()) ;
Locked.clear();
Locked = {};
Locked.insert(Locked.end(),alreadyLocked.begin(),alreadyLocked.end()) ;
if (debugL == true){
cout<<"Concurrent Lane"<<endl;
dumplistLock(Locked);
}
}else if(CounterOfSimilarLanes == 1 || CounterOfSimilarLanes == 2){ // if there's a similarity is 1 lock at least so it leads to conflict
markOfLocks = 3;
Locked.clear();
Locked = {};
Locked.insert(Locked.end(),alreadyLocked.begin(),alreadyLocked.end()) ;
if (debugL == true){
cout<< "opposite Lane"<<endl;
dumplistLock(Locked);
}
ReturnOfLocks = make_pair(alreadyLocked,markOfLocks);
}else{
markOfLocks = 1;
Locked.clear();
Locked.insert(Locked.end(),alreadyLocked.begin(),alreadyLocked.end()) ;
if (debugL == true){
cout<<"default case"<<endl;
dumplistLock(Locked);
}
ReturnOfLocks = make_pair(alreadyLocked,markOfLocks);
}
}
}catch(const std::exception &e){
cout<<"Lock Cases Exceptions"<<endl;
}
try{
return ReturnOfLocks;
}catch(const std::exception &e){
cout<<"No Return of Locks in Locks Alg Exception"<<endl;
}
}
so I changed the for loop to a while loop and it didn't show an exception, and not sure why.
therefore the loop looks like this now:
//while loop instead.
std::list<std::pair<std::string,std::string>>::iterator iterwil = waitingList.begin();
std::pair<std::string, std::string> Vehwil ;
while (iterwil != waitingList.end()){
Vehwil = *iterwil;
CompareResult3 = Locks(Locked,Vehwil.second);
if(CompareResult3.second == 1 || CompareResult3.second == 2 ){
crossingList.push_back(Vehwil);
waitingList.erase(iterwil++);
}else{
++iterwil;
}
}
if someone has a valid reason to enlighten me on why the while loop works with no exception unlike the for loop that would be great. ^^"
You should use iterator instead of const_iterator because you modify (i.e. delete) indicated element.
By the way, in the code iteh2 is unnecessary - iteh is sufficient as well as VehicleT and ehk variables are not used and may be removed.

SDL2 Side scrolling variable not accruing

I have a cat game I have been working on in pygame that I am now writing in c++ SDL2 which are similar. But I have a weird specific problem. A variable in my level.cc class doesn't accrue with old += new in the move() function I am thinking that it is being set to 0 somewhere or my scope is off but I am just lost. I will post the files that are pertinent here and then link to my github as well. I appreciate your time and help.
The level.cc file:
void Level::move(int newx){
groundX += newx;
}
and the cat.cc file:
void Cat::move(int screenSize, Level l){
if((catmX + mVelX > 0) && (catmX + mVelX + (catwidth / 2) < (screenSize * .70))){
catmX += mVelX;
} else if(catmX + mVelX + (catwidth / 2) >= (screenSize * .70)){
l.move(CAT_VEL);
catmY += mVelY;
}
}
and the main:
string grndLoc = "src/grass.png";
Level level1(extra.loadTexture(grndLoc, extra.getRen()), extra.getHeight());
string backgroundImage = "src/sky.png";
SDL_Texture *bck = extra.loadTexture(backgroundImage, extra.getRen());
if(bck == nullptr){
extra.destroyer(bck);
extra.quitGame();
return 1;
}
SDL_Event e;
bool quit = false;
while(!quit){
while(SDL_PollEvent(&e)){
if(e.type == SDL_QUIT){
quit = true;
}
switch(e.key.keysym.sym){
case SDLK_ESCAPE:
quit = true;
break;
}
catplayer.handleEvent(e);
}
SDL_RenderClear(extra.getRen());
extra.renderTexture(bck, extra.getRen(), 0, 0, extra.getWidth(), extra.getHeight());
level1.rend(extra);
extra.renderTexture(catplayer.getTexture(), extra.getRen(), catplayer.getX(), catplayer.getY(), catplayer.getclip());
SDL_RenderPresent(extra.getRen());
catplayer.move(extra.getWidth(), level1);
https://github.com/ironsketch/catGamecpp
My teacher made mention that I was probably calling the constructor somewhere! I found that I was passing a copy of the level and not a pointer to the level!
void Cat::move(int screenSize, Level l){
So I changed it to
void Cat::move(int screenSize, Level *l){
I updated a few other things to reflect that I am now using a pointer and it's fixed! Thanks everyone who responded <3

Pops / clicks when stopping and starting DirectX sound synth in C++ / MFC

I have made a soft synthesizer in Visual Studio 2012 with C++, MFC and DirectX. Despite having added code to rapidly fade out the sound I am experiencing popping / clicking when stopping playback (also when starting).
I copied the DirectX code from this project: http://www.codeproject.com/Articles/7474/Sound-Generator-How-to-create-alien-sounds-using-m
I'm not sure if I'm allowed to cut and paste all the code from the Code Project. Basically I use the Player class from that project as is, the instance of this class is called m_player in my code. The Stop member function in that class calls the Stop function of LPDIRECTSOUNDBUFFER:
void Player::Stop()
{
DWORD status;
if (m_lpDSBuffer == NULL)
return;
HRESULT hres = m_lpDSBuffer->GetStatus(&status);
if (FAILED(hres))
EXCEP(DirectSoundErr::GetErrDesc(hres), "Player::Stop GetStatus");
if ((status & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING)
{
hres = m_lpDSBuffer->Stop();
if (FAILED(hres))
EXCEP(DirectSoundErr::GetErrDesc(hres), "Player::Stop Stop");
}
}
Here is the notification code (with some supporting code) in my project that fills the sound buffer. Note that the rend function always returns a double between -1 to 1, m_ev_smps = 441, m_n_evs = 3 and m_ev_sz = 882. subInit is called from OnInitDialog:
#define FD_STEP 0.0005
#define SC_NOT_PLYD 0
#define SC_PLYNG 1
#define SC_FD_OUT 2
#define SC_FD_IN 3
#define SC_STPNG 4
#define SC_STPD 5
bool CMainDlg::subInit()
// initialises various variables and the sound player
{
Player *pPlayer;
SOUNDFORMAT format;
std::vector<DWORD> events;
int t, buf_sz;
try
{
pPlayer = new Player();
pPlayer->SetHWnd(m_hWnd);
m_player = pPlayer;
m_player->Init();
format.NbBitsPerSample = 16;
format.NbChannels = 1;
format.SamplingRate = 44100;
m_ev_smps = 441;
m_n_evs = 3;
m_smps = new short[m_ev_smps];
m_smp_scale = (int)pow(2, format.NbBitsPerSample - 1);
m_max_tm = (int)((double)m_ev_smps / (double)(format.SamplingRate * 1000));
m_ev_sz = m_ev_smps * format.NbBitsPerSample/8;
buf_sz = m_ev_sz * m_n_evs;
m_player->CreateSoundBuffer(format, buf_sz, 0);
m_player->SetSoundEventListener(this);
for(t = 0; t < m_n_evs; t++)
events.push_back((int)((t + 1)*m_ev_sz - m_ev_sz * 0.95));
m_player->CreateEventReadNotification(events);
m_status = SC_NOT_PLYD;
}
catch(MATExceptions &e)
{
MessageBox(e.getAllExceptionStr().c_str(), "Error initializing the sound player");
EndDialog(IDCANCEL);
return FALSE;
}
return TRUE;
}
void CMainDlg::Stop()
// stop playing
{
m_player->Stop();
m_status = SC_STPD;
}
void CMainDlg::OnBnClickedStop()
// causes fade out
{
m_status = SC_FD_OUT;
}
void CMainDlg::OnSoundPlayerNotify(int ev_num)
// render some sound samples and check for errors
{
ScopeGuardMutex guard(&m_mutex);
int s, end, begin, elapsed;
if (m_status != SC_STPNG)
{
begin = GetTickCount();
try
{
for(s = 0; s < m_ev_smps; s++)
{
m_smps[s] = (int)(m_synth->rend() * 32768 * m_fade);
if (m_status == SC_FD_IN)
{
m_fade += FD_STEP;
if (m_fade > 1)
{
m_fade = 1;
m_status = SC_PLYNG;
}
}
else if (m_status == SC_FD_OUT)
{
m_fade -= FD_STEP;
if (m_fade < 0)
{
m_fade = 0;
m_status = SC_STPNG;
}
}
}
}
catch(MATExceptions &e)
{
OutputDebugString(e.getAllExceptionStr().c_str());
}
try
{
m_player->Write(((ev_num + 1) % m_n_evs)*m_ev_sz, (unsigned char*)m_smps, m_ev_sz);
}
catch(MATExceptions &e)
{
OutputDebugString(e.getAllExceptionStr().c_str());
}
end = GetTickCount();
elapsed = end - begin;
if(elapsed > m_max_tm)
m_warn_msg.Format(_T("Warning! compute time: %dms"), elapsed);
else
m_warn_msg.Format(_T("compute time: %dms"), elapsed);
}
if (m_status == SC_STPNG)
Stop();
}
It seems like the buffer is not always sounding out when the stop button is clicked. I don't have any specific code for waiting for the sound buffer to finish playing before the DirectX Stop is called. Other than that the sound playback is working just fine, so at least I am initialising the player correctly and notification code is working in that respect.
Try replacing 32768 with 32767. Not by any means sure this is your issue, but it could overflow the positive short int range (assuming your audio is 16-bit) and cause a "pop".
I got rid of the pops / clicks when stopping playback, by filling the buffer with zeros after the fade out. However I still get pops when re-starting playback, despite filling with zeros and then fading back in (it is frustrating).

saving contact bodies to be destroyed

In my code I would like to destroy one of two contacted bodies. Within the beginContact the following method in CCPhysicsSprite is called:
-(void)contactMade:(CCPhysicsSprite*)contactedSprite {
int spriteTag1 = self.tag;
int spriteTag2 = contactedSprite.tag;
if (((spriteTag1 == 3) && (spriteTag2 == 4)) || ((spriteTag1 == 4) && (spriteTag2 == 3)) {
CCPhysicsSprite* heroSprite = (CCPhysicsSprite*)[self getChildByTag:4];
b2World* world;
world->DestroyBody(heroSprite.b2Body);
heroSprite.b2Body = NULL;
[heroSprite.parent removeChild:heroSprite];
}
I get a signal SIGABRT pointing to
b2Assert(m_bodyCount > 0);
After searching on this issue. I read that the contact body has to be saved and destroyed after the timestep. How can I do this, given that I have set my contact conditions in the CCPhyscisSprite.
You can add a flag ( like : isDead ... ) to your physical object and in collision event just change that flag value to TRUE .
-(void) CollisionBegin:(b2Fixture*)target With:(b2Fixture*) source
{
if ( target->GetBody()->GetType() == b2_dynamicBody)
{
yourCustomClass *temp = (yourCustomClass *)target->GetBody()->GetUserData();
temp->isDead = true ;
}
}
Then in update function after step get all physical world's object and find that specific object by flag ( Here : isDead ) , and destroy that .
-(void) update: (ccTime) dt
{
int32 velocityIterations = 8;
int32 positionIterations = 3;
world->Step(dt, velocityIterations, positionIterations);
// remove your box2d object here , after step function
for ( b2Body *b = world->GetBodyList(); b; )
{
b2Body *baba = b->GetNext();
if ( b->GetUserData() != NULL && b->GetType() == b2_dynamicBody)
{
yourCustomClass *t = (yourCustomClass *)b->GetUserData();
if ( t->isDead )
{
world->DestroyBody(b); // remove physical body
[self removeChild:t]; // remove node from super layer
}
}
b = baba ;
}
}

strange contact between bodies

I have a strange problem.
the shot of my players, when it collides with a body, destroys it without problems, but, when it hits the two bodies at once, it crashes.
shooting player
b2Body *shooting = [_lhelper newBodyWithUniqueName:#"shoot" world:_world];
CCSprite *shootingSprite = (CCSprite *)shootingBody->GetUserData();
shootingBody.position = pos;
shootingBody->SetTransform(b2Vec2(pos.x/PTM_RATIO,
pos.y/PTM_RATIO),
CC_DEGREES_TO_RADIANS(angle));
contact
if([spriteA tag] == ENEMY && [spriteB tag] == SHOT)
{
int animIdx = [(NSNumber*)[spriteA userData] intValue];
if(animIdx < 2)
{
[spriteA setTextureRect:MY_RECTS[animIdx]];
[spriteA setUserData:[NSNumber numberWithInt:animIdx+1]];
}
else
{
[objectThatWillBeDeleted addObject:[NSValue valueWithPointer:bodyA]];
}
[objectThatWillBeDeleted addObject:[NSValue valueWithPointer:bodyB]];
}
else if([spriteB tag] == ENEMY && [spriteA tag] == SHOT)
{
int animIdx = [(NSNumber*)[spriteB userData] intValue];
if(animIdx < 2)
{
[spriteB setTextureRect:MY_RECTS[animIdx]];
[spriteA setUserData:[NSNumber numberWithInt:animIdx+1]];
}
else
{
[objectThatWillBeDeleted addObject:[NSValue valueWithPointer:bodyB]];
}
[objectThatWillBeDeleted addObject:[NSValue valueWithPointer:bodyA]];
}
update
std::vector<Contact>::iterator pos;
for(pos = _contactListener->_contacts.begin();
pos != _contactListener->_contacts.end(); ++pos)
{
Contact contact = *pos;
//[self checkBodies2:&contact];
}
for(NSValue* val in objectThatWillBeDeleted)
{
b2Body* body = (b2Body*)[val pointerValue];
[_lhelper removeBody:body];
}
[objectThatWillBeDeleted removeAllObjects];
}
}
I do not understand where the error.
I do not understand where the error either because you didn't say where it crashes :)
But I would guess you are trying to destroy the same body twice.
When the shot hits two enemies in the same time step, the shot body gets added to the objectThatWillBeDeleted list twice. You just need to make that list unique before you destroy the contents of it.