/****************************************************************************** *_Copyright (c) 2009 Digital Stream Technology Inc. All Rights Reserved. * * Module: dstddgfx.c * * Description * * @author * @version $Revision: 1.1 $ * ******************************************************************************/ #include "dsthalcommon.h" #include "dstoslayer.h" #include "dsthalgfx.h" #include "dstddsys.h" #include "SDL.h" /****************************************************************************** * Global variable declaration ******************************************************************************/ /****************************************************************************** * Imported variable declaration ******************************************************************************/ /****************************************************************************** * Imported function declaration ******************************************************************************/ /****************************************************************************** * Local definitions ******************************************************************************/ #define MAX_SDL_MESSAGES 256 /****************************************************************************** * Local typedefs ******************************************************************************/ typedef enum { cmdSDL_Init, cmdSDL_Quit, cmdSDL_AllocFrameBuffer, cmdSDL_FreeFrameBuffer, cmdSDL_DrawBox, cmdSDL_DrawImage, cmdSDL_CopyBlock, cmdSDL_UpdateScreen, cmdSDL_ReadPixels, cmdSDL_MAX } SDLMessageType; struct SdlInitParam { DS_U16 width, height; DS_U32 flags; int psize; }; struct SdlCopyBlockParam { DS_U32 p_src_buffer_id; DS_U32 p_dst_buffer_id; SDL_Rect src_rect; SDL_Rect dst_rect; DS_BOOL bUpdateScreen; }; struct SdlDrawBoxParam { DS_U32 pBufferId; int x, y, w, h; DS_PIXEL_t color; }; struct SdlAllocFrameBuffer { int width; int height; int fmt; }; typedef struct tag_SdlMessage { int type; void *param; DS_BOOL bFreeParam; DS_BOOL bWaitForComplete; DS_U32 *pReturnParam; DS_U32 *pReturnStatus; OS_SEMAPHORE_ID sema4; } SDLMessage; /****************************************************************************** * Local variables declaration ******************************************************************************/ static DS_U16 g_OutputWidth, g_OutputHeight, g_OutputBPP; static SDL_Surface *ScrSurf; static SDL_Surface *PhySurf; static SDL_Surface *VidSurf; static SDL_Surface *PrimSurf, *ScndSurf; static SDL_Surface *bmp_surface = 0; static int s_EnablePlane[MAX_PLANE] = {0}; // // SDL surface variables // static DS_BOOL bSDLThread = DS_FALSE; static OS_TASK_ID SdlTaskId = (OS_TASK_ID)NULL; static OS_MESSAGEQUEUE_ID SdlQueue = (OS_MESSAGEQUEUE_ID)NULL; //static OS_SEMAPHORE_ID semSdlWait = (OS_SEMAPHORE_ID)NULL; // // SDL thread variables // /****************************************************************************** * Local function prototypes ******************************************************************************/ static void _InitSDLThread(void); static void _CloseSDLThread(void); static int _SendSdlCommand(SDLMessageType Type, void *Param, DS_BOOL bWaitForComplete, DS_BOOL bFreeParam, void *ReturnParam); static int doCmd_SDLInit(struct SdlInitParam *p); static int doCmd_SDLCopyBlock(SDL_Surface *src_surf, SDL_Rect *sr, SDL_Surface *dst_surf, SDL_Rect *dr, DS_BOOL ); static int doCmd_SDLUpdateScreen(SDL_Rect *src_rect, SDL_Rect *dst_rect); static DS_U32 doCmd_SDLAllocFrameBuffer( int width, int height, int fmt ); static int doCmd_SDLDrawBox(DS_U32 pBufferId, int x, int y, int w, int h, DS_PIXEL_t color); #if 0 ___Lower_Graphic_APIs___() #endif DHL_RESULT DD_GFX_Init(DS_U16 offsetX, DS_U16 offsetY, DS_U16 width, DS_U16 height, int BPP) { DHL_RESULT dhlResult = DHL_OK; struct SdlInitParam param; int err; _InitSDLThread(); memset(¶m, 0, sizeof(param)); param.width = width; param.height = height; param.psize = BPP; err = _SendSdlCommand( cmdSDL_Init, (void *)¶m, DS_TRUE, DS_FALSE, (void *)NULL ); if (err) dhlResult = DHL_FAIL; return dhlResult; } DHL_RESULT DD_GFX_Close(void) { DHL_RESULT dhlResult = DHL_OK; _CloseSDLThread(); return dhlResult; } DS_U32 DD_GFX_SetPlane(int Plane, DS_U16 HStart, DS_U16 VStart, DS_U16 InHWidth, DS_U16 InVLength, DS_U16 OutHWidth, DS_U16 OutVLength, int BPP) { static DS_BOOL bInit = DS_FALSE; int err=0; if ( bInit == DS_FALSE ) { g_OutputWidth = OutHWidth; g_OutputHeight = OutVLength; g_OutputBPP = BPP; err=DD_GFX_Init(HStart, VStart, OutHWidth, OutVLength, BPP); //err=doCmd_SDLInit(OutHWidth, OutVLength, BPP, 0); if ( err ) return 0; bInit = DS_TRUE; } SysASSERT( InHWidth == OutHWidth ); SysASSERT( InVLength == OutVLength ); if (Plane == 0/*Primary*/ && !PrimSurf) { #if (DHL_GFX_FMT32 == DHL_GFX_FORMAT) PrimSurf=SDL_CreateRGBSurface( SDL_SWSURFACE, OutHWidth, OutVLength, BPP, 0xFF0000, 0xFF00, 0xFF, 0xFF000000); #else PrimSurf=SDL_CreateRGBSurface( SDL_SWSURFACE, OutHWidth, OutVLength, BPP, 0xF00, 0xF0, 0xF, 0x0000); #endif if (!PrimSurf) { printf("SDL_CreateRGBSurface()\n"); //SDL_Quit(); return 0; } #if (DHL_GFX_FMT32 == DHL_GFX_FORMAT) ScrSurf=SDL_CreateRGBSurface( SDL_SWSURFACE, OutHWidth, OutVLength, BPP, 0xFF0000, 0xFF00, 0xFF, 0x00000000); #else ScrSurf=SDL_CreateRGBSurface( SDL_SWSURFACE, OutHWidth, OutVLength, BPP, 0xF00, 0xF0, 0xF, 0x0000); #endif if (!ScrSurf) { printf("SDL_CreateRGBSurface()\n"); //SDL_Quit(); return 0; } s_EnablePlane[Plane] = 0; err=SDL_FillRect( PrimSurf, 0, 0 ); if (err) exit(1); return (DS_U32)PrimSurf; } else if (Plane == 1/*Secondary*/ && !ScndSurf ) { #if (DHL_GFX_FMT32 == DHL_GFX_FORMAT) ScndSurf=SDL_CreateRGBSurface( SDL_SWSURFACE, OutHWidth, OutVLength, BPP, 0xFF0000, 0xFF00, 0xFF, 0xFF000000); #else ScndSurf=SDL_CreateRGBSurface( SDL_SWSURFACE, OutHWidth, OutVLength, BPP, 0xF00, 0xF0, 0xF, 0x0000); #endif if (!ScndSurf) { printf("SDL_CreateRGBSurface()\n"); //SDL_Quit(); return 0; } s_EnablePlane[Plane] = 0; err=SDL_FillRect( ScndSurf, 0, 0 ); if (err) exit(1); return (DS_U32)ScndSurf; } return 0; } DS_U32 DD_GFX_GetPhysicalFrameBuffer(void) { return (DS_U32)ScrSurf; //return (DS_U32)PrimSurf; } DS_U32 DD_GFX_GetVideoFrameBuffer(void) { return (DS_U32)VidSurf; } DS_U32 DD_GFX_AllocFrameBuffer( int width, int height, int fmt ) { DS_U32 bufId=0; struct SdlAllocFrameBuffer param; int err; param.width = width; param.height = height; param.fmt = fmt; err = _SendSdlCommand( cmdSDL_AllocFrameBuffer, (void *)¶m, DS_TRUE, DS_FALSE, (void *)&bufId ); if (bufId==0) { fprintf(stderr, "bufId: 0x%08lX\n", bufId); } return bufId; } DHL_RESULT DD_GFX_FreeFrameBuffer( DS_U32 pBufferId ) { int err; err = _SendSdlCommand( cmdSDL_FreeFrameBuffer, (void *)pBufferId, DS_FALSE, DS_FALSE, (void *)NULL ); if (err) return DHL_FAIL; return DHL_OK; } DS_U32 DD_GFX_GetFrameBuffer( DS_U32 pBufferId ) { SDL_Surface *surf = (SDL_Surface *)pBufferId; // printf("\n\n\n\n\n%s()\n\n\n\n\n", __func__); return (DS_U32)surf->pixels; } void DD_GFX_ReadPixels( DS_U32 pBufferId, int offsetX, int offsetY, int w, int h, DS_PIXEL_t *pPixels ) { SDL_Surface *surf = (SDL_Surface *)pBufferId; int x, y; int surf_w, surf_h; DS_PIXEL_t *p = (DS_PIXEL_t *)surf->pixels; printf("\n\n\n\n\n%s()\n\n\n\n\n", __func__); SysASSERT( pPixels ); surf_w = surf->w; surf_h = surf->h; if ( (offsetX+w) > surf_w ) w = surf_w - offsetX; if ( (offsetY+h) > surf_h ) h = surf_h - offsetY; for (y=0; yp_src_buffer_id = p_src_buffer_id; param->src_rect.x = src_x; param->src_rect.y = src_y; param->src_rect.w = src_w; param->src_rect.h = src_h; param->p_dst_buffer_id = p_dst_buffer_id; param->dst_rect.x = dst_x; param->dst_rect.y = dst_y; param->dst_rect.w = dst_w; param->dst_rect.h = dst_h; param->bUpdateScreen = bUpdateScreen; err = _SendSdlCommand( cmdSDL_CopyBlock, (void *)param, DS_FALSE, DS_TRUE, (void *)NULL ); if (err) printf("!!! Cannot send SDL_CopyBlock command.\n"); } void DD_GFX_UpdateScreen(void) { int err; err = _SendSdlCommand( cmdSDL_UpdateScreen, (void *)NULL, DS_FALSE, DS_FALSE, (void *)NULL ); if (err) printf("!!! Cannot send SDL_UpdateScreen command.\n"); } void DD_GFX_DrawImage( DS_U32 pBufferId, int offsetX, int offsetY, int w, int h, DS_PIXEL_t *pPixels) { SDL_Surface *surf = (SDL_Surface *)pBufferId; DS_PIXEL_t *p; int x, y, surf_h, surf_w; DS_PIXEL_t c; SysENSURE( surf ); surf_h = surf->h; surf_w = surf->w; p = (DS_PIXEL_t *)surf->pixels; SysASSERT( p ); if ( (offsetX+w) > surf_w ) w = surf_w - offsetX; if ( (offsetY+h) > surf_h ) h = surf_h - offsetY; for (y=0; yw; surf_h = VidSurf->h; p = (DS_PIXEL_t *)PhySurf->pixels; for (i=0; iw; surf_h = PrimSurf->h; p = (DS_PIXEL_t *)PrimSurf->pixels; for (i=0; ip_src_buffer_id, &p->src_rect, (SDL_Surface *)p->p_dst_buffer_id, &p->dst_rect, p->bUpdateScreen ); break; } case cmdSDL_DrawBox: { struct SdlDrawBoxParam *p = (struct SdlDrawBoxParam *)msg.param; err = doCmd_SDLDrawBox( p->pBufferId, p->x, p->y, p->w, p->h, p->color ); break; } case cmdSDL_AllocFrameBuffer: { struct SdlAllocFrameBuffer *p = (struct SdlAllocFrameBuffer *)msg.param; returnParam = doCmd_SDLAllocFrameBuffer( p->width, p->height, p->fmt ); break; } case cmdSDL_FreeFrameBuffer: { SDL_Surface *surf = (SDL_Surface *)msg.param; SDL_FreeSurface( surf ); break; } case cmdSDL_UpdateScreen: { err = doCmd_SDLUpdateScreen(NULL, NULL); break; } default: { printf("!!! Invalid SDL message 0x%x\n", msg.type); break; } } if (msg.bFreeParam) { if (msg.param) { free(msg.param); } } if (msg.bWaitForComplete) { if(msg.pReturnParam) { *msg.pReturnParam = returnParam; } if(msg.pReturnStatus) { *msg.pReturnStatus = err; OS_GiveSemaphore(msg.sema4); } else { printf("!!! Command need to wait for completion but return status field is NULL.\n"); } } ProcessSDLEvent(); //OS_mDelay(10); } } static int _SendSdlCommand(SDLMessageType Type, void *Param, DS_BOOL bWaitForComplete, DS_BOOL bFreeParam, void *ReturnParam) { DS_U32 err=0; SDLMessage msg; DS_U32 status=0; memset(&msg, 0, sizeof(msg)); msg.type = Type; msg.bFreeParam = bFreeParam; msg.param = Param; msg.bWaitForComplete = bWaitForComplete; msg.pReturnStatus = &status; msg.pReturnParam = ReturnParam; if (msg.bWaitForComplete) { msg.sema4 = OS_CreateBinarySemaphore("SdlWaitSem", 0, DS_FALSE); SysASSERT( msg.sema4 ); } err=OS_SendMessage(SdlQueue, (DS_U32 *)&msg, sizeof(msg)); if (err) { printf("!!! %s cannot send %d message. err: %lx\n", __FUNCTION__, Type, err); goto _SendSdlCommandExit; } if (bWaitForComplete) { OS_TakeSemaphore(msg.sema4); OS_DeleteSemaphore(msg.sema4); err=status; } _SendSdlCommandExit: if (err) return -1; return 0; } static int doCmd_SDLInit(struct SdlInitParam *p) { int err=0; SDL_version compiled; SDL_VERSION(&compiled); printf("SDL version %d.%d.%d ...\n", compiled.major, compiled.minor, compiled.patch); if(SDL_Init(SDL_INIT_VIDEO)==-1) { printf("SDL_Init: %s\n", SDL_GetError()); err = -1; goto SDLInit_Exit; } { FILE *fp = fopen("win_size.txt", "r"); int nWidth = p->width; int nHeight = p->height; int nSize = p->psize; if (fp != 0) { fscanf(fp,"%d,%d,%d", &nWidth, &nHeight, &nSize); fclose(fp); } else { fp = fopen("win_size.txt", "w"); fprintf(fp,"%d,%d,%d", nWidth, nHeight, nSize); fclose(fp); } PhySurf=SDL_SetVideoMode(nWidth, nHeight, nSize, SDL_RESIZABLE); if(!PhySurf) { printf("SDL_SetVideoMode: %s\n", SDL_GetError()); //SDL_Quit(); err = -1; goto SDLInit_Exit; } } if(!PhySurf) { printf("SDL_SetVideoMode: %s\n", SDL_GetError()); //SDL_Quit(); err = -1; goto SDLInit_Exit; } err=SDL_FillRect( PhySurf, 0, 0 ); SysASSERT(err==0); ScndSurf = PrimSurf = (SDL_Surface *)NULL; #if 0 VidSurf=SDL_CreateRGBSurface( SDL_SWSURFACE, g_OutputWidth, g_OutputHeight, g_OutputBPP, 0, 0, 0, 0); #else srand(time(NULL)); int r = (rand() % 5); switch(r) { case 0: VidSurf=SDL_LoadBMP("background.bmp"); // ¹è°æ ±×¸²¿ë bmp ¼­Çǽº »ý¼º break; case 1: VidSurf=SDL_LoadBMP("background1.bmp"); // ¹è°æ ±×¸²¿ë bmp ¼­Çǽº »ý¼º break; case 2: VidSurf=SDL_LoadBMP("background2.bmp"); // ¹è°æ ±×¸²¿ë bmp ¼­Çǽº »ý¼º break; case 3: VidSurf=SDL_LoadBMP("background3.bmp"); // ¹è°æ ±×¸²¿ë bmp ¼­Çǽº »ý¼º break; case 4: VidSurf=SDL_LoadBMP("background4.bmp"); // ¹è°æ ±×¸²¿ë bmp ¼­Çǽº »ý¼º break; default: VidSurf=SDL_LoadBMP("sosi.bmp"); // ¹è°æ ±×¸²¿ë bmp ¼­Çǽº »ý¼º break; } #endif if (!VidSurf) { printf("SDL_CreateRGBSurface()\n"); //SDL_Quit(); err = -1; goto SDLInit_Exit; } //err=SDL_FillRect( VidSurf, 0, 0 ); SysASSERT(err==0); SDLInit_Exit: return err; } static int doCmd_SDLCopyBlock(SDL_Surface *src_surf, SDL_Rect *sr, SDL_Surface *dst_surf, SDL_Rect *dr, DS_BOOL bUpdateScreen ) { int err=0; if (src_surf == dst_surf) return err; if (0)//dst_surf == (SDL_Surface *)DHL_GFX_GetPhysicalFrameBuffer()) { int x = 0, y =0; for (y = 0; y < dst_surf->h; y++) { for (x = 0; x < dst_surf->w; x++) { int xx = (x * src_surf->w) / dst_surf->w; int yy = (y * src_surf->h) / dst_surf->h; DS_PIXEL_t Pixel; DD_GFX_ReadPixels((DS_U32)src_surf, xx, yy, 1, 1, &Pixel); DHL_GFX_DrawImage((DS_U32)dst_surf, x, y, 1, 1, &Pixel); } } } else { // SDL_Rect sr, dr; // // sr.x = p->src_x; // sr.y = p->src_y; // sr.w = p->src_w; // sr.h = p->src_h; // // dr.x = p->dst_x; // dr.y = p->dst_y; // dr.w = p->dst_w; // dr.h = p->dst_h; #if 0 if (dst_surf != ScrSurf && dst_surf != VidSurf) //if (dst_surf == PrimSurf || dst_surf == ScndSurf ) SDL_FillRect( dst_surf, dr, 0x000000 ); #endif if ( (err=SDL_BlitSurface( src_surf, sr, dst_surf, dr )) < 0 ) { printf("SDL_BlitSurface(): %s (%d)\n", SDL_GetError(), err); err = -1; } } if ( bUpdateScreen ) { doCmd_SDLUpdateScreen(sr, dr); } return 0; } static int doCmd_SDLUpdateScreen(SDL_Rect *src_rect, SDL_Rect *dst_rect) { // SDL_Flip( PhySurf ); int err; err=SDL_FillRect( ScrSurf, dst_rect, 0x000000 ); SysASSERT(err==0); err=SDL_BlitSurface( VidSurf, src_rect, ScrSurf, dst_rect ); SysASSERT(err==0); if ( DHL_GFX_IsEnabled(PLANE_CC) ) { err=SDL_BlitSurface( ScndSurf, src_rect, ScrSurf, dst_rect ); SysASSERT(err==0); } if ( DHL_GFX_IsEnabled(PLANE_OSD) ) { err=SDL_BlitSurface( PrimSurf, src_rect, ScrSurf, dst_rect ); SysASSERT(err==0); } if ( dst_rect ) { //SDL_UpdateRect( ScrSurf, dst_rect->x, dst_rect->y, dst_rect->w, dst_rect->h ); err=SDL_BlitSurface( ScrSurf, dst_rect, PhySurf, dst_rect ); SysASSERT(err==0); SDL_UpdateRect( PhySurf, dst_rect->x, dst_rect->y, dst_rect->w, dst_rect->h ); } else { //SDL_UpdateRect( ScrSurf, 0, 0, 0, 0 ); err=SDL_BlitSurface( ScrSurf, NULL, PhySurf, NULL ); SysASSERT(err==0); SDL_UpdateRect( PhySurf, 0, 0, 0, 0 ); } //SDL_Flip( PhySurf ); return 0; } static DS_U32 doCmd_SDLAllocFrameBuffer( int width, int height, int fmt ) { SDL_Surface *surf = (SDL_Surface *)NULL; SysENSURE( fmt == 8 || fmt == 16 || fmt == 32 ); #if (DHL_GFX_FMT32 == DHL_GFX_FORMAT) surf=SDL_CreateRGBSurface( SDL_SWSURFACE | SDL_SRCALPHA, width, height, fmt, 0xFF0000, 0xFF00, 0xFF, 0xFF000000); #else surf=SDL_CreateRGBSurface( SDL_SWSURFACE | SDL_SRCALPHA, width, height, fmt, 0xF00, 0xF0, 0xF, 0xF000); #endif //surf=SDL_CreateRGBSurface( SDL_SWSURFACE, width, height, fmt, 0xFF0000, 0xFF00, 0xFF, 0xFF000000); //surf=SDL_CreateRGBSurface( SDL_SWSURFACE, width, height, fmt, 0, 0, 0, 0); if (!surf) { fprintf(stderr, "ERROR: SDL_CreateRGBSurface()\n"); return 0; } SDL_SetAlpha( surf, 0, 0xFF ); //SDL_SetColorKey( surf, 0, 0xFF000000 ); return (DS_U32)surf; } static int doCmd_SDLDrawBox(DS_U32 pBufferId, int x, int y, int w, int h, DS_PIXEL_t color) { SDL_Surface *surf = (SDL_Surface *)pBufferId; SDL_Rect rect; int err; SysREQUIRE( surf ); rect.x = x; rect.y = y; rect.w = w; rect.h = h; err=SDL_FillRect( surf, &rect, color ); return err; } static void _InitSDLThread(void) { if ( bSDLThread == DS_TRUE ) { printf("!!! SDL thread is already created.\n"); return; } SdlQueue = OS_CreateMessageQueue("qSdl", 0, MAX_SDL_MESSAGES, sizeof(SDLMessage)); SysASSERT( SdlQueue ); SdlTaskId = OS_SpawnTask( _tSDLMonitor, "tSDLMonitor", 0, 4096, (DS_U32)0); SysASSERT( SdlTaskId ); bSDLThread = DS_TRUE; return; } static void _CloseSDLThread(void) { if ( bSDLThread == DS_FALSE ) { printf("!!! SDL thread is already deleted.\n"); return; } bSDLThread = DS_FALSE; return; } // 2009.03.18 megakiss // OSD Plane ¿Í Video Plane ÀÌ Àû¿ëµÈ »õ·Î¿î 8ºñÆ® ¹öÀü static SDL_Surface *screen_surface = 0; static SDL_Surface *osd_surface = 0; static SDL_Surface *video_surface = 0; static int g_OSDWidth = 0; static int g_OSDHeight = 0; static DS_BOOL g_OSDInitialized = DS_FALSE; void SDL_ScaleBlit(SDL_Surface *src, SDL_Surface *des) { int x = 0, y = 0; for (y = 0; y < des->h; y++) { for (x = 0; x < des->w; x++) { int xx = (x * src->w) / des->w; int yy = (y * src->h) / des->h; SDL_Rect rectSrc = {xx,yy,1,1}; SDL_Rect rectDes = {x,y,1,1}; SDL_BlitSurface(src, &rectSrc, des, &rectDes); } } } static void LoadSize(int *w, int *h) { FILE *fp = fopen("win_size.txt", "r"); if (fp == 0) return; fscanf(fp,"%d,%d", w, h); fclose(fp); } static void SaveSize(int w, int h) { FILE *fp = fopen("win_size.txt", "w"); fprintf(fp,"%d,%d", w, h); fclose(fp); } static int SDLCALL ThreadFunc(void *n) { int nWidth = g_OSDWidth, nHeight = g_OSDHeight; SDL_Event event; SDL_Init(SDL_INIT_VIDEO); // SDL ÃÖ±âÈ­ LoadSize(&nWidth, &nHeight); // ¸¶Áö¸· ÀúÀåÇß´ø À©µµ¿ì »çÀÌÁî ·Îµù screen_surface=SDL_SetVideoMode(nWidth, nHeight, 32, SDL_RESIZABLE); // ½ºÅ©¸° ¼­Çǽº »ý¼º SDL_WM_SetCaption("DST PC Emulator",0); // ŸÀÌÆ² ¹Ù bmp_surface = SDL_LoadBMP("sosi.bmp"); // ¹è°æ ±×¸²¿ë bmp ¼­Çǽº »ý¼º // ºñµð¿À ¼­Çǽº´Â bmp ¼­Çǽº¸¦ ÇöÀç È­¸é Å©±â¿¡ ¸ÂÃß¾î È®´ëÇÑ °ÍÀÌ´Ù. video_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, nWidth, nHeight, 32, 0, 0, 0, 0); SDL_ScaleBlit(bmp_surface, video_surface); // ºñµð¿À ¼­Çǽº¸¦ ½ºÅ©¸° ¼­Çǽº¿¡ º¹»ç SDL_BlitSurface(video_surface, 0, screen_surface, 0); // OSD ¼­Çǽº »ý¼º ÆÈ·¹Æ®´Â ARGB(8:8:8:8) osd_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, g_OSDWidth, g_OSDHeight, 32, 0x00FF0000, 0xFF00, 0xFF, 0xFF000000); // È­¸é¿¡ º¸ÀδÙ. SDL_Flip(screen_surface); // ÃʱâÈ­ ¿Ï·á g_OSDInitialized = DS_TRUE; // À̰ªÀÌ TRUE À϶§±îÁö initÇÔ¼ö¿¡¼­ ±â´Ù¸°´Ù. while (SDL_WaitEvent(&event)) { switch (event.type) { case SDL_VIDEORESIZE: SaveSize(event.resize.w, event.resize.h); // À©µµ »çÀÌÁî ÀúÀå // º¯°æµÈ »çÀÌÁî¿¡ ¸Â°Ô ºñµð¿À ¸ðµå Àç¼³Á¤ screen_surface = SDL_SetVideoMode(event.resize.w, event.resize.h, 32, SDL_RESIZABLE); // º¯°æµÈ È­¸é Å©±â¿¡ ¸Â°Ô bmp ¼­Çǽº¸¦ º¯ÇüÇÑ video surface¸¦ Àç»ý¼ºÇÑ´Ù. SDL_FreeSurface(video_surface); video_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, event.resize.w, event.resize.h, 32, 0, 0, 0, 0); SDL_ScaleBlit(bmp_surface, video_surface); // ºñµð¿À ¼­Çǽº¸¦ ½ºÅ©¸° ¼­Çǽº¿¡ º¹»ç SDL_BlitSurface(video_surface, 0, screen_surface, 0); // OSD ¼­Çǽº¸¦ ½ºÅ©¸° ¼­Çǽº¿¡ º¹»ç SDL_ScaleBlit(osd_surface, screen_surface); // È­¸éÀ» º¸ÀδÙ. SDL_Flip(screen_surface); break; case SDL_KEYDOWN: DHL_IR_Input((DS_U32)(event.key.keysym.sym|0xCAFE0000),1); break; case SDL_KEYUP: DHL_IR_Input((DS_U32)(event.key.keysym.sym|0xCAFE0000),0); break; case SDL_QUIT: SDL_Quit(); exit(0); break; } } return(0); } void DD_GFX8_Init(int w, int h) { //±×·¡ÇÈ ÃʱâÈ­ ÇÔ¼ö ¾²·¹µå¸¦ »ý¼ºÇϰí ÃʱâÈ­°¡ ¿Ï·áµÉ¶§±îÁö ±â´Ù¸°´Ù. g_OSDWidth = w; g_OSDHeight = h; SDL_CreateThread(ThreadFunc, 0); while (g_OSDInitialized == DS_FALSE) OS_Delay(10); } unsigned int Pallette[256]; void DD_GFX8_BlockCopy(int x, int y, int w, int h, unsigned char *buff) { // OSD_Surface(32bit)¿¡ 8ºñÆ® ¹öÆÛ¸¦ º¹»çÇÑ´Ù. int xx = 0, yy = 0; if (g_OSDInitialized == DS_FALSE) return; for (yy = 0 ; yy < h; yy++) { for (xx = 0; xx < w; xx++) { SDL_Rect rect = {x+xx,y+yy,1,1}; Uint32 pixel = Pallette[buff[yy*w+xx]]; SDL_FillRect(osd_surface, &rect, pixel); } } #if 0 SDL_BlitSurface(video_surface, 0, screen_surface, 0); // OSD ¼­Çǽº¸¦ ½ºÅ©¸° ¼­Çǽº¿¡ º¹»ç SDL_ScaleBlit(osd_surface, screen_surface); // È­¸éÀ» º¸ÀδÙ. SDL_Flip(screen_surface); #else // 1:1 È­¸éÀÌ ¾Æ´Ï¹Ç·Î º¸¿©Áö´Â À©µµ¿ì »ó¿¡ ¾÷µ¥ÀÌÆ® ÇÒ ¿µ¿ªÀ» ±¸ÇÑ´Ù. SDL_Rect rect; rect.x = (x * video_surface->w) / osd_surface->w; rect.y = (y * video_surface->h) / osd_surface->h; rect.w = (w * video_surface->w) / osd_surface->w; rect.h = (h * video_surface->h) / osd_surface->h; // ¿µ¿ª ¿¬»ê ÀÌÈÄ ³ª´©±â ¿¬»ê¿¡ ÀÇÇÑ º¸Á¤ÀÌ ÇÊ¿äÇÏ´Ù. rect.x-=2; rect.y-=2; rect.w+=4; rect.h+=4; if (rect.x < 0) rect.x = 0; if (rect.y < 0) rect.y = 0; if (rect.x + rect.w > screen_surface->w) rect.w=screen_surface->w - rect.x; if (rect.y + rect.h < screen_surface->h) rect.h=screen_surface->h - rect.y; // ºñµð¿À ¹öÆÛ¸¦ ½ºÅ©¸° ¹öÆÛ·Î º¹»ç SDL_BlitSurface(video_surface, &rect, screen_surface, &rect); // OSD ¹öÆÛ¸¦ ½ºÄÉÀϸµÇÏ¿© ½ºÅ©¸° ¹öÆÛ·Î º¹»ç for (yy = rect.y; yy < rect.y+rect.h; yy++) { for (xx = rect.x; xx < rect.x+rect.w; xx++) { int src_x = (xx * osd_surface->w) / screen_surface->w; int src_y = (yy * osd_surface->h) / screen_surface->h; SDL_Rect rectSrc = {src_x, src_y,1,1}; SDL_Rect rectDes = {xx,yy,1,1}; SDL_BlitSurface(osd_surface, &rectSrc, screen_surface, &rectDes); } } // ½ºÅ©¸° ¹öÆÛ¸¦ È­¸éÀ¸·Î ¾÷µ¥ÀÌÆ® SDL_UpdateRect(screen_surface, rect.x, rect.y, rect.w, rect.h); #endif } void DD_GFX8_SetPallete(unsigned int *pal) { memcpy(Pallette,pal, sizeof(unsigned int)*256); } void DD_GFX32_Init(int w, int h) { //±×·¡ÇÈ ÃʱâÈ­ ÇÔ¼ö ¾²·¹µå¸¦ »ý¼ºÇϰí ÃʱâÈ­°¡ ¿Ï·áµÉ¶§±îÁö ±â´Ù¸°´Ù. g_OSDWidth = w; g_OSDHeight = h; SDL_CreateThread(ThreadFunc, 0); while (g_OSDInitialized == DS_FALSE) OS_Delay(10); } unsigned int Pallette[256]; void DD_GFX32_BlockCopy(int x, int y, int w, int h, unsigned long *buff) { // OSD_Surface(32bit)¿¡ 8ºñÆ® ¹öÆÛ¸¦ º¹»çÇÑ´Ù. int xx = 0, yy = 0; if (g_OSDInitialized == DS_FALSE) return; for (yy = 0 ; yy < h; yy++) { for (xx = 0; xx < w; xx++) { SDL_Rect rect = {x+xx,y+yy,1,1}; Uint32 pixel = buff[yy*w+xx]; SDL_FillRect(osd_surface, &rect, pixel); } } #if 0 SDL_BlitSurface(video_surface, 0, screen_surface, 0); // OSD ¼­Çǽº¸¦ ½ºÅ©¸° ¼­Çǽº¿¡ º¹»ç SDL_ScaleBlit(osd_surface, screen_surface); // È­¸éÀ» º¸ÀδÙ. SDL_Flip(screen_surface); #else // 1:1 È­¸éÀÌ ¾Æ´Ï¹Ç·Î º¸¿©Áö´Â À©µµ¿ì »ó¿¡ ¾÷µ¥ÀÌÆ® ÇÒ ¿µ¿ªÀ» ±¸ÇÑ´Ù. SDL_Rect rect; rect.x = (x * video_surface->w) / osd_surface->w; rect.y = (y * video_surface->h) / osd_surface->h; rect.w = (w * video_surface->w) / osd_surface->w; rect.h = (h * video_surface->h) / osd_surface->h; // ¿µ¿ª ¿¬»ê ÀÌÈÄ ³ª´©±â ¿¬»ê¿¡ ÀÇÇÑ º¸Á¤ÀÌ ÇÊ¿äÇÏ´Ù. rect.x-=2; rect.y-=2; rect.w+=4; rect.h+=4; if (rect.x < 0) rect.x = 0; if (rect.y < 0) rect.y = 0; if (rect.x + rect.w > screen_surface->w) rect.w=screen_surface->w - rect.x; if (rect.y + rect.h < screen_surface->h) rect.h=screen_surface->h - rect.y; // ºñµð¿À ¹öÆÛ¸¦ ½ºÅ©¸° ¹öÆÛ·Î º¹»ç SDL_BlitSurface(video_surface, &rect, screen_surface, &rect); // OSD ¹öÆÛ¸¦ ½ºÄÉÀϸµÇÏ¿© ½ºÅ©¸° ¹öÆÛ·Î º¹»ç for (yy = rect.y; yy < rect.y+rect.h; yy++) { for (xx = rect.x; xx < rect.x+rect.w; xx++) { int src_x = (xx * osd_surface->w) / screen_surface->w; int src_y = (yy * osd_surface->h) / screen_surface->h; SDL_Rect rectSrc = {src_x, src_y,1,1}; SDL_Rect rectDes = {xx,yy,1,1}; SDL_BlitSurface(osd_surface, &rectSrc, screen_surface, &rectDes); } } // ½ºÅ©¸° ¹öÆÛ¸¦ È­¸éÀ¸·Î ¾÷µ¥ÀÌÆ® SDL_UpdateRect(screen_surface, rect.x, rect.y, rect.w, rect.h); #endif }