@@ -1544,24 +1544,21 @@ surf_set_alpha(pgSurfaceObject *self, PyObject *args)
15441544 bool success =
15451545 PG_SetSurfaceRLE (surf , (flags & PGS_RLEACCEL ) ? SDL_TRUE : SDL_FALSE );
15461546 /* HACK HACK HACK */
1547- // TODO SDL3: figure out how to port this or if it's relevant to SDL3.
1548- #if !SDL_VERSION_ATLEAST (3 , 0 , 0 )
1549- if ((surf -> flags & SDL_RLEACCEL ) && (!(flags & PGS_RLEACCEL ))) {
1547+ if (SDL_MUSTLOCK (surf ) && (!(flags & PGS_RLEACCEL ))) {
15501548 /* hack to strip SDL_RLEACCEL flag off surface immediately when
15511549 it is not requested */
15521550 SDL_Rect sdlrect ;
15531551 sdlrect .x = 0 ;
15541552 sdlrect .y = 0 ;
1555- sdlrect .h = 0 ;
1556- sdlrect .w = 0 ;
1553+ sdlrect .h = 1 ;
1554+ sdlrect .w = 1 ;
15571555
15581556 SDL_Surface * surface =
15591557 PG_CreateSurface (1 , 1 , PG_SURF_FORMATENUM (surf ));
15601558
15611559 SDL_LowerBlit (surf , & sdlrect , surface , & sdlrect );
15621560 SDL_FreeSurface (surface );
15631561 }
1564- #endif
15651562 /* HACK HACK HACK */
15661563 if (success ) {
15671564 success = PG_SetSurfaceAlphaMod (surf , alpha );
@@ -1623,7 +1620,7 @@ surf_copy(pgSurfaceObject *self, PyObject *_null)
16231620 SURF_INIT_CHECK (surf )
16241621
16251622 pgSurface_Prep (self );
1626- newsurf = PG_ConvertSurface (surf , surf -> format );
1623+ newsurf = PG_ConvertSurface (surf , surf );
16271624 pgSurface_Unprep (self );
16281625
16291626 final = surf_subtype_new (Py_TYPE (self ), newsurf , 1 );
@@ -1683,7 +1680,7 @@ surf_convert(pgSurfaceObject *self, PyObject *args)
16831680 if (argobject ) {
16841681 if (pgSurface_Check (argobject )) {
16851682 src = pgSurface_AsSurface (argobject );
1686- newsurf = PG_ConvertSurface (surf , src -> format );
1683+ newsurf = PG_ConvertSurface (surf , src );
16871684 }
16881685 else {
16891686 /* will be updated later, initialize to make static analyzer happy
@@ -1837,7 +1834,7 @@ surf_convert(pgSurfaceObject *self, PyObject *args)
18371834 if (argobject ) {
18381835 if (pgSurface_Check (argobject )) {
18391836 src = pgSurface_AsSurface (argobject );
1840- newsurf = PG_ConvertSurface (surf , src -> format );
1837+ newsurf = PG_ConvertSurface (surf , src );
18411838 }
18421839 else {
18431840 /* will be updated later, initialize to make static analyzer happy
@@ -1961,7 +1958,7 @@ surf_convert(pgSurfaceObject *self, PyObject *args)
19611958 SDL_SetPixelFormatPalette (& format , palette );
19621959 }
19631960 }
1964- newsurf = PG_ConvertSurface (surf , & format );
1961+ newsurf = SDL_ConvertSurface (surf , & format , 0 );
19651962 SDL_SetSurfaceBlendMode (newsurf , SDL_BLENDMODE_NONE );
19661963 SDL_FreePalette (palette );
19671964 }
@@ -3019,10 +3016,8 @@ surf_get_flags(PyObject *self, PyObject *_null)
30193016 if (PG_SurfaceHasRLE (surf )) {
30203017 flags |= PGS_RLEACCELOK ;
30213018 }
3022- // TODO SDL3: figure out how to properly emulate SDL2 check/relevance
3023- // Current implementation is just a placeholder.
30243019#if SDL_VERSION_ATLEAST (3 , 0 , 0 )
3025- if (SDL_SurfaceHasRLE (surf )) {
3020+ if (SDL_MUSTLOCK (surf )) {
30263021 flags |= PGS_RLEACCEL ;
30273022 }
30283023#else
@@ -3767,7 +3762,7 @@ surf_premul_alpha(pgSurfaceObject *self, PyObject *_null)
37673762
37683763 pgSurface_Prep (self );
37693764 // Make a copy of the surface first
3770- newsurf = PG_ConvertSurface (surf , surf -> format );
3765+ newsurf = PG_ConvertSurface (surf , surf );
37713766
37723767 if ((surf -> w > 0 && surf -> h > 0 )) {
37733768 // If the surface has no pixels we don't need to premul
@@ -4461,6 +4456,76 @@ surface_do_overlap(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst,
44614456 return dstoffset < span || dstoffset > src -> pitch - span ;
44624457}
44634458
4459+ int
4460+ PG_BlitSurface (SDL_Surface * src , const SDL_Rect * srcrect , SDL_Surface * dst ,
4461+ SDL_Rect * dstrect )
4462+ {
4463+ #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4464+ /* SDL3 doesn't modify dstrect, so compat for that.
4465+ * Below logic taken from SDL2 source with slight modifications */
4466+ SDL_Rect r_src , r_dst ;
4467+
4468+ r_src .x = 0 ;
4469+ r_src .y = 0 ;
4470+ r_src .w = src -> w ;
4471+ r_src .h = src -> h ;
4472+
4473+ if (dstrect ) {
4474+ r_dst .x = dstrect -> x ;
4475+ r_dst .y = dstrect -> y ;
4476+ }
4477+ else {
4478+ r_dst .x = 0 ;
4479+ r_dst .y = 0 ;
4480+ }
4481+
4482+ /* clip the source rectangle to the source surface */
4483+ if (srcrect ) {
4484+ SDL_Rect tmp ;
4485+ if (SDL_IntersectRect (srcrect , & r_src , & tmp ) == SDL_FALSE ) {
4486+ goto end ;
4487+ }
4488+
4489+ /* Shift dstrect, if srcrect origin has changed */
4490+ r_dst .x += tmp .x - srcrect -> x ;
4491+ r_dst .y += tmp .y - srcrect -> y ;
4492+
4493+ /* Update srcrect */
4494+ r_src = tmp ;
4495+ }
4496+
4497+ /* There're no dstrect.w/h parameters. It's the same as srcrect */
4498+ r_dst .w = r_src .w ;
4499+ r_dst .h = r_src .h ;
4500+
4501+ /* clip the destination rectangle against the clip rectangle */
4502+ {
4503+ SDL_Rect tmp , clip_rect ;
4504+ SDL_GetSurfaceClipRect (dst , & clip_rect );
4505+ if (SDL_IntersectRect (& r_dst , & clip_rect , & tmp ) == SDL_FALSE ) {
4506+ goto end ;
4507+ }
4508+
4509+ /* Update dstrect */
4510+ r_dst = tmp ;
4511+ }
4512+
4513+ if (r_dst .w > 0 && r_dst .h > 0 ) {
4514+ if (dstrect ) { /* update output parameter */
4515+ * dstrect = r_dst ;
4516+ }
4517+ return SDL_BlitSurface (src , srcrect , dst , dstrect ) ? 0 : -1 ;
4518+ }
4519+ end :
4520+ if (dstrect ) {
4521+ dstrect -> w = dstrect -> h = 0 ;
4522+ }
4523+ return 0 ;
4524+ #else
4525+ return SDL_BlitSurface (src , srcrect , dst , dstrect );
4526+ #endif
4527+ }
4528+
44644529/*this internal blit function is accessible through the C api*/
44654530int
44664531pgSurface_Blit (pgSurfaceObject * dstobj , pgSurfaceObject * srcobj ,
@@ -4471,13 +4536,11 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
44714536 SDL_Surface * subsurface = NULL ;
44724537 int result , suboffsetx = 0 , suboffsety = 0 ;
44734538 SDL_Rect orig_clip , sub_clip , dstclip ;
4474- #if !SDL_VERSION_ATLEAST (3 , 0 , 0 )
44754539 Uint8 alpha ;
4476- #endif
44774540
44784541 if (!PG_GetSurfaceClipRect (dst , & dstclip )) {
44794542 PyErr_SetString (pgExc_SDLError , SDL_GetError ());
4480- return 0 ;
4543+ return 1 ;
44814544 }
44824545
44834546 /* passthrough blits to the real surface */
@@ -4528,8 +4591,6 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
45284591 result = pygame_Blit (src , srcrect , dst , dstrect , blend_flags );
45294592 /* Py_END_ALLOW_THREADS */
45304593 }
4531- // TODO SDL3: port the below bit of code. Skipping for initial surface port.
4532- #if !SDL_VERSION_ATLEAST (3 , 0 , 0 )
45334594 /* can't blit alpha to 8bit, crashes SDL */
45344595 else if (PG_SURF_BytesPerPixel (dst ) == 1 &&
45354596 (SDL_ISPIXELFORMAT_ALPHA (PG_SURF_FORMATENUM (src )) ||
@@ -4539,17 +4600,22 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
45394600 result = pygame_Blit (src , srcrect , dst , dstrect , 0 );
45404601 }
45414602 else {
4603+ #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4604+ const SDL_PixelFormatDetails * fmt =
4605+ SDL_GetPixelFormatDetails (src -> format );
4606+ src = fmt ? SDL_ConvertSurface (src ,
4607+ SDL_GetPixelFormatForMasks (
4608+ fmt -> bits_per_pixel , fmt -> Rmask ,
4609+ fmt -> Gmask , fmt -> Bmask , 0 ))
4610+ : NULL ;
4611+
4612+ #else
45424613 SDL_PixelFormat * fmt = src -> format ;
45434614 SDL_PixelFormat newfmt ;
45444615
45454616 newfmt .palette = 0 ; /* Set NULL (or SDL gets confused) */
4546- #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4547- newfmt .bits_per_pixel = fmt -> bits_per_pixel ;
4548- newfmt .bytes_per_pixel = fmt -> bytes_per_pixel ;
4549- #else
45504617 newfmt .BitsPerPixel = fmt -> BitsPerPixel ;
45514618 newfmt .BytesPerPixel = fmt -> BytesPerPixel ;
4552- #endif
45534619 newfmt .Amask = 0 ;
45544620 newfmt .Rmask = fmt -> Rmask ;
45554621 newfmt .Gmask = fmt -> Gmask ;
@@ -4562,13 +4628,10 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
45624628 newfmt .Rloss = fmt -> Rloss ;
45634629 newfmt .Gloss = fmt -> Gloss ;
45644630 newfmt .Bloss = fmt -> Bloss ;
4565- src = PG_ConvertSurface (src , & newfmt );
4566- if (src ) {
4567- #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4568- result = SDL_BlitSurface (src , srcrect , dst , dstrect ) ? 0 : -1 ;
4569- #else
4570- result = SDL_BlitSurface (src , srcrect , dst , dstrect );
4631+ src = SDL_ConvertSurface (src , & newfmt , 0 );
45714632#endif
4633+ if (src ) {
4634+ result = PG_BlitSurface (src , srcrect , dst , dstrect );
45724635 SDL_FreeSurface (src );
45734636 }
45744637 else {
@@ -4577,7 +4640,6 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
45774640 }
45784641 /* Py_END_ALLOW_THREADS */
45794642 }
4580- #endif
45814643 else if (blend_flags != PYGAME_BLEND_ALPHA_SDL2 &&
45824644 !(pg_EnvShouldBlendAlphaSDL2 ()) && !SDL_HasColorKey (src ) &&
45834645 (PG_SURF_BytesPerPixel (dst ) == 4 ||
@@ -4598,11 +4660,7 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
45984660 }
45994661 else {
46004662 /* Py_BEGIN_ALLOW_THREADS */
4601- #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4602- result = SDL_BlitSurface (src , srcrect , dst , dstrect ) ? 0 : -1 ;
4603- #else
4604- result = SDL_BlitSurface (src , srcrect , dst , dstrect );
4605- #endif
4663+ result = PG_BlitSurface (src , srcrect , dst , dstrect );
46064664 /* Py_END_ALLOW_THREADS */
46074665 }
46084666
0 commit comments