📄 sdl_ph_image.c
字号:
surface->hwdata=SDL_malloc(sizeof(struct private_hwdata)); SDL_memset(surface->hwdata, 0x00, sizeof(struct private_hwdata)); surface->hwdata->offscreenctx=PdCreateOffscreenContext(0, surface->w, surface->h, Pg_OSC_MEM_PAGE_ALIGN); if (surface->hwdata->offscreenctx == NULL) { SDL_SetError("ph_AllocHWSurface(): PdCreateOffscreenContext() function failed !\n"); return -1; } surface->pixels=PdGetOffscreenContextPtr(surface->hwdata->offscreenctx); if (surface->pixels==NULL) { PhDCRelease(surface->hwdata->offscreenctx); SDL_SetError("ph_AllocHWSurface(): PdGetOffscreenContextPtr() function failed !\n"); return -1; } surface->pitch=surface->hwdata->offscreenctx->pitch; surface->flags|=SDL_HWSURFACE; surface->flags|=SDL_PREALLOC; #if 0 /* FIXME */ /* create simple offscreen lock */ surface->hwdata->crlockparam.flags=0; if (PdCreateOffscreenLock(surface->hwdata->offscreenctx, &surface->hwdata->crlockparam)!=EOK) { PhDCRelease(surface->hwdata->offscreenctx); SDL_SetError("ph_AllocHWSurface(): Can't create offscreen lock !\n"); return -1; }#endif /* 0 */ /* Update video ram amount */ if (PgGetGraphicsHWCaps(&hwcaps) < 0) { PdDestroyOffscreenLock(surface->hwdata->offscreenctx); PhDCRelease(surface->hwdata->offscreenctx); SDL_SetError("ph_AllocHWSurface(): GetGraphicsHWCaps() function failed !\n"); return -1; } this->info.video_mem=hwcaps.currently_available_video_ram/1024; return 0;}void ph_FreeHWSurface(_THIS, SDL_Surface* surface){ PgHWCaps_t hwcaps; if (surface->hwdata==NULL) { SDL_SetError("ph_FreeHWSurface(): no hwdata!\n"); return; } if (surface->hwdata->offscreenctx == NULL) { SDL_SetError("ph_FreeHWSurface(): no offscreen context to delete!\n"); return; }#if 0 /* FIXME */ /* unlock the offscreen context if it has been locked before destroy it */ if (PdIsOffscreenLocked(surface->hwdata->offscreenctx)==Pg_OSC_LOCKED) { PdUnlockOffscreen(surface->hwdata->offscreenctx); } PdDestroyOffscreenLock(surface->hwdata->offscreenctx);#endif /* 0 */ PhDCRelease(surface->hwdata->offscreenctx); SDL_free(surface->hwdata); surface->hwdata=NULL; /* Update video ram amount */ if (PgGetGraphicsHWCaps(&hwcaps) < 0) { SDL_SetError("ph_FreeHWSurface(): GetGraphicsHWCaps() function failed !\n"); return; } this->info.video_mem=hwcaps.currently_available_video_ram/1024; return;}int ph_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst){ if ((src->hwdata==NULL) && (src != this->screen)) { SDL_SetError("ph_CheckHWBlit(): Source surface haven't hardware specific data.\n"); src->flags&=~SDL_HWACCEL; return -1; } if ((src->flags & SDL_HWSURFACE) != SDL_HWSURFACE) { SDL_SetError("ph_CheckHWBlit(): Source surface isn't a hardware surface.\n"); src->flags&=~SDL_HWACCEL; return -1; } if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { if (this->info.blit_hw_CC!=1) { src->flags&=~SDL_HWACCEL; src->map->hw_blit=NULL; return -1; } } if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA) { if (this->info.blit_hw_A!=1) { src->flags&=~SDL_HWACCEL; src->map->hw_blit=NULL; return -1; } } src->flags|=SDL_HWACCEL; src->map->hw_blit = ph_HWAccelBlit; return 1;}PgColor_t ph_ExpandColor(_THIS, SDL_Surface* surface, Uint32 color){ Uint32 truecolor; /* Photon API accepts true colors only during hw filling operations */ switch(surface->format->BitsPerPixel) { case 8: { if ((surface->format->palette) && (color<=surface->format->palette->ncolors)) { truecolor=PgRGB(surface->format->palette->colors[color].r, surface->format->palette->colors[color].g, surface->format->palette->colors[color].b); } else { SDL_SetError("ph_ExpandColor(): Color out of range for the 8bpp mode !\n"); return 0xFFFFFFFFUL; } } break; case 15: { truecolor = ((color & 0x00007C00UL) << 9) | /* R */ ((color & 0x000003E0UL) << 6) | /* G */ ((color & 0x0000001FUL) << 3) | /* B */ ((color & 0x00007000UL) << 4) | /* R compensation */ ((color & 0x00000380UL) << 1) | /* G compensation */ ((color & 0x0000001CUL) >> 2); /* B compensation */ } break; case 16: { truecolor = ((color & 0x0000F800UL) << 8) | /* R */ ((color & 0x000007E0UL) << 5) | /* G */ ((color & 0x0000001FUL) << 3) | /* B */ ((color & 0x0000E000UL) << 3) | /* R compensation */ ((color & 0x00000600UL) >> 1) | /* G compensation */ ((color & 0x0000001CUL) >> 2); /* B compensation */ } break; case 24: { truecolor=color & 0x00FFFFFFUL; } break; case 32: { truecolor=color; } break; default: { SDL_SetError("ph_ExpandColor(): Unsupported depth for the hardware operations !\n"); return 0xFFFFFFFFUL; } } return truecolor;}int ph_FillHWRect(_THIS, SDL_Surface* surface, SDL_Rect* rect, Uint32 color){ PgColor_t oldcolor; Uint32 truecolor; int ydisp=0; if (this->info.blit_fill!=1) { return -1; } truecolor=ph_ExpandColor(this, surface, color); if (truecolor==0xFFFFFFFFUL) { return -1; } oldcolor=PgSetFillColor(truecolor); /* 640x400 videomode emulation */ if (videomode_emulatemode==1) { ydisp+=40; } PgDrawIRect(rect->x, rect->y+ydisp, rect->w+rect->x-1, rect->h+rect->y+ydisp-1, Pg_DRAW_FILL); PgSetFillColor(oldcolor); PgFlush(); PgWaitHWIdle(); return 0;}int ph_FlipHWSurface(_THIS, SDL_Surface* screen){ PhArea_t farea; if ((screen->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) { /* flush all drawing ops before blitting */ PgFlush(); PgWaitHWIdle(); farea.pos.x=0; farea.pos.y=0; farea.size.w=screen->w; farea.size.h=screen->h; /* emulate 640x400 videomode */ if (videomode_emulatemode==1) { farea.pos.y+=40; } PgContextBlitArea(OCImage.offscreen_context, &farea, OCImage.offscreen_backcontext, &farea); /* flush the blitting */ PgFlush(); PgWaitHWIdle(); } return 0;}int ph_LockHWSurface(_THIS, SDL_Surface* surface){#if 0 /* FIXME */ int lockresult; if (surface->hwdata == NULL) { return; } surface->hwdata->lockparam.flags=0; surface->hwdata->lockparam.time_out=NULL; lockresult=PdLockOffscreen(surface->hwdata->offscreenctx, &surface->hwdata->lockparam); switch (lockresult) { case EOK: break; case Pg_OSC_LOCK_DEADLOCK: SDL_SetError("ph_LockHWSurface(): Deadlock detected !\n"); return -1; case Pg_OSC_LOCK_INVALID: SDL_SetError("ph_LockHWSurface(): Lock invalid !\n"); return -1; default: SDL_SetError("ph_LockHWSurface(): Can't lock the surface !\n"); return -1; }#endif /* 0 */ return 0;}void ph_UnlockHWSurface(_THIS, SDL_Surface* surface){#if 0 /* FIXME */ int unlockresult; if ((surface == NULL) || (surface->hwdata == NULL)) { return; } if (PdIsOffscreenLocked(surface->hwdata->offscreenctx)==Pg_OSC_LOCKED) { unlockresult=PdUnlockOffscreen(surface->hwdata->offscreenctx); }#endif /* 0 */ return;}int ph_HWAccelBlit(SDL_Surface* src, SDL_Rect* srcrect, SDL_Surface* dst, SDL_Rect* dstrect){ SDL_VideoDevice* this=current_video; PhArea_t srcarea; PhArea_t dstarea; int ydisp=0; /* 640x400 videomode emulation */ if (videomode_emulatemode==1) { ydisp+=40; } srcarea.pos.x=srcrect->x; srcarea.pos.y=srcrect->y; srcarea.size.w=srcrect->w; srcarea.size.h=srcrect->h; dstarea.pos.x=dstrect->x; dstarea.pos.y=dstrect->y; dstarea.size.w=dstrect->w; dstarea.size.h=dstrect->h; if (((src == this->screen) || (src->hwdata!=NULL)) && ((dst == this->screen) || (dst->hwdata!=NULL))) { if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { ph_SetHWColorKey(this, src, src->format->colorkey); PgChromaOn(); } if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA) { ph_SetHWAlpha(this, src, src->format->alpha); PgAlphaOn(); } if (dst == this->screen) { if (src == this->screen) { /* blitting from main screen to main screen */ dstarea.pos.y+=ydisp; srcarea.pos.y+=ydisp; PgContextBlitArea(OCImage.offscreen_context, &srcarea, OCImage.offscreen_context, &dstarea); } else { /* blitting from offscreen to main screen */ dstarea.pos.y+=ydisp; PgContextBlitArea(src->hwdata->offscreenctx, &srcarea, OCImage.offscreen_context, &dstarea); } } else { if (src == this->screen) { /* blitting from main screen to offscreen */ srcarea.pos.y+=ydisp; PgContextBlitArea(OCImage.offscreen_context, &srcarea, dst->hwdata->offscreenctx, &dstarea); } else { /* blitting offscreen to offscreen */ PgContextBlitArea(src->hwdata->offscreenctx, &srcarea, dst->hwdata->offscreenctx, &dstarea); } } if ((src->flags & SDL_SRCALPHA) == SDL_SRCALPHA) { PgAlphaOff(); } if ((src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { PgChromaOff(); } } else { SDL_SetError("ph_HWAccelBlit(): Source or target surface is not a hardware surface !\n"); return -1; } PgFlush(); PgWaitHWIdle(); return 0;}int ph_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key){ if (this->info.blit_hw_CC!=1) { return -1; } if (surface->hwdata!=NULL) { surface->hwdata->colorkey=ph_ExpandColor(this, surface, key); if (surface->hwdata->colorkey==0xFFFFFFFFUL) { return -1; } } PgSetChroma(surface->hwdata->colorkey, Pg_CHROMA_SRC_MATCH | Pg_CHROMA_NODRAW); return 0;}int ph_SetHWAlpha(_THIS, SDL_Surface* surface, Uint8 alpha){ if (this->info.blit_hw_A!=1) { return -1; } PgSetAlphaBlend(NULL, alpha); return 0;}#if SDL_VIDEO_OPENGLvoid ph_OpenGLUpdate(_THIS, int numrects, SDL_Rect* rects){ this->GL_SwapBuffers(this); return;}#endif /* SDL_VIDEO_OPENGL */void ph_NormalUpdate(_THIS, int numrects, SDL_Rect *rects){ PhPoint_t ph_pos; PhRect_t ph_rect; int i; for (i=0; i<numrects; ++i) { if (rects[i].w==0) /* Clipped? dunno why but this occurs sometime. */ { continue; } if (rects[i].h==0) /* Clipped? dunno why but this occurs sometime. */ { continue; } ph_pos.x = rects[i].x; ph_pos.y = rects[i].y; ph_rect.ul.x = rects[i].x; ph_rect.ul.y = rects[i].y; ph_rect.lr.x = rects[i].x + rects[i].w; ph_rect.lr.y = rects[i].y + rects[i].h; if (PgDrawPhImageRectmx(&ph_pos, SDL_Image, &ph_rect, 0) < 0) { SDL_SetError("ph_NormalUpdate(): PgDrawPhImageRectmx failed!\n"); return; } } if (PgFlush() < 0) { SDL_SetError("ph_NormalUpdate(): PgFlush() function failed!\n"); }}void ph_OCUpdate(_THIS, int numrects, SDL_Rect *rects){ int i; PhPoint_t zero = {0, 0}; PhArea_t src_rect; PhArea_t dest_rect; PgSetTranslation(&zero, 0); PgSetRegion(PtWidgetRid(window)); PgSetClipping(0, NULL); PgFlush(); PgWaitHWIdle(); for (i=0; i<numrects; ++i) { if (rects[i].w == 0) /* Clipped? */ { continue; } if (rects[i].h == 0) /* Clipped? */ { continue; } src_rect.pos.x=rects[i].x; src_rect.pos.y=rects[i].y; dest_rect.pos.x=rects[i].x; dest_rect.pos.y=rects[i].y; src_rect.size.w=rects[i].w; src_rect.size.h=rects[i].h; dest_rect.size.w=rects[i].w; dest_rect.size.h=rects[i].h; PgContextBlitArea(OCImage.offscreen_context, &src_rect, NULL, &dest_rect); } if (PgFlush() < 0) { SDL_SetError("ph_OCUpdate(): PgFlush failed.\n"); }}void ph_OCDCUpdate(_THIS, int numrects, SDL_Rect *rects){ PgWaitHWIdle(); if (PgFlush() < 0) { SDL_SetError("ph_OCDCUpdate(): PgFlush failed.\n"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -