/** * \fn void speedBombReaction(Worms* pWorms, int centerX, int centerY, int radius * \brief Applies speed and dammage according to the position of the worms to the center of the explosion. * * \param[in] pWorms, pointer to the worms. * \param[in] centerX, X coordinate of the center of the cercle of the explosion. * \param[in] centerY, Y coordinate of the center of the cercle of the explosion. * \param[in] radius, radius of the explosion. * \returns void */ void speedBombReaction(Worms* pWorms, int centerX, int centerY, int radius) { int middleX = pWorms->wormsObject->objectBox.x + pWorms->wormsObject->objectBox.w / 2; int middleY = pWorms->wormsObject->objectBox.y + pWorms->wormsObject->objectBox.h / 2; float signeX = 1.0, signeY = 1.0, distanceX = 0, distanceY = 0; if (middleX < centerX) { signeX = -1.0; if (middleY > centerY) { signeY = -1.0; } } //calcul de la distance par rapport au centre distanceX = MY_ABS((middleX - centerX)) / (float)radius; distanceY = MY_ABS((middleY - centerY)) / (float)radius; double decrease = sqrt(CARRE(distanceX) + CARRE(distanceY)); if (decrease <= 0.35) { pWorms->wormsObject->Xspeed = (float)(vitesseX * BombFactor * signeX*1.0 / 0.35); pWorms->wormsObject->Yspeed = (float)(vitesseY * BombFactor * signeY*1.0 / 0.35); pWorms->vie -= (int)(MAXDAMAGE * 1.0 / 0.35); } else { pWorms->wormsObject->Xspeed = (float)(vitesseX * BombFactor * signeX * 1.0 / decrease); pWorms->wormsObject->Yspeed = (float)(vitesseY * BombFactor * signeY * 1.0 / decrease); pWorms->vie -= (int)(MAXDAMAGE * 1.0 / decrease); } wormsDead(pWorms, 0); }
/** * \fn int collisionSurfaceWithMap(SDL_Surface* pSurfaceMap, SDL_Surface* pSurfaceMotion, enum DIRECTION* pDirection) * \brief Detecte s'il y a collision entre deux surfaces selon le sens de déplacement du worms. * * \param[in] pSurfaceMap, pointer to the surface of the map. * \param[in] pSurfaceMotion, pointer to the surface in motion. * \param[in] pDirection, pointer to the object direction. * \returns int, indicateur de collision : 1 = collision, 0 sinon */ int collisionSurfaceWithMap(SDL_Surface* pSurfaceMap, SDL_Surface* pSurfaceMotion, enum DIRECTION* pDirection, int checkMode) { //Variables d'acquisitions Uint32 pixelS1 = 0; //Variable stockant le pixel en cours de lecture de la surface de la map Uint8 rS1 = 0, gS1 = 0, bS1 = 0, aS1 = 0; //Variables stockant les informations sur les couleurs du pixel lu de la surface de la map Uint32 pixelS2 = 0; //Variable stockant le pixel en cours de lecture de la surface en mouvement Uint8 rS2 = 0, gS2 = 0, bS2 = 0, aS2 = 0; //Variables stockant les informations sur les couleurs du pixel lu de la surface en mouvement int offset_xS2 = pSurfaceMotion->clip_rect.x; //Offset en x de la surface en mouvement dans la map int offset_yS2 = pSurfaceMotion->clip_rect.y; //Offset en y de la surface en mouvement dans la map SDL_PixelFormat* formatS1 = pSurfaceMap->format; //Pointeur du format de pixels de la surface de la map SDL_PixelFormat* formatS2 = pSurfaceMotion->format; //Pointeur du format de pixels de la surface en mouvement //Variables de balayage int x = 0, y = 0; //Variables de balayage des x, y int xStart = pSurfaceMotion->clip_rect.x, xEnd = pSurfaceMotion->clip_rect.x + pSurfaceMotion->clip_rect.w, xInc = 1; //Variables de début, de fin et d'incrément du balayage des x int yStart = pSurfaceMotion->clip_rect.y, yEnd = pSurfaceMotion->clip_rect.y + pSurfaceMotion->clip_rect.h, yInc = 1; //Variables de début, de fin et d'incrément du balayage des y int zone[4] = { 0, 0, 0, 0 }, balayageGen = 0; //Variable de collision int collision = 0; //Booleen de collision, 0 = pas de collision, 1 = collision /*Test des limites de la map et de la fenetre*/ if (collisionSurfaceWithMapLimits(pSurfaceMap, pSurfaceMotion)) //Detection d'un dépassement de la map return 1; /*Détermination de l'ordre des zones à balayer*/ calculOrdreBalayage(*pDirection, zone); for (balayageGen = 0; (balayageGen < 4) && (collision == 0); balayageGen += 1) { /*Détermination de yStart, yEnd, xStart et xEnd*/ calculXYBalayage(pSurfaceMotion, &xStart, &xEnd, &yStart, &yEnd, zone[balayageGen]); //Calcul des valeurs de balayage des boucles for pour optimiser la vitesse de traitement /*Calcul de la collision*/ for (y = yStart; (y < yEnd) && (collision == 0); y += yInc) { for (x = xStart; (x < xEnd) && (collision == 0); x += xInc) { /*Acquisition des pixels des surfaces 1 et 2*/ pixelS1 = ReadPixel(pSurfaceMap, MY_ABS(x), MY_ABS(y)); //Lecture du pixel de la map pixelS2 = ReadPixel(pSurfaceMotion, MY_ABS(x) - offset_xS2, MY_ABS(y) - offset_yS2); //Lecture du pixel de la surface en mouvement /*Récupération des composantes colorimétriques*/ SDL_GetRGBA(pixelS1, formatS1, &rS1, &gS1, &bS1, &aS1); //Informations sur les couleurs du pixel de la surface de la map SDL_GetRGBA(pixelS2, formatS2, &rS2, &gS2, &bS2, &aS2); //Informations sur les couleurs du pixel de la surface en mouvement /*Détermination de la collision*/ if (aS1 != 255 || aS2 != 255) //Si le pixel de la surface de la map ou le pixel de la surface en mouvement est transparent collision = 0; //Collision = 0 -> pas de collision else //Au moins l'un des pixels n'est pas transparent { collision = 1; //Collision = 1 -> collision *pDirection = calculDirectionCollision(*pDirection, zone[balayageGen], checkMode); //Calcul de la direction de la collision pour affiner le traitement } } } } formatS1 = NULL; //Remise à 0 des pointeurs de format formatS2 = NULL; //Remise à 0 des pointeurs de format return collision; }
/** * \fn int collisionHighSpeedWithMap(KaamObject* pObject, SDL_Surface* pSurfaceMap) * \brief Detect if an obstacle is between the last position and the current position. * * \param[in] pObject, pointer to the object in motion. * \param[in] pSurfaceMap, pointer to the surface of the map. * \returns int, indicateur de collision : 1 = collision, 0 sinon */ int collisionHighSpeedWithMap(KaamObject* pObject, SDL_Surface* pSurfaceMap) { int xPrec = pObject->objectBox.x; int yPrec = pObject->objectBox.y; int xNow = pObject->objectSurface->clip_rect.x; int yNow = pObject->objectSurface->clip_rect.y; int collision = 0, dx = xNow - xPrec, dy = yNow - yPrec, x = xPrec, y = yPrec; int dp = 2 * dy - dx; /* Valeur initiale de dp */ int deltaE = 2 * dy; int deltaNE = 2 * (dy - dx); Uint32* pixelsMap = (Uint32*)(pSurfaceMap->pixels); if (yNow < yPrec) { SWAP(yNow, yPrec); } if (xNow < xPrec) SWAP(xNow, xPrec); x = xPrec; y = yPrec; dy = yNow - yPrec; dx = xNow - xPrec; if (MY_ABS(dx) < MY_ABS(dy)) { dp = 2 * dx - dy; deltaE = 2 * dx; deltaNE = 2 * (dx - dy); } while (x < xNow) { if (dp <= 0) /* On choisit le point E */ { dp = dp + deltaE; /* Nouveau dp */ x++; /* Calcul de x_p+1 */ /* y_p+1 = y_p */ } else /* On choisit le point NE */ { dp = dp + deltaNE; /* Nouveau dp */ x++; /* Calcul de x_p+1 */ y++; /* Calcul de y_p+1 */ } Uint32 pixelToRead = pixelsMap[x + y * pSurfaceMap->w]; if (!pixelTransparent(pixelToRead, pSurfaceMap->format)) { collision = 1; break; } } return collision; }
/* returns 'val' element, -1 on last item, POPT_ERROR_* on error */ int poptGetNextOpt(poptContext con) { const struct poptOption * opt = NULL; int done = 0; if (con == NULL) return -1; while (!done) { const char * origOptString = NULL; poptCallbackType cb = NULL; const void * cbData = NULL; const char * longArg = NULL; int canstrip = 0; int shorty = 0; while (!con->os->nextCharArg && con->os->next == con->os->argc && con->os > con->optionStack) { cleanOSE(con->os--); } if (!con->os->nextCharArg && con->os->next == con->os->argc) { /*@-internalglobs@*/ invokeCallbacksPOST(con, con->options); /*@=internalglobs@*/ if (con->doExec) return execCommand(con); return -1; } /* Process next long option */ if (!con->os->nextCharArg) { char * localOptString, * optString; int thisopt; /*@-sizeoftype@*/ if (con->os->argb && PBM_ISSET(con->os->next, con->os->argb)) { con->os->next++; continue; } /*@=sizeoftype@*/ thisopt = con->os->next; if (con->os->argv != NULL) /* XXX can't happen */ origOptString = con->os->argv[con->os->next++]; if (origOptString == NULL) /* XXX can't happen */ return POPT_ERROR_BADOPT; if (con->restLeftover || *origOptString != '-') { if (con->flags & POPT_CONTEXT_POSIXMEHARDER) con->restLeftover = 1; if (con->flags & POPT_CONTEXT_ARG_OPTS) { con->os->nextArg = xstrdup(origOptString); return 0; } if (con->leftovers != NULL) /* XXX can't happen */ con->leftovers[con->numLeftovers++] = origOptString; continue; } /* Make a copy we can hack at */ { size_t bufsize = strlen(origOptString) + 1; localOptString = optString = alloca(bufsize); if (optString == NULL) /* XXX can't happen */ return POPT_ERROR_BADOPT; strlcpy(optString, origOptString, bufsize); } if (optString[0] == '\0') return POPT_ERROR_BADOPT; if (optString[1] == '-' && !optString[2]) { con->restLeftover = 1; continue; } else { char *oe; int singleDash; optString++; if (*optString == '-') singleDash = 0, optString++; else singleDash = 1; /* XXX aliases with arg substitution need "--alias=arg" */ if (handleAlias(con, optString, '\0', NULL)) continue; if (handleExec(con, optString, '\0')) continue; /* Check for "--long=arg" option. */ for (oe = optString; *oe && *oe != '='; oe++) {}; if (*oe == '=') { *oe++ = '\0'; /* XXX longArg is mapped back to persistent storage. */ longArg = origOptString + (oe - localOptString); } else oe = NULL; opt = findOption(con->options, optString, '\0', &cb, &cbData, singleDash); if (!opt && !singleDash) return POPT_ERROR_BADOPT; if (!opt && oe) oe[-1] = '='; /* restore overwritten '=' */ } if (!opt) { con->os->nextCharArg = origOptString + 1; longArg = NULL; } else { if (con->os == con->optionStack && opt->argInfo & POPT_ARGFLAG_STRIP) { canstrip = 1; poptStripArg(con, thisopt); } shorty = 0; } } /* Process next short option */ /*@-branchstate@*/ /* FIX: W2DO? */ if (con->os->nextCharArg) { origOptString = con->os->nextCharArg; con->os->nextCharArg = NULL; if (handleAlias(con, NULL, *origOptString, origOptString + 1)) continue; if (handleExec(con, NULL, *origOptString)) { /* Restore rest of short options for further processing */ origOptString++; if (*origOptString != '\0') con->os->nextCharArg = origOptString; continue; } opt = findOption(con->options, NULL, *origOptString, &cb, &cbData, 0); if (!opt) return POPT_ERROR_BADOPT; shorty = 1; origOptString++; if (*origOptString != '\0') con->os->nextCharArg = origOptString; } /*@=branchstate@*/ if (opt == NULL) return POPT_ERROR_BADOPT; /* XXX can't happen */ if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_NONE || (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_VAL) { if (longArg || (con->os->nextCharArg && con->os->nextCharArg[0] == '=')) return POPT_ERROR_UNWANTEDARG; if (opt->arg) { long val = (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_VAL ? opt->val : 1; if (poptSaveInt((int *)opt->arg, opt->argInfo, val)) return POPT_ERROR_BADOPERATION; } } else { con->os->nextArg = _free(con->os->nextArg); /*@-usedef@*/ /* FIX: W2DO? */ if (longArg) { /*@=usedef@*/ longArg = expandNextArg(con, longArg); con->os->nextArg = longArg; } else if (con->os->nextCharArg) { longArg = expandNextArg(con, con->os->nextCharArg + (con->os->nextCharArg[0] == '=')); con->os->nextArg = longArg; con->os->nextCharArg = NULL; } else { while (con->os->next == con->os->argc && con->os > con->optionStack) { cleanOSE(con->os--); } if (con->os->next == con->os->argc) { if (!(opt->argInfo & POPT_ARGFLAG_OPTIONAL)) /*@-compdef@*/ /* FIX: con->os->argv not defined */ return POPT_ERROR_NOARG; /*@=compdef@*/ con->os->nextArg = NULL; } else { /* * Make sure this isn't part of a short arg or the * result of an alias expansion. */ if (con->os == con->optionStack && (opt->argInfo & POPT_ARGFLAG_STRIP) && canstrip) { poptStripArg(con, con->os->next); } if (con->os->argv != NULL) { /* XXX can't happen */ /* XXX watchout: subtle side-effects live here. */ longArg = con->os->argv[con->os->next++]; longArg = expandNextArg(con, longArg); con->os->nextArg = longArg; } } } longArg = NULL; if (opt->arg) { switch (opt->argInfo & POPT_ARG_MASK) { case POPT_ARG_STRING: /* XXX memory leak, hard to plug */ *((const char **) opt->arg) = (con->os->nextArg) ? xstrdup(con->os->nextArg) : NULL; /*@switchbreak@*/ break; case POPT_ARG_INT: case POPT_ARG_LONG: { long aLong = 0; char *end; if (con->os->nextArg) { aLong = strtol(con->os->nextArg, &end, 0); if (!(end && *end == '\0')) return POPT_ERROR_BADNUMBER; } if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_LONG) { if (aLong == LONG_MIN || aLong == LONG_MAX) return POPT_ERROR_OVERFLOW; if (poptSaveLong((long *)opt->arg, opt->argInfo, aLong)) return POPT_ERROR_BADOPERATION; } else { if (aLong > INT_MAX || aLong < INT_MIN) return POPT_ERROR_OVERFLOW; if (poptSaveInt((int *)opt->arg, opt->argInfo, aLong)) return POPT_ERROR_BADOPERATION; } } /*@switchbreak@*/ break; case POPT_ARG_FLOAT: case POPT_ARG_DOUBLE: { double aDouble = 0.0; char *end; if (con->os->nextArg) { /*@-mods@*/ int saveerrno = errno; errno = 0; aDouble = strtod(con->os->nextArg, &end); if (errno == ERANGE) return POPT_ERROR_OVERFLOW; errno = saveerrno; /*@=mods@*/ if (*end != '\0') return POPT_ERROR_BADNUMBER; } if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_DOUBLE) { *((double *) opt->arg) = aDouble; } else { #define MY_ABS(a) ((((a) - 0.0) < DBL_EPSILON) ? -(a) : (a)) if ((MY_ABS(aDouble) - FLT_MAX) > DBL_EPSILON) return POPT_ERROR_OVERFLOW; if ((FLT_MIN - MY_ABS(aDouble)) > DBL_EPSILON) return POPT_ERROR_OVERFLOW; *((float *) opt->arg) = aDouble; } } /*@switchbreak@*/ break; default: fprintf(stdout, POPT_("option type (%d) not implemented in popt\n"), (opt->argInfo & POPT_ARG_MASK)); exit(EXIT_FAILURE); /*@notreached@*/ /*@switchbreak@*/ break; } } } if (cb) { /*@-internalglobs@*/ invokeCallbacksOPTION(con, con->options, opt, cbData, shorty); /*@=internalglobs@*/ } else if (opt->val && ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL)) done = 1; if ((con->finalArgvCount + 2) >= (con->finalArgvAlloced)) { con->finalArgvAlloced += 10; con->finalArgv = realloc(con->finalArgv, sizeof(*con->finalArgv) * con->finalArgvAlloced); } if (con->finalArgv != NULL) { ssize_t bufsize = (opt->longName ? strlen(opt->longName) : 0) + 3; char *s = malloc(bufsize); if (s != NULL) { /* XXX can't happen */ if (opt->longName) snprintf(s, bufsize, "%s%s", ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"), opt->longName); else snprintf(s, bufsize, "-%c", opt->shortName); con->finalArgv[con->finalArgvCount++] = s; } else con->finalArgv[con->finalArgvCount++] = NULL; } if (opt->arg && (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_NONE) /*@-ifempty@*/ ; /*@=ifempty@*/ else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_VAL) /*@-ifempty@*/ ; /*@=ifempty@*/ else if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE) { if (con->finalArgv != NULL && con->os->nextArg) con->finalArgv[con->finalArgvCount++] = /*@-nullpass@*/ /* LCL: con->os->nextArg != NULL */ xstrdup(con->os->nextArg); /*@=nullpass@*/ } } return (opt ? opt->val : -1); /* XXX can't happen */ }