Beispiel #1
0
bool Enemy::CheckCollision(Vector3 pos)
{
	SDL_Rect* result = new SDL_Rect();

	Vector3 objPos = _transform.position;

	SDL_Rect objRect = SDL_Rect();
	objRect.x = objPos.x;
	objRect.y = objPos.y;
	objRect.w = 1;
	objRect.h = 1;

	SDL_Rect targetRect = SDL_Rect();
	targetRect.x = pos.x;
	targetRect.y = pos.y;
	targetRect.w = 1;
	targetRect.h = 1;

	bool enemyCollision = SDL_IntersectRect(&objRect, &targetRect, result);

	if (enemyCollision)
		return true;
	else
	{
		objPos = _projectile->GetTransform().position;

		objRect.x = objPos.x;
		objRect.y = objPos.y;
		objRect.w = 1;
		objRect.h = 1;

		return SDL_IntersectRect(&objRect, &targetRect, result);
	}

}
Beispiel #2
0
/**
 *  This is a semi-private blit function and it performs low-level surface
 *  scaled blitting only.
 */
int
SDL_LowerBlitScaled(SDL_Surface * src, SDL_Rect * srcrect,
                    SDL_Surface * dst, SDL_Rect * dstrect)
{
    static const Uint32 complex_copy_flags = (
                SDL_COPY_MODULATE_COLOR | SDL_COPY_MODULATE_ALPHA |
                SDL_COPY_BLEND | SDL_COPY_ADD | SDL_COPY_MOD |
                SDL_COPY_COLORKEY
            );

    /* Save off the original dst width, height */
    int dstW = dstrect->w;
    int dstH = dstrect->h;
    SDL_Rect full_rect;
    SDL_Rect final_dst = *dstrect;
    SDL_Rect final_src = *srcrect;

    /* Clip the dst surface to the dstrect */
    full_rect.x = 0;
    full_rect.y = 0;
    full_rect.w = dst->w;
    full_rect.h = dst->h;
    if (!SDL_IntersectRect(&final_dst, &full_rect, &final_dst)) {
        return 0;
    }

    /* Did the dst width change? */
    if ( dstW != final_dst.w ) {
        /* scale the src width appropriately */
        final_src.w = final_src.w * dst->clip_rect.w / dstW;
    }

    /* Did the dst height change? */
    if ( dstH != final_dst.h ) {
        /* scale the src width appropriately */
        final_src.h = final_src.h * dst->clip_rect.h / dstH;
    }

    /* Clip the src surface to the srcrect */
    full_rect.x = 0;
    full_rect.y = 0;
    full_rect.w = src->w;
    full_rect.h = src->h;
    if (!SDL_IntersectRect(&final_src, &full_rect, &final_src)) {
        return 0;
    }

    if (!(src->map->info.flags & SDL_COPY_NEAREST)) {
        src->map->info.flags |= SDL_COPY_NEAREST;
        SDL_InvalidateMap(src->map);
    }

    if ( !(src->map->info.flags & complex_copy_flags) &&
            src->format->format == dst->format->format &&
            !SDL_ISPIXELFORMAT_INDEXED(src->format->format) ) {
        return SDL_SoftStretch( src, &final_src, dst, &final_dst );
    } else {
        return SDL_LowerBlit( src, &final_src, dst, &final_dst );
    }
}
    bool CollisionDetect::bitMapMatch(Sprite* sprite1, Sprite* sprite2)
    {
        //int startX;
        //int startY;
        SDL_Rect rect1 = sprite1->getRect();
        SDL_Rect rect2 = sprite2->getRect();
        SDL_Rect result;
        SDL_IntersectRect(&rect1, &rect2, &result);
        
        /*
        int xdirection = 0;
        int ydirection = 0;
        
        if (sprite1->getX()>sprite2->getX())
            xdirection = 1; // sprite 1 till höger om 2
        else if (sprite1->getX()<sprite2->getX())
            xdirection = 2;
        
        if (sprite1->getY()>sprite2->getY())
            ydirection = 1; //sprite 1 högre än sprite 2
        else if (sprite1->getY()<sprite2->getY())
            ydirection = 2;*/
        

        
        if (result.h > 0 && result.w > 0)
           // if (pixelCheck(sprite1, sprite2))
                return true;
        
        return false;
    }
/* 
 * This function performs a fast fill of the given rectangle with 'color'
 */
int SDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color)
{
	int x, y;
	Uint8 *row;

	if ( dstrect )
   {
      /* Perform clipping */
      if ( !SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect) )
         return(0);
   }
   else
   {
      /* If 'dstrect' == NULL, then fill the whole surface */
		dstrect = &dst->clip_rect;
   }


	row = (Uint8 *)dst->pixels+dstrect->y*dst->pitch+
			dstrect->x*dst->format->BytesPerPixel;
	if ( dst->format->palette || (color == 0) ) {
		x = dstrect->w*dst->format->BytesPerPixel;
		if ( !color && !((uintptr_t)row&3) && !(x&3) && !(dst->pitch&3) ) {
			int n = x >> 2;
			for ( y=dstrect->h; y; --y ) {
				SDL_memset4(row, 0, n);
				row += dst->pitch;
			}
		} else {
Beispiel #5
0
	// if r is nullptr, clip to the full size of the surface.
	clip_rect_setter(const surface &surf, const SDL_Rect* r, bool operate = true) : surface_(surf), rect_(), operate_(operate)
	{
		if(operate_){
			SDL_GetClipRect(surface_, &rect_);
			SDL_Rect final_rect;
			SDL_IntersectRect(&rect_, r, &final_rect);
			SDL_SetClipRect(surface_, &final_rect);
		}
	}
Beispiel #6
0
SDL_Rect intersect_rects(const SDL_Rect& rect1, const SDL_Rect& rect2)
{
	SDL_Rect res;
	if(!SDL_IntersectRect(&rect1, &rect2, &res)) {
		return empty_rect;
	}

	return res;
}
Beispiel #7
0
static int
GDI_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
                    int count)
{
    GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata;
    HPEN pen;
    POINT vertices[5];
    int i, status = 1;

    if (data->makedirty) {
        SDL_Window *window = renderer->window;
        SDL_Rect clip, rect;

        clip.x = 0;
        clip.y = 0;
        clip.w = window->w;
        clip.h = window->h;

        for (i = 0; i < count; ++i) {
            if (SDL_IntersectRect(rects[i], &clip, &rect)) {
                SDL_AddDirtyRect(&data->dirty, &rect);
            }
        }
    }

    /* Should we cache the pen? .. it looks like GDI does for us. :) */
    pen = CreatePen(PS_SOLID, 1, RGB(renderer->r, renderer->g, renderer->b));
    SelectObject(data->current_hdc, pen);
    for (i = 0; i < count; ++i) {
        const SDL_Rect *rect = rects[i];

        vertices[0].x = rect->x;
        vertices[0].y = rect->y;

        vertices[1].x = rect->x+rect->w-1;
        vertices[1].y = rect->y;

        vertices[2].x = rect->x+rect->w-1;
        vertices[2].y = rect->y+rect->h-1;

        vertices[3].x = rect->x;
        vertices[3].y = rect->y+rect->h-1;

        vertices[4].x = rect->x;
        vertices[4].y = rect->y;

        status &= Polyline(data->current_hdc, vertices, 5);
    }
    DeleteObject(pen);

    if (!status) {
        WIN_SetError("Polyline()");
        return -1;
    }
    return 0;
}
bool CollisionManager::checkCollision(const SDL_Rect bo, const SDL_Rect check, SDL_Rect* intersect)
{
    //SDL_IntersectRect unreliable :(
    if(SDL_HasIntersection(&bo, &check) == SDL_TRUE)
    {
        SDL_IntersectRect(&bo, &check, intersect);
        return true;
    }
    return false;
}
Beispiel #9
0
static int
GDI_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
                    int count)
{
    GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata;
    HPEN pen;
    BOOL status;

    if (data->makedirty) {
        /* Get the smallest rectangle that contains everything */
        SDL_Window *window = renderer->window;
        SDL_Rect clip, rect;

        clip.x = 0;
        clip.y = 0;
        clip.w = window->w;
        clip.h = window->h;
        SDL_EnclosePoints(points, count, NULL, &rect);
        if (!SDL_IntersectRect(&rect, &clip, &rect)) {
            /* Nothing to draw */
            return 0;
        }

        SDL_AddDirtyRect(&data->dirty, &rect);
    }

    /* Should we cache the pen? .. it looks like GDI does for us. :) */
    pen = CreatePen(PS_SOLID, 1, RGB(renderer->r, renderer->g, renderer->b));
    SelectObject(data->current_hdc, pen);
    {
        LPPOINT p = SDL_stack_alloc(POINT, count);
        int i;

        for (i = 0; i < count; ++i) {
            p[i].x = points[i].x;
            p[i].y = points[i].y;
        }
        status = Polyline(data->current_hdc, p, count);
        SDL_stack_free(p);
    }
    DeleteObject(pen);

    /* Need to close the endpoint of the line */
    if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) {
        SetPixel(data->current_hdc, points[count-1].x, points[count-1].y,
                 RGB(renderer->r, renderer->g, renderer->b));
    }

    if (!status) {
        WIN_SetError("Polyline()");
        return -1;
    }
    return 0;
}
Beispiel #10
0
	void recomputeOnScreen()
	{
		SDL_Rect r1 = { screenRect.x, screenRect.y,
		                screenRect.w, screenRect.h };

		SDL_Rect r2 = { rect->x,     rect->y,
		                rect->width, rect->height };

		SDL_Rect result;
		isOnScreen = SDL_IntersectRect(&r1, &r2, &result);
	}
Beispiel #11
0
static void doBlit(Bitmap *bm, const IntRect &src, const Vec2i &dst)
{
	/* Translate tile to pixel units */
	IntRect _src(src.x*32, src.y*32, src.w*32, src.h*32);
	Vec2i _dst(dst.x*32, dst.y*32);
	IntRect bmr(0, 0, bm->width(), bm->height());

	if (!SDL_IntersectRect(&_src, &bmr, &_src))
		return;

	GLMeta::blitRectangle(_src, _dst);
}
/*
Moves back the moving object so that it and the tile it collides with are next to each other.
*/
void MovingObjectController::handle_movement_collision(const Tile& tile)
{
	SDL_Rect intersection;

	SDL_IntersectRect(&_moving_object.get_bounding_box(), &tile.get_bounding_box(), &intersection);

	Vector2f reversed_direction = _moving_object.get_direction() * -1.0f;

	Vector2f offset(intersection.w * reversed_direction.getX(), intersection.h * reversed_direction.getY());

	_moving_object.set_position(_moving_object.get_position() + offset);
}
Beispiel #13
0
void GLScissorBox::setIntersect(const IntRect &value)
{
	IntRect &current = get();

	SDL_Rect r1 = { current.x, current.y, current.w, current.h };
	SDL_Rect r2 = { value.x,   value.y,   value.w,   value.h };

	SDL_Rect result;
	if (!SDL_IntersectRect(&r1, &r2, &result))
		result.w = result.h = 0;

	set(IntRect(result.x, result.y, result.w, result.h));
}
Beispiel #14
0
	void updateClipRect()
	{
		SDL_Rect winRect = { 0, 0, geo.w, geo.h };

		padRect.x = padRect.y = padding;
		padRect.w = std::max(0, geo.w - padding*2);
		padRect.h = std::max(0, geo.h - (padding+paddingBottom));

		SDL_Rect tmp = padRect;

		SDL_IntersectRect(&winRect, &tmp, &tmp);
		clipRect = IntRect(tmp.x, tmp.y, tmp.w, tmp.h);

		ctrlVertDirty = true;
	}
Beispiel #15
0
static void
DrawRectRectIntersections(SDL_Renderer * renderer)
{
    int i, j;

    SDL_SetRenderDrawColor(renderer, 255, 200, 0, 255);

    for (i = 0; i < num_rects; i++)
        for (j = i + 1; j < num_rects; j++) {
            SDL_Rect r;
            if (SDL_IntersectRect(&rects[i], &rects[j], &r)) {
                SDL_RenderFillRect(renderer, &r);
            }
        }
}
Beispiel #16
0
  void Text::DoRender(SDL_Renderer* renderer)
  {
    if (_cachedTexture != nullptr)
    {
      SDL_Rect destination = { 0 , 0 , _width, _height };

      switch (_textHorizontalAlign)
      {
      case kHorizontalAlignment_Left:
        destination.x = _x;
        break;
      case kHorizontalAlignment_Center:
        destination.x = _x - _width / 2;
        break;
      case kHorizontalAlignment_Right:
        destination.x = _x - _width;
        break;
      }

      switch (_textVerticalAlign)
      {
      case kVerticalAlignment_Top:
        destination.y = _y;
        break;
      case kVerticalAlignment_Center:
        destination.y = _y - _height / 2;
        break;
      case kVerticalAlignment_Bottom:
        destination.y = _y - _height;
        break;
      }

      if (_masked)
      {
        SDL_Rect interesection;
        if (SDL_IntersectRect(&destination, &_mask, &interesection) != SDL_FALSE)
        {
          SDL_Rect source = { interesection.x - destination.x, interesection.y - destination.y,
            interesection.w, interesection.h };
          SDL_RenderCopy(renderer, _cachedTexture, &source, &interesection);
        }
      }
      else
      {
        SDL_RenderCopy(renderer, _cachedTexture, nullptr, &destination);
      }
    }
  }
Beispiel #17
0
/*
 * SDL.intersectRect(r1, r2)
 *
 * Arguments:
 *	r1 the first rectangle
 *	r2 the second rectangle
 *
 * Returns:
 *	True if has intersection
 *	The result rectangle
 */
static int
l_intersectRect(lua_State *L)
{
	SDL_Rect a, b, result;
	int rvalue;

	videoGetRect(L, 1, &a);
	videoGetRect(L, 2, &b);

	rvalue = SDL_IntersectRect(&a, &b, &result);

	lua_pushboolean(L, rvalue);
	videoPushRect(L, &result);

	return 2;
}
Beispiel #18
0
static int
GDI_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
                    int count)
{
    GDI_RenderData *data = (GDI_RenderData *) renderer->driverdata;
    RECT rc;
    HBRUSH brush;
    int i, status = 1;

    if (data->makedirty) {
        SDL_Window *window = renderer->window;
        SDL_Rect clip, rect;

        clip.x = 0;
        clip.y = 0;
        clip.w = window->w;
        clip.h = window->h;

        for (i = 0; i < count; ++i) {
            if (SDL_IntersectRect(rects[i], &clip, &rect)) {
                SDL_AddDirtyRect(&data->dirty, &rect);
            }
        }
    }

    /* Should we cache the brushes? .. it looks like GDI does for us. :) */
    brush = CreateSolidBrush(RGB(renderer->r, renderer->g, renderer->b));
    SelectObject(data->current_hdc, brush);
    for (i = 0; i < count; ++i) {
        const SDL_Rect *rect = rects[i];

        rc.left = rect->x;
        rc.top = rect->y;
        rc.right = rect->x + rect->w;
        rc.bottom = rect->y + rect->h;

        status &= FillRect(data->current_hdc, &rc, brush);
    }
    DeleteObject(brush);

    if (!status) {
        WIN_SetError("FillRect()");
        return -1;
    }
    return 0;
}
Beispiel #19
0
    bool Rect::intersectWith(const Rect& other, Rect* intersection) const {
        SDL_Rect a;
        SDL_Rect b;

        if (!intersection)
            return SDL_HasIntersection(this->copyInto(&a), other.copyInto(&b)) == SDL_TRUE;

        SDL_Rect result;
        const SDL_bool intersects = SDL_IntersectRect(this->copyInto(&a), other.copyInto(&b), intersection->copyInto(&result));

        intersection->x = result.x;
        intersection->y = result.y;
        intersection->width = result.w;
        intersection->height = result.h;

        return intersects == SDL_TRUE;
    }
Beispiel #20
0
static void
DrawRectRectIntersections(SDL_Window * window)
{
    int i, j;

    SDL_SetRenderDrawBlendMode(SDL_BLENDMODE_NONE);

    for (i = 0; i < num_rects; i++)
        for (j = i + 1; j < num_rects; j++) {
            SDL_Rect r;
            if (SDL_IntersectRect(&rects[i], &rects[j], &r)) {
                SDL_SetRenderDrawColor(255, 200, 0, 255);
                SDL_RenderFillRect(&r);
            }
        }

    SDL_SetRenderDrawBlendMode(SDL_BLENDMODE_NONE);
}
Beispiel #21
0
static int
X11_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
{
    X11_RenderData *data = (X11_RenderData *) renderer->driverdata;
    SDL_Window *window = renderer->window;
    SDL_Rect clip, rect;
    unsigned long foreground;
    XRectangle *xrects, *xrect;
    int i, xcount;

    clip.x = 0;
    clip.y = 0;
    clip.w = window->w;
    clip.h = window->h;

    foreground = renderdrawcolor(renderer, 1);
    XSetForeground(data->display, data->gc, foreground);

    xrect = xrects = SDL_stack_alloc(XRectangle, count);
    xcount = 0;
    for (i = 0; i < count; ++i) {
        if (!SDL_IntersectRect(rects[i], &clip, &rect)) {
            continue;
        }

        xrect->x = (short)rect.x;
        xrect->y = (short)rect.y;
        xrect->width = (unsigned short)rect.w;
        xrect->height = (unsigned short)rect.h;
        ++xrect;
        ++xcount;

        if (data->makedirty) {
            SDL_AddDirtyRect(&data->dirty, &rect);
        }
    }
    if (xcount > 0) {
        XFillRectangles(data->display, data->drawable, data->gc,
                        xrects, xcount);
    }
    SDL_stack_free(xpoints);

    return 0;
}
Beispiel #22
0
static int
SW_UpdateClipRect(SDL_Renderer * renderer)
{
    SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
    SDL_Surface *surface = data->surface;
    if (surface) {
        if (renderer->clipping_enabled) {
            SDL_Rect clip_rect;
            clip_rect = renderer->clip_rect;
            clip_rect.x += renderer->viewport.x;
            clip_rect.y += renderer->viewport.y;
            SDL_IntersectRect(&renderer->viewport, &clip_rect, &clip_rect);
            SDL_SetClipRect(surface, &clip_rect);
        } else {
            SDL_SetClipRect(surface, &renderer->viewport);
        }
    }
    return 0;
}
Beispiel #23
0
/*
IDEA FOR BALL DRAWING:
SINCE EVERYTHING IS DRAWN WITH RECTS:
CREATE A VENEER FOR THE RENDERFILLRECT FUNTIONS THAT STORES THE RECT INTO A LIST ON EACH MAIN DRAW PASS
ONCE YOU HAVE THE LIST (I.E. MUST DRAW BALL LAST), USE THAT LIST OF RECTS TO INTERSECT THE BALL AND INVERT COLOR IN THE INTERSECTED AREA.
*/
void CBall::draw(SDL_Renderer* r, const std::vector<SDL_Rect> &drawnBoxes) {
	// draw ball
	CRectEntity::draw(r);
	// draw inverted over intersects
	std::vector<SDL_Rect> intersects;
	for (auto box : drawnBoxes) {
		SDL_Rect intersection;
		if (SDL_IntersectRect(&_boundingBox, &box, &intersection))
			intersects.push_back(intersection);
	}
	if (!intersects.empty()) {
		// keep old color
		SDL_Color save;
		SDL_GetRenderDrawColor(r, &save.r, &save.g, &save.b, &save.a);
		// draw colored rectangle
		SDL_SetRenderDrawColor(r, 255 - _drawColor.r, 255 - _drawColor.g, 255 - _drawColor.b, SDL_ALPHA_OPAQUE);
		SDL_RenderFillRects(r, &intersects[0], intersects.size());
		// reset color
		SDL_SetRenderDrawColor(r, save.r, save.g, save.b, save.a);
	}
}
Beispiel #24
0
/*
 * Set the clipping rectangle for a blittable surface
 */
SDL_bool SDL_SetClipRect(SDL_Surface *surface, const SDL_Rect *rect)
{
	SDL_Rect full_rect;

	/* Don't do anything if there's no surface to act on */
	if ( ! surface ) {
		return SDL_FALSE;
	}

	/* Set up the full surface rectangle */
	full_rect.x = 0;
	full_rect.y = 0;
	full_rect.w = surface->w;
	full_rect.h = surface->h;

	/* Set the clipping rectangle */
	if ( ! rect ) {
		surface->clip_rect = full_rect;
		return 1;
	}
	return SDL_IntersectRect(rect, &full_rect, &surface->clip_rect);
}
Beispiel #25
0
/* 
 * This function performs a fast fill of the given rectangle with 'color'
 */
int SDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color)
{
	SDL_VideoDevice *video = current_video;
	SDL_VideoDevice *this  = current_video;
	int x, y;
	Uint8 *row;

	/* If 'dstrect' == NULL, then fill the whole surface */
	if ( dstrect ) {
		/* Perform clipping */
		if ( !SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect) ) {
			return(0);
		}
	} else {
		dstrect = &dst->clip_rect;
	}

	/* Check for hardware acceleration */
	if ( ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) &&
					video->info.blit_fill ) {
		return(video->FillHWRect(this, dst, dstrect, color));
	}

	/* Perform software fill */
	if ( SDL_LockSurface(dst) != 0 ) {
		return(-1);
	}
	row = (Uint8 *)dst->pixels+dstrect->y*dst->pitch+
			dstrect->x*dst->format->BytesPerPixel;
	if ( dst->format->palette || (color == 0) ) {
		x = dstrect->w*dst->format->BytesPerPixel;
		if ( !color && !((long)row&3) && !(x&3) && !(dst->pitch&3) ) {
			int n = x >> 2;
			for ( y=dstrect->h; y; --y ) {
				SDL_memset4(row, 0, n);
				row += dst->pitch;
			}
		} else {
Beispiel #26
0
/* 
 * This function performs a fast fill of the given rectangle with 'color'
 */
int SDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color)
{
	SDL_VideoDevice *video = current_video;
	SDL_VideoDevice *this  = current_video;
	int x, y;
	Uint8 *row;

	/* This function doesn't work on surfaces < 8 bpp */
	if ( dst->format->BitsPerPixel < 8 ) {
		switch(dst->format->BitsPerPixel) {
		    case 1:
			return SDL_FillRect1(dst, dstrect, color);
			break;
		    case 4:
			return SDL_FillRect4(dst, dstrect, color);
			break;
		    default:
			SDL_SetError("Fill rect on unsupported surface format");
			return(-1);
			break;
		}
	}

	/* If 'dstrect' == NULL, then fill the whole surface */
	if ( dstrect ) {
		/* Perform clipping */
		if ( !SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect) ) {
			return(0);
		}
	} else {
		dstrect = &dst->clip_rect;
	}

	/* Check for hardware acceleration */
	if ( ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) &&
					video->info.blit_fill ) {
		SDL_Rect hw_rect;
		if ( dst == SDL_VideoSurface ) {
			hw_rect = *dstrect;
			hw_rect.x += current_video->offset_x;
			hw_rect.y += current_video->offset_y;
			dstrect = &hw_rect;
		}
		return(video->FillHWRect(this, dst, dstrect, color));
	}

	/* Perform software fill */
	if ( SDL_LockSurface(dst) != 0 ) {
		return(-1);
	}
	row = (Uint8 *)dst->pixels+dstrect->y*dst->pitch+
			dstrect->x*dst->format->BytesPerPixel;
	if ( dst->format->palette || (color == 0) ) {
		x = dstrect->w*dst->format->BytesPerPixel;
		if ( !color && !((int)row&3) && !(x&3) && !(dst->pitch&3) ) {
			int n = x >> 2;
			for ( y=dstrect->h; y; --y ) {
				SDL_memset4(row, 0, n);
				row += dst->pitch;
			}
		} else {
Beispiel #27
0
void Bitmap::drawText(const IntRect &rect, const char *str, int align)
{
	GUARD_DISPOSED;

	GUARD_MEGA;

	if (*str == '\0')
		return;

	if (str[0] == ' ' && str[1] == '\0')
		return;

	TTF_Font *font = p->font->getSdlFont();
	Color *fontColor = p->font->getColor();

	SDL_Color c;
	fontColor->toSDLColor(c);

	float txtAlpha = fontColor->norm.w;

	SDL_Surface *txtSurf;

	if (shState->rtData().config.solidFonts)
		txtSurf = TTF_RenderUTF8_Solid(font, str, c);
	else
		txtSurf = TTF_RenderUTF8_Blended(font, str, c);

	p->ensureFormat(txtSurf, SDL_PIXELFORMAT_ARGB8888);

	int alignX = rect.x;

	switch (align)
	{
	default:
	case Left :
		break;

	case Center :
		alignX += (rect.w - txtSurf->w) / 2;
		break;

	case Right :
		alignX += rect.w - txtSurf->w;
		break;
	}

	if (alignX < rect.x)
		alignX = rect.x;

	int alignY = rect.y + (rect.h - txtSurf->h) / 2;

	float squeeze = (float) rect.w / txtSurf->w;

	if (squeeze > 1)
		squeeze = 1;

	FloatRect posRect(alignX, alignY, txtSurf->w * squeeze, txtSurf->h);

	Vec2i gpTexSize;
	shState->ensureTexSize(txtSurf->w, txtSurf->h, gpTexSize);

	bool fastBlit = !p->touchesTaintedArea(posRect) && txtAlpha == 1.0;

	if (fastBlit)
	{
		if (squeeze == 1.0)
		{
			/* Even faster: upload directly to bitmap texture.
			 * We have to make sure the posRect lies within the texture
			 * boundaries or texSubImage will generate errors.
			 * If it partly lies outside bounds we have to upload
			 * the clipped visible part of it. */
			SDL_Rect btmRect;
			btmRect.x = btmRect.y = 0;
			btmRect.w = width();
			btmRect.h = height();

			SDL_Rect txtRect;
			txtRect.x = posRect.x;
			txtRect.y = posRect.y;
			txtRect.w = posRect.w;
			txtRect.h = posRect.h;

			SDL_Rect inters;

			/* If we have no intersection at all,
			 * there's nothing to upload to begin with */
			if (SDL_IntersectRect(&btmRect, &txtRect, &inters))
			{
				if (inters.w != txtRect.w || inters.h != txtRect.h)
				{
					/* Clip the text surface */
					SDL_Rect clipSrc = inters;
					clipSrc.x -= txtRect.x;
					clipSrc.y -= txtRect.y;

					posRect.x = inters.x;
					posRect.y = inters.y;
					posRect.w = inters.w;
					posRect.h = inters.h;

					PixelStore::setupSubImage(txtSurf->w, clipSrc.x, clipSrc.y);
				}

				TEX::bind(p->gl.tex);
				TEX::uploadSubImage(posRect.x, posRect.y, posRect.w, posRect.h, txtSurf->pixels, GL_BGRA);

				PixelStore::reset();
			}
		}
		else
		{
			/* Squeezing involved: need to use intermediary TexFBO */
			TEXFBO &gpTF = shState->gpTexFBO(txtSurf->w, txtSurf->h);

			TEX::bind(gpTF.tex);
			TEX::uploadSubImage(0, 0, txtSurf->w, txtSurf->h, txtSurf->pixels, GL_BGRA);

			FBO::bind(gpTF.fbo, FBO::Read);
			p->bindFBO();

			FBO::blit(0, 0, txtSurf->w, txtSurf->h,
			          posRect.x, posRect.y, posRect.w, posRect.h,
			          FBO::Linear);
		}
	}
	else
	{
		/* Aquire a partial copy of the destination
		 * buffer we're about to render to */
		TEXFBO &gpTex2 = shState->gpTexFBO(posRect.w, posRect.h);

		FBO::bind(gpTex2.fbo, FBO::Draw);
		FBO::bind(p->gl.fbo, FBO::Read);
		FBO::blit(posRect.x, posRect.y, 0, 0, posRect.w, posRect.h);

		FloatRect bltRect(0, 0,
		                  (float) gpTexSize.x / gpTex2.width,
		                  (float) gpTexSize.y / gpTex2.height);

		BltShader &shader = shState->shaders().blt;
		shader.bind();
		shader.setTexSize(gpTexSize);
		shader.setSource();
		shader.setDestination(gpTex2.tex);
		shader.setSubRect(bltRect);
		shader.setOpacity(txtAlpha);

		shState->bindTex();
		TEX::uploadSubImage(0, 0, txtSurf->w, txtSurf->h, txtSurf->pixels, GL_BGRA);
		TEX::setSmooth(true);

		Quad &quad = shState->gpQuad();
		quad.setTexRect(FloatRect(0, 0, txtSurf->w, txtSurf->h));
		quad.setPosRect(posRect);

		p->bindFBO();
		p->pushSetViewport(shader);

		glState.blendMode.pushSet(BlendNone);

		quad.draw();

		glState.blendMode.pop();
		p->popViewport();
	}

	SDL_FreeSurface(txtSurf);
	p->addTaintedArea(posRect);

	modified();
}
Beispiel #28
0
bool overlaps(SDL_Rect a, SDL_Rect b)
{
	SDL_Rect r; // dumps unused output
	return SDL_IntersectRect(&a, &b, &r);
}
void SdlBaseContainerView::Render()
{
	if (!model.IsVisible() || model.IsEmpty()) return;

	SDL_Renderer *renderer = display.GetRenderer();

	//TODO: Currently, we assume that the render target is the whole screen.
	SDL_Texture *oldRenderTarget = nullptr;
	if (rttTarget) {
		oldRenderTarget = SDL_GetRenderTarget(renderer);
		SDL_SetRenderTarget(renderer, rttTarget->Get());
		SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
		SDL_RenderClear(renderer);
	}

	bool clip = model.IsClip();
	SDL_Rect oldClip = { 0, 0, 0, 0 };

	if (clip) {
		// Translate our bounds into screen-space.
		Vec2 pos = display.LayoutUiPosition(
			model.GetAlignedPos(model.GetSize().x, model.GetSize().y));

		const Vec2 &size = model.GetSize();
		double w = size.x;
		double h = size.y;
		if (!model.IsLayoutUnscaled()) {
			double uiScale = display.GetUiScale();
			w *= uiScale;
			h *= uiScale;
		}

		screenPos = pos;
		screenSize.x = w;
		screenSize.y = h;

		SDL_RenderGetClipRect(renderer, &oldClip);
		SDL_Rect ourClip = {
			static_cast<int>(pos.x), static_cast<int>(pos.y),
			static_cast<int>(w), static_cast<int>(h) };
		SDL_Rect clipRect = { 0, 0, 0, 0 };

		// If there's an existing clip area, then set the clip rect to be
		// the intersection of the two areas.
		if (oldClip.w == 0 || oldClip.h == 0) {
			clipRect = ourClip;
		}
		else {
			if (!SDL_IntersectRect(&oldClip, &ourClip, &clipRect)) {
				// If there's no intersection, set a tiny off-screen rect so
				// the existing clip area check still works.
				clipRect.x = -1;
				clipRect.y = -1;
				clipRect.w = 1;
				clipRect.h = 1;
			}
		}

		SDL_RenderSetClipRect(renderer, &clipRect);
	}

	const Vec2 &size = model.GetSize();
	Vec2 origin = model.GetAlignedPos(size.x, size.y);
	origin += model.GetChildOffset();

	Vec2 oldOrigin = display.AddUiOrigin(origin);
	auto oldFlags = display.AddUiLayoutFlags(model.GetLayoutFlags());
	model.ForEachVisibleChild(std::mem_fn(&ViewModel::Render));
	display.SetUiLayoutFlags(oldFlags);
	display.SetUiOrigin(oldOrigin);

	if (clip) {
		SDL_RenderSetClipRect(renderer, &oldClip);
	}

	if (rttTarget) {
		SDL_SetRenderTarget(renderer, oldRenderTarget);

		// Draw the render target with the selected opacity.
		SDL_Texture *tex = rttTarget->Get();
		SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND);
		SDL_SetTextureAlphaMod(tex,
			static_cast<MR_UInt8>(255.0 * model.GetOpacity()));
		SDL_SetTextureColorMod(tex, 0xff, 0xff, 0xff);

		SDL_RenderCopy(renderer, tex, nullptr, nullptr);
	}
}
int
SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect * rects, int count,
                   SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
    SDL_Rect rect;
    int i;
    int (*func)(SDL_Surface * dst, const SDL_Rect * rect,
                SDL_BlendMode blendMode, Uint8 r, Uint8 g, Uint8 b, Uint8 a) = NULL;
    int status = 0;

    if (!dst) {
        return SDL_SetError("Passed NULL destination surface");
    }

    /* This function doesn't work on surfaces < 8 bpp */
    if (dst->format->BitsPerPixel < 8) {
        return SDL_SetError("SDL_BlendFillRects(): Unsupported surface format");
    }

    if (blendMode == SDL_BLENDMODE_BLEND || blendMode == SDL_BLENDMODE_ADD) {
        r = DRAW_MUL(r, a);
        g = DRAW_MUL(g, a);
        b = DRAW_MUL(b, a);
    }

    /* FIXME: Does this function pointer slow things down significantly? */
    switch (dst->format->BitsPerPixel) {
    case 15:
        switch (dst->format->Rmask) {
        case 0x7C00:
            func = SDL_BlendFillRect_RGB555;
        }
        break;
    case 16:
        switch (dst->format->Rmask) {
        case 0xF800:
            func = SDL_BlendFillRect_RGB565;
        }
        break;
    case 32:
        switch (dst->format->Rmask) {
        case 0x00FF0000:
            if (!dst->format->Amask) {
                func = SDL_BlendFillRect_RGB888;
            } else {
                func = SDL_BlendFillRect_ARGB8888;
            }
            break;
        }
        break;
    default:
        break;
    }

    if (!func) {
        if (!dst->format->Amask) {
            func = SDL_BlendFillRect_RGB;
        } else {
            func = SDL_BlendFillRect_RGBA;
        }
    }

    for (i = 0; i < count; ++i) {
        /* Perform clipping */
        if (!SDL_IntersectRect(&rects[i], &dst->clip_rect, &rect)) {
            continue;
        }
        status = func(dst, &rect, blendMode, r, g, b, a);
    }
    return status;
}