static void diff_rects (Rect r1, Rect r2, int *count, Rect result[4]) { g_assert (count != NULL); g_assert (result != NULL); *count = 0; if (rects_intersect (r1, r2)) { diff_rects_guts (r1, r2, count, result); diff_rects_guts (r2, r1, count, result); } else { if (!rect_empty (&r1)) { result[(*count)++] = r1; } if (!rect_empty (&r2)) { result[(*count)++] = r2; } } }
/* Returns true if the ghost can see pacman from its position; looks at most max_dist blocks in the given cardinal direction. */ int agent_can_see_agent(GameAgent *ga, GameAgent *pman, FixedVector *direction, int max_dist) { FixedVector dir_block_size; FixedVector ga_new_loc; SDL_Rect r_pman; SDL_Rect r_block; int blocks_seen = 0; fixed_vector_to_rect_dimensions(&pman->physical_dim, &r_pman); fixed_vector_to_rect_coords(&pman->loc, &r_pman); r_block.h = BLOCK_SIZE; r_block.w = BLOCK_SIZE; dir_block_size = fixed_vector_scale(direction, FIXED_SET_INT(BLOCK_SIZE)); ga_new_loc = fixed_vector_add(&ga->loc, &dir_block_size); while ( blocks_seen < max_dist && agent_is_position_viable(ga, &ga_new_loc) ) { blocks_seen++; fixed_vector_to_rect_coords(&ga_new_loc, &r_block); if ( rects_intersect(&r_pman, &r_block) ) { return 1; } ga_new_loc = fixed_vector_add(&ga_new_loc, &dir_block_size); } return 0; }
bool entity_collides_with_entity(const entity& e, const entity& other, collision_info* info) { if((e.solid_dimensions()&other.weak_solid_dimensions()) == 0 && (e.weak_solid_dimensions()&other.solid_dimensions()) == 0) { return false; } const rect& our_rect = e.solid_rect(); const rect& other_rect = other.solid_rect(); if(!rects_intersect(our_rect, other_rect)) { return false; } if(other.destroyed()) { return false; } const rect area = intersection_rect(our_rect, other_rect); const solid_info* our_solid = e.solid(); const solid_info* other_solid = other.solid(); assert(our_solid && other_solid); const frame& our_frame = e.current_frame(); const frame& other_frame = other.current_frame(); for(int y = area.y(); y <= area.y2(); ++y) { for(int x = area.x(); x < area.x2(); ++x) { const int our_x = e.face_right() ? x - e.x() : (e.x() + our_frame.width()-1) - x; const int our_y = y - e.y(); if(our_solid->solid_at(our_x, our_y, info ? &info->area_id : NULL)) { const int other_x = other.face_right() ? x - other.x() : (other.x() + other_frame.width()-1) - x; const int other_y = y - other.y(); if(other_solid->solid_at(other_x, other_y, info ? &info->collide_with_area_id : NULL)) { return true; } } } } return false; }
void RoomContainer::DrawObject(const Bitmap* bitmap, const IE::point& point, bool mask) { if (bitmap == NULL) return; IE::point leftTop = offset_point(point, -(bitmap->Frame().x + bitmap->Frame().w / 2), -(bitmap->Frame().y + bitmap->Frame().h / 2)); GFX::rect rect(leftTop.x, leftTop.y, bitmap->Width(), bitmap->Height()); if (rects_intersect(fMapArea, rect)) { GFX::rect offsetRect = offset_rect(rect, -fAreaOffset.x, -fAreaOffset.y); if (mask) GraphicsEngine::BlitBitmapWithMask(bitmap, NULL, fBackMap->Image(), &offsetRect, fBlitMask, &rect); else GraphicsEngine::BlitBitmap(bitmap, NULL, fBackMap->Image(), &offsetRect); } }
int rect_difference(const rect& a, const rect& b, rect* output) { if (rects_intersect(a,b) == false){ //return empty if there's no intersection return -1; } /* returning 4 rectangles in this orientation: _________ | |___| | | | | | | |___| | |_|___|_| */ const rect* begin_output = output; if(a.x() < b.x()) { //get the left section of the source rectangle *output++ = rect(a.x(), a.y(), b.x() - a.x(), a.h()); } if(a.x() + a.w() > b.x() + b.w()) { *output++ = rect(b.x() + b.w(), a.y(), (a.x() + a.w()) - (b.x() + b.w()), a.h()); } if(a.y() < b.y()) { const int x1 = std::max(a.x(), b.x()); const int x2 = std::min(a.x() + a.w(), b.x() + b.w()); *output++ = rect(x1, a.y(), x2 - x1, b.y() - a.y()); } if(a.y() + a.h() > b.y() + b.h()) { const int x1 = std::max(a.x(), b.x()); const int x2 = std::min(a.x() + a.w(), b.x() + b.w()); *output++ = rect(x1, b.y() + b.h(), x2 - x1, (a.y() + a.h()) - (b.y() + b.h())); } return output - begin_output; }
void RoomContainer::Draw(Bitmap *surface) { GraphicsEngine* gfx = GraphicsEngine::Get(); if (fWorldMap != NULL) { GFX::rect sourceRect = offset_rect(fViewPort, -fViewPort.x, -fViewPort.y); sourceRect = offset_rect(sourceRect, fAreaOffset.x, fAreaOffset.y); if (sourceRect.w < gfx->ScreenFrame().w || sourceRect.h < gfx->ScreenFrame().h) { GFX::rect clippingRect = fViewPort; clippingRect.w = gfx->ScreenFrame().w; clippingRect.h = gfx->ScreenFrame().h; gfx->SetClipping(&clippingRect); gfx->ScreenBitmap()->Clear(0); gfx->SetClipping(NULL); } gfx->BlitToScreen(fWorldMapBitmap, &sourceRect, &fViewPort); } else { if (sSelectedActorRadius > 22) { sSelectedActorRadiusStep = -1; } else if (sSelectedActorRadius < 18) { sSelectedActorRadiusStep = 1; } sSelectedActorRadius += sSelectedActorRadiusStep; GFX::rect mapRect = offset_rect_to(fViewPort, fAreaOffset.x, fAreaOffset.y); bool paused = Core::Get()->IsPaused(); if (!paused) { assert(fBackMap != NULL); fBackMap->Update(mapRect); } if (fDrawAnimations) { Timer* timer = Timer::Get("ANIMATIONS"); bool advance = timer != NULL && timer->Expired() && !paused; _DrawAnimations(advance); } _DrawActors(); if (fDrawPolygons) { fBackMap->Image()->Lock(); for (uint32 p = 0; p < fWed->CountPolygons(); p++) { const Polygon* poly = fWed->PolygonAt(p); if (poly != NULL && poly->CountPoints() > 0) { if (rects_intersect(poly->Frame(), mapRect)) { uint32 color = 0; if (poly->Flags() & IE::POLY_SHADE_WALL) color = 200; else if (poly->Flags() & IE::POLY_HOVERING) color = 500; else if (poly->Flags() & IE::POLY_COVER_ANIMATIONS) color = 1000; fBackMap->Image()->FillPolygon(*poly, color, -fAreaOffset.x, -fAreaOffset.y); fBackMap->Image()->StrokePolygon(*poly, color, -fAreaOffset.x, -fAreaOffset.y); } } } fBackMap->Image()->Unlock(); } // TODO: handle this better if (Door* door = dynamic_cast<Door*>(fMouseOverObject.Target())) { GFX::rect rect = rect_to_gfx_rect(door->Frame()); rect = offset_rect(rect, -mapRect.x, -mapRect.y); fBackMap->Image()->Lock(); fBackMap->Image()->StrokeRect(rect, 70); fBackMap->Image()->Unlock(); } else if (Actor* actor = dynamic_cast<Actor*>(fMouseOverObject.Target())) { try { GFX::rect rect = rect_to_gfx_rect(actor->Frame()); rect = offset_rect(rect, -mapRect.x, -mapRect.y); fBackMap->Image()->Lock(); IE::point position = offset_point(actor->Position(), -mapRect.x, -mapRect.y); uint32 color = fBackMap->Image()->MapColor(255, 255, 255); fBackMap->Image()->StrokeCircle(position.x, position.y, 20, color); fBackMap->Image()->Unlock(); } catch (const char* string) { std::cerr << string << std::endl; } catch (...) { } } else if (Region* region = dynamic_cast<Region*>(fMouseOverObject.Target())) { GFX::rect rect = rect_to_gfx_rect(region->Frame()); rect = offset_rect(rect, -mapRect.x, -mapRect.y); uint32 color = 0; switch (region->Type()) { case IE::REGION_TYPE_TRAVEL: color = fBackMap->Image()->MapColor(0, 125, 0); break; case IE::REGION_TYPE_TRIGGER: color = fBackMap->Image()->MapColor(125, 0, 0); break; default: color = fBackMap->Image()->MapColor(255, 255, 255); break; } fBackMap->Image()->Lock(); if (region->Polygon().CountPoints() > 2) { fBackMap->Image()->StrokePolygon(region->Polygon(), color, -mapRect.x, -mapRect.y); } else fBackMap->Image()->StrokeRect(rect, color); fBackMap->Image()->Unlock(); } else if (Container* container = dynamic_cast<Container*>(fMouseOverObject.Target())) { uint32 color = 0; color = fBackMap->Image()->MapColor(0, 125, 0); // TODO: Different colors for trapped/nontrapped fBackMap->Image()->Lock(); if (container->Polygon().CountPoints() > 2) { fBackMap->Image()->StrokePolygon(container->Polygon(), color, -mapRect.x, -mapRect.y); } fBackMap->Image()->Unlock(); } gfx->BlitToScreen(fBackMap->Image(), NULL, &fViewPort); _DrawSearchMap(mapRect); } }