📄 sdl_gemvideo.c
字号:
/* Setup VDI fill functions */ vsf_color(VDI_handle,0); vsf_interior(VDI_handle,1); vsf_perimeter(VDI_handle,0); /* Menu bar save buffer */ menubar_size = GEM_desk_w * GEM_desk_y * VDI_pixelsize; GEM_menubar=Atari_SysMalloc(menubar_size,MX_PREFTTRAM); /* Fill video modes list */ SDL_modelist[0] = SDL_malloc(sizeof(SDL_Rect)); SDL_modelist[0]->x = 0; SDL_modelist[0]->y = 0; SDL_modelist[0]->w = VDI_w; SDL_modelist[0]->h = VDI_h; SDL_modelist[1] = NULL;#if SDL_VIDEO_OPENGL SDL_AtariGL_InitPointers(this);#endif /* We're done! */ return(0);}SDL_Rect **GEM_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags){ if (format->BitsPerPixel != VDI_bpp) { return ((SDL_Rect **)NULL); } if (flags & SDL_FULLSCREEN) { return (SDL_modelist); } return((SDL_Rect **)-1);}static void GEM_FreeBuffers(_THIS){ /* Release buffer */ if ( GEM_buffer2 ) { Mfree( GEM_buffer2 ); GEM_buffer2=NULL; } if ( GEM_buffer1 ) { Mfree( GEM_buffer1 ); GEM_buffer1=NULL; }}static void GEM_ClearRect(_THIS, short *rect){ short oldrgb[3], rgb[3]={0,0,0}; vq_color(VDI_handle, vdi_index[0], 0, oldrgb); vs_color(VDI_handle, vdi_index[0], rgb); vsf_color(VDI_handle,0); vsf_interior(VDI_handle,1); vsf_perimeter(VDI_handle,0); v_bar(VDI_handle, rect); vs_color(VDI_handle, vdi_index[0], oldrgb);}static void GEM_ClearScreen(_THIS){ short pxy[4]; v_hide_c(VDI_handle); pxy[0] = pxy[1] = 0; pxy[2] = VDI_w - 1; pxy[3] = VDI_h - 1; GEM_ClearRect(this, pxy); v_show_c(VDI_handle, 1);}static void GEM_SetNewPalette(_THIS, Uint16 newpal[256][3]){ int i; short rgb[3]; if (VDI_oldnumcolors==0) return; for(i = 0; i < VDI_oldnumcolors; i++) { rgb[0] = newpal[i][0]; rgb[1] = newpal[i][1]; rgb[2] = newpal[i][2]; vs_color(VDI_handle, i, rgb); }}static void GEM_LockScreen(_THIS){ if (!GEM_locked) { /* Lock AES */ wind_update(BEG_UPDATE); wind_update(BEG_MCTRL); /* Reserve memory space, used to be sure of compatibility */ form_dial( FMD_START, 0,0,0,0, 0,0,VDI_w,VDI_h); /* Save menu bar */ if (GEM_menubar) { MFDB mfdb_src; short blitcoords[8]; mfdb_src.fd_addr=GEM_menubar; mfdb_src.fd_w=GEM_desk_w; mfdb_src.fd_h=GEM_desk_y; mfdb_src.fd_wdwidth=GEM_desk_w>>4; mfdb_src.fd_nplanes=VDI_bpp; mfdb_src.fd_stand= mfdb_src.fd_r1= mfdb_src.fd_r2= mfdb_src.fd_r3= 0; blitcoords[0] = blitcoords[4] = 0; blitcoords[1] = blitcoords[5] = 0; blitcoords[2] = blitcoords[6] = GEM_desk_w-1; blitcoords[3] = blitcoords[7] = GEM_desk_y-1; vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &VDI_dst_mfdb, &mfdb_src); } GEM_locked=SDL_TRUE; }}static void GEM_UnlockScreen(_THIS){ if (GEM_locked) { /* Restore menu bar */ if (GEM_menubar) { MFDB mfdb_src; short blitcoords[8]; mfdb_src.fd_addr=GEM_menubar; mfdb_src.fd_w=GEM_desk_w; mfdb_src.fd_h=GEM_desk_y; mfdb_src.fd_wdwidth=GEM_desk_w>>4; mfdb_src.fd_nplanes=VDI_bpp; mfdb_src.fd_stand= mfdb_src.fd_r1= mfdb_src.fd_r2= mfdb_src.fd_r3= 0; blitcoords[0] = blitcoords[4] = 0; blitcoords[1] = blitcoords[5] = 0; blitcoords[2] = blitcoords[6] = GEM_desk_w-1; blitcoords[3] = blitcoords[7] = GEM_desk_y-1; vro_cpyfm(VDI_handle, S_ONLY, blitcoords, &mfdb_src, &VDI_dst_mfdb); } /* Restore screen memory, and send REDRAW to all apps */ form_dial( FMD_FINISH, 0,0,0,0, 0,0,VDI_w,VDI_h); /* Unlock AES */ wind_update(END_MCTRL); wind_update(END_UPDATE); GEM_locked=SDL_FALSE; }}SDL_Surface *GEM_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags){ int maxwidth, maxheight; Uint32 modeflags, screensize; SDL_bool use_shadow1, use_shadow2; /*--- Verify if asked mode can be used ---*/ if (flags & SDL_FULLSCREEN) { maxwidth=VDI_w; maxheight=VDI_h; } else { /* Windowed mode */ maxwidth=GEM_desk_w; maxheight=GEM_desk_h; } /* width must be multiple of 16, for vro_cpyfm() and c2p_convert() */ if ((width & 15) != 0) { width = (width | 15) +1; } if ((maxwidth < width) || (maxheight < height) || (VDI_bpp != bpp)) { SDL_SetError("Couldn't find requested mode in list"); return(NULL); } /*--- Allocate the new pixel format for the screen ---*/ if ( ! SDL_ReallocFormat(current, VDI_bpp, VDI_redmask, VDI_greenmask, VDI_bluemask, VDI_alphamask) ) { SDL_SetError("Couldn't allocate new pixel format for requested mode"); return(NULL); } screensize = width * height * VDI_pixelsize;#ifdef DEBUG_VIDEO_GEM printf("sdl:video:gem: setvideomode(): %dx%dx%d = %d\n", width, height, bpp, screensize);#endif /*--- Allocate shadow buffers if needed, and conversion operations ---*/ GEM_FreeBuffers(this); GEM_bufops=0; use_shadow1=use_shadow2=SDL_FALSE; if (VDI_screen && (flags & SDL_FULLSCREEN)) { if (VDI_format==VDI_FORMAT_INTER) { use_shadow1=SDL_TRUE; GEM_bufops = B2S_C2P_1TOS; } } else { use_shadow1=SDL_TRUE; if (VDI_format==VDI_FORMAT_PACK) { GEM_bufops = B2S_VROCPYFM_1TOS; } else { use_shadow2=SDL_TRUE; GEM_bufops = B2S_C2P_1TO2|B2S_VROCPYFM_2TOS; } } if (use_shadow1) { GEM_buffer1 = Atari_SysMalloc(screensize, MX_PREFTTRAM); if (GEM_buffer1==NULL) { SDL_SetError("Can not allocate %d KB for frame buffer", screensize>>10); return NULL; } SDL_memset(GEM_buffer1, 0, screensize);#ifdef DEBUG_VIDEO_GEM printf("sdl:video:gem: setvideomode(): allocated buffer 1\n");#endif } if (use_shadow2) { GEM_buffer2 = Atari_SysMalloc(screensize, MX_PREFTTRAM); if (GEM_buffer2==NULL) { SDL_SetError("Can not allocate %d KB for shadow buffer", screensize>>10); return NULL; } SDL_memset(GEM_buffer2, 0, screensize);#ifdef DEBUG_VIDEO_GEM printf("sdl:video:gem: setvideomode(): allocated buffer 2\n");#endif } /*--- Initialize screen ---*/ modeflags = SDL_PREALLOC; if (VDI_bpp == 8) { modeflags |= SDL_HWPALETTE; } if (flags & SDL_FULLSCREEN) { GEM_LockScreen(this); GEM_ClearScreen(this); modeflags |= SDL_FULLSCREEN; if (VDI_screen && (VDI_format==VDI_FORMAT_PACK) && !use_shadow1) { modeflags |= SDL_HWSURFACE; } else { modeflags |= SDL_SWSURFACE; } GEM_fullscreen = SDL_TRUE; } else { int old_win_type; short x2,y2,w2,h2; GEM_UnlockScreen(this); /* Set window gadgets */ old_win_type = GEM_win_type; if (!(flags & SDL_NOFRAME)) { GEM_win_type=NAME|MOVER|CLOSER|SMALLER; if (flags & SDL_RESIZABLE) { GEM_win_type |= FULLER|SIZER; modeflags |= SDL_RESIZABLE; } } else { GEM_win_type=0; modeflags |= SDL_NOFRAME; } modeflags |= SDL_SWSURFACE; /* Recreate window ? only for different widget or non-created window */ if ((old_win_type != GEM_win_type) || (GEM_handle < 0)) { /* Calculate window size */ if (!wind_calc(WC_BORDER, GEM_win_type, 0,0,width,height, &x2,&y2,&w2,&h2)) { GEM_FreeBuffers(this); SDL_SetError("Can not calculate window attributes"); return NULL; } /* Center window */ x2 = GEM_desk_x+((GEM_desk_w-w2)>>1); y2 = GEM_desk_y+((GEM_desk_h-h2)>>1); /* Destroy existing window */ if (GEM_handle >= 0) { wind_close(GEM_handle); wind_delete(GEM_handle); } /* Create window */ GEM_handle=wind_create(GEM_win_type, x2,y2,w2,h2); if (GEM_handle<0) { GEM_FreeBuffers(this); SDL_SetError("Can not create window"); return NULL; }#ifdef DEBUG_VIDEO_GEM printf("sdl:video:gem: handle=%d\n", GEM_handle);#endif /* Setup window name */ wind_set(GEM_handle,WF_NAME,(short)(((unsigned long)GEM_title_name)>>16),(short)(((unsigned long)GEM_title_name) & 0xffff),0,0); GEM_refresh_name = SDL_FALSE; /* Open the window */ wind_open(GEM_handle,x2,y2,w2,h2); } else { /* Resize window if needed, to fit asked video mode */ if (modeflags & SDL_RESIZABLE) { wind_get (GEM_handle, WF_WORKXYWH, &x2,&y2,&w2,&h2); if ((w2&15)!=0) { w2=(w2|15)+1; } if ((w2!=width) || (h2!=height)) { if (wind_calc(WC_BORDER, GEM_win_type, x2,y2,width,height, &x2,&y2,&w2,&h2)) { wind_set (GEM_handle, WF_CURRXYWH, x2,y2,w2,h2); } } } } GEM_fullscreen = SDL_FALSE; } /* Set up the new mode framebuffer */ current->w = width; current->h = height; if (use_shadow1) { current->pixels = GEM_buffer1; current->pitch = width * VDI_pixelsize; } else { current->pixels = VDI_screen; current->pitch = VDI_pitch; }#if SDL_VIDEO_OPENGL if (flags & SDL_OPENGL) { if (!SDL_AtariGL_Init(this, current)) { GEM_FreeBuffers(this); SDL_SetError("Can not create OpenGL context"); return NULL; } modeflags |= SDL_OPENGL; }#endif current->flags = modeflags;#ifdef DEBUG_VIDEO_GEM printf("sdl:video:gem: surface: %dx%d\n", current->w, current->h);#endif this->UpdateRects = GEM_UpdateRects; GEM_lock_redraw = SDL_FALSE; /* Enable redraw */ /* We're done */ return(current);}static int GEM_AllocHWSurface(_THIS, SDL_Surface *surface){ return -1;}static void GEM_FreeHWSurface(_THIS, SDL_Surface *surface){ return;}static int GEM_LockHWSurface(_THIS, SDL_Surface *surface){ return(0);}static void GEM_UnlockHWSurface(_THIS, SDL_Surface *surface){ return;}static void GEM_UpdateRectsFullscreen(_THIS, int numrects, SDL_Rect *rects){ SDL_Surface *surface; int i, surf_width; surface = this->screen; /* Need to be a multiple of 16 pixels */ surf_width=surface->w; if ((surf_width & 15) != 0) { surf_width = (surf_width | 15) + 1; } if (GEM_bufops & (B2S_C2P_1TO2|B2S_C2P_1TOS)) { void *destscr; int destpitch; if (GEM_bufops & B2S_C2P_1TOS) { destscr = VDI_screen; destpitch = VDI_pitch; } else { destscr = GEM_buffer2; destpitch = surface->pitch; } for (i=0;i<numrects;i++) { void *source,*destination; int x1,x2; x1 = rects[i].x & ~15; x2 = rects[i].x+rects[i].w; if (x2 & 15) { x2 = (x2 | 15) +1; } source = surface->pixels; source += surface->pitch * rects[i].y; source += x1; destination = destscr; destination += destpitch * rects[i].y; destination += x1; SDL_Atari_C2pConvert(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -