SDL_Surface *FULLSCREEN_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) { _kernel_swi_regs regs; Uint32 Rmask = 0; Uint32 Gmask = 0; Uint32 Bmask = 0; int create_back_buffer = riscos_backbuffer; switch(bpp) { case 8: flags |= SDL_HWPALETTE; break; case 15: case 16: Bmask = 0x00007c00; Gmask = 0x000003e0; Rmask = 0x0000001f; break; case 32: Bmask = 0x00ff0000; Gmask = 0x0000ff00; Rmask = 0x000000ff; break; default: SDL_SetError("Pixel depth not supported"); return NULL; break; } if (FULLSCREEN_SetMode(width, height, bpp) == 0) { SDL_SetError("Couldn't set requested mode"); return (NULL); } if ( ! SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, 0) ) { RISCOS_RestoreWimpMode(); SDL_SetError("Couldn't allocate new pixel format for requested mode"); return(NULL); } current->w = width; this->hidden->height = current->h = height; regs.r[0] = -1; regs.r[1] = 6; _kernel_swi(OS_ReadModeVariable, ®s, ®s); current->pitch = regs.r[2]; if (flags & SDL_DOUBLEBUF) { regs.r[0] = 2; _kernel_swi(OS_ReadDynamicArea, ®s, ®s); regs.r[0] = 2; regs.r[1] = (current->pitch * height * 2) - regs.r[1]; if (_kernel_swi(OS_ChangeDynamicArea, ®s, ®s) != NULL) { flags &= ~SDL_DOUBLEBUF; } } current->flags = flags | SDL_FULLSCREEN | SDL_HWSURFACE | SDL_PREALLOC; if (flags & SDL_DOUBLEBUF) { FULLSCREEN_SetWriteBank(0); FULLSCREEN_SetDisplayBank(1); create_back_buffer = 0; } FULLSCREEN_SetupBanks(this); if (create_back_buffer) { if (riscos_backbuffer == 3) this->hidden->bank[0] = WIMP_CreateBuffer(width, height, bpp); else this->hidden->bank[0] = SDL_malloc(height * current->pitch); if (this->hidden->bank[0] == 0) { RISCOS_RestoreWimpMode(); SDL_SetError("Couldnt allocate memory for back buffer"); return (NULL); } current->flags &= ~SDL_HWSURFACE; } if (this->hidden->alloc_bank) SDL_free(this->hidden->alloc_bank); if (create_back_buffer) { this->hidden->alloc_bank = this->hidden->bank[0]; if (riscos_backbuffer == 3) { this->hidden->bank[0] += 60; if (bpp == 8) this->hidden->bank[0] += 2048; } } else this->hidden->alloc_bank = 0; SDL_memset(this->hidden->bank[0], 0, height * current->pitch); SDL_memset(this->hidden->bank[1], 0, height * current->pitch); this->hidden->current_bank = 0; current->pixels = this->hidden->bank[0]; this->screen = current; FULLSCREEN_SetDeviceMode(this); return(current); }
SDL_Surface *WIMP_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) { Uint32 Rmask = 0; Uint32 Gmask = 0; Uint32 Bmask = 0; char *buffer = NULL; int bytesPerPixel = 1; /* Don't support double buffering in Wimp mode */ flags &= ~SDL_DOUBLEBUF; flags &= ~SDL_HWSURFACE; switch(bpp) { case 8: /* Emulated palette using ColourTrans */ flags |= SDL_HWPALETTE; break; case 15: case 16: Bmask = 0x00007c00; Gmask = 0x000003e0; Rmask = 0x0000001f; bytesPerPixel = 2; break; case 32: Bmask = 0x00ff0000; Gmask = 0x0000ff00; Rmask = 0x000000ff; bytesPerPixel = 4; break; default: SDL_SetError("Pixel depth not supported"); return NULL; break; } /* printf("Setting mode %dx%d\n", width, height);*/ /* Allocate the new pixel format for the screen */ if ( ! SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, 0) ) { SDL_SetError("Couldn't allocate new pixel format for requested mode"); return(NULL); } /* Set up the new mode framebuffer */ current->w = width; this->hidden->height = current->h = height; if (bpp == 15) bpp = 16; buffer = WIMP_CreateBuffer(width, height, bpp); if (buffer == NULL) { SDL_SetError("Couldn't create sprite for video memory"); return (NULL); } this->hidden->bank[0] = buffer + 60; /* Start of sprite data */ if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */ this->hidden->bank[1] = buffer; /* Start of buffer */ /* Remember sprite buffer so it can be freed later */ if (this->hidden->alloc_bank) SDL_free(this->hidden->alloc_bank); this->hidden->alloc_bank = buffer; current->pitch = width * bytesPerPixel; if ((current->pitch & 3)) { /* Sprites are 32bit word aligned */ current->pitch += (4 - (current->pitch & 3)); } current->flags = flags | SDL_PREALLOC; WIMP_ReadModeInfo(this); SDL_memset(this->hidden->bank[0], 0, height * current->pitch); this->hidden->current_bank = 0; current->pixels = this->hidden->bank[0]; if (WIMP_SetupWindow(this, current) == 0) { SDL_SetError("Unable to create window to display surface"); return NULL; } /* Reset device functions for the wimp */ WIMP_SetDeviceMode(this); /* Needs to set up plot info after window has been created */ /* Not sure why, but plots don't work if I do it earlier */ WIMP_SetupPlotInfo(this); /* Poll until window is shown */ { /* We wait until it gets the focus, but give up after 5 seconds in case the focus is prevented in any way. */ Uint32 now = SDL_GetTicks(); while (!hasFocus && SDL_GetTicks() - now < 5000) { WIMP_Poll(this, 0); } } /* We're done */ return(current); }
SDL_Surface * FULLSCREEN_SetVideoMode(_THIS, SDL_Surface * current, int width, int height, int bpp, Uint32 flags) { _kernel_swi_regs regs; Uint32 Rmask = 0; Uint32 Gmask = 0; Uint32 Bmask = 0; int create_back_buffer = riscos_backbuffer; switch (bpp) { case 8: flags |= SDL_HWPALETTE; break; case 15: case 16: Bmask = 0x00007c00; Gmask = 0x000003e0; Rmask = 0x0000001f; break; case 32: Bmask = 0x00ff0000; Gmask = 0x0000ff00; Rmask = 0x000000ff; break; default: SDL_SetError("Pixel depth not supported"); return NULL; break; } if (FULLSCREEN_SetMode(width, height, bpp) == 0) { SDL_SetError("Couldn't set requested mode"); return (NULL); } /* printf("Setting mode %dx%d\n", width, height); */ /* Allocate the new pixel format for the screen */ if (!SDL_ReallocFormat(current, bpp, Rmask, Gmask, Bmask, 0)) { RISCOS_RestoreWimpMode(); SDL_SetError("Couldn't allocate new pixel format for requested mode"); return (NULL); } /* Set up the new mode framebuffer */ current->w = width; this->hidden->height = current->h = height; regs.r[0] = -1; /* -1 for current screen mode */ /* Get screen width in bytes */ regs.r[1] = 6; // Screen Width in bytes _kernel_swi(OS_ReadModeVariable, ®s, ®s); current->pitch = regs.r[2]; if (flags & SDL_DOUBLEBUF) { regs.r[0] = 2; /* Screen area */ _kernel_swi(OS_ReadDynamicArea, ®s, ®s); /* Reg 1 has amount of memory currently used for display */ regs.r[0] = 2; /* Screen area */ regs.r[1] = (current->pitch * height * 2) - regs.r[1]; if (_kernel_swi(OS_ChangeDynamicArea, ®s, ®s) != NULL) { /* Can't allocate enough screen memory for double buffer */ flags &= ~SDL_DOUBLEBUF; } } current->flags = flags | SDL_FULLSCREEN | SDL_HWSURFACE | SDL_PREALLOC; /* Need to set display banks here for double buffering */ if (flags & SDL_DOUBLEBUF) { FULLSCREEN_SetWriteBank(0); FULLSCREEN_SetDisplayBank(1); create_back_buffer = 0; /* Don't need a back buffer for a double buffered display */ } FULLSCREEN_SetupBanks(this); if (create_back_buffer) { /* If not double buffered we may need to create a memory ** back buffer to simulate processing on other OSes. ** This is turned on by setting the enviromental variable ** SDL$<name>$BackBuffer >= 1 */ if (riscos_backbuffer == 3) this->hidden->bank[0] = WIMP_CreateBuffer(width, height, bpp); else this->hidden->bank[0] = SDL_malloc(height * current->pitch); if (this->hidden->bank[0] == 0) { RISCOS_RestoreWimpMode(); SDL_SetError("Couldnt allocate memory for back buffer"); return (NULL); } /* Surface updated in programs is now a software surface */ current->flags &= ~SDL_HWSURFACE; } /* Store address of allocated screen bank to be freed later */ if (this->hidden->alloc_bank) SDL_free(this->hidden->alloc_bank); if (create_back_buffer) { this->hidden->alloc_bank = this->hidden->bank[0]; if (riscos_backbuffer == 3) { this->hidden->bank[0] += 60; /* Start of sprite data */ if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */ } } else this->hidden->alloc_bank = 0; // Clear both banks to black SDL_memset(this->hidden->bank[0], 0, height * current->pitch); SDL_memset(this->hidden->bank[1], 0, height * current->pitch); this->hidden->current_bank = 0; current->pixels = this->hidden->bank[0]; /* Have to set the screen here, so SetDeviceMode will pick it up */ this->screen = current; /* Reset device functions for the wimp */ FULLSCREEN_SetDeviceMode(this); /* FULLSCREEN_DisableEscape(); */ /* We're done */ return (current); }
/* Toggle to window from full screen */ int WIMP_ToggleFromFullScreen(_THIS) { int width = this->screen->w; int height = this->screen->h; int bpp = this->screen->format->BitsPerPixel; char *buffer = NULL; char *old_bank[2]; char *old_alloc_bank; /* Ensure flags are OK */ this->screen->flags &= ~(SDL_DOUBLEBUF|SDL_HWSURFACE); if (this->hidden->bank[0] == this->hidden->alloc_bank || riscos_backbuffer == 0) { /* Need to create a sprite for the screen and copy the data to it */ char *data; buffer = WIMP_CreateBuffer(width, height, bpp); data = buffer + 60; /* Start of sprite data */ if (bpp == 8) data += 2048; /* 8bpp sprite have palette first */ if (buffer == NULL) return 0; SDL_memcpy(data, this->hidden->bank[0], width * height * this->screen->format->BytesPerPixel); } /* else We've switch to full screen before so we already have a sprite */ old_bank[0] = this->hidden->bank[0]; old_bank[1] = this->hidden->bank[1]; old_alloc_bank = this->hidden->alloc_bank; if (buffer != NULL) this->hidden->alloc_bank = buffer; this->hidden->bank[1] = this->hidden->alloc_bank; this->hidden->bank[0] = this->hidden->bank[1] + 60; /* Start of sprite data */ if (bpp == 8) this->hidden->bank[0] += 2048; /* 8bpp sprite have palette first */ this->hidden->current_bank = 0; this->screen->pixels = this->hidden->bank[0]; RISCOS_RestoreWimpMode(); WIMP_ReadModeInfo(this); if (WIMP_SetupWindow(this, this->screen)) { WIMP_SetDeviceMode(this); WIMP_SetupPlotInfo(this); if (riscos_backbuffer == 0) riscos_backbuffer = 1; if (buffer && old_alloc_bank) SDL_free(old_alloc_bank); return 1; } else { /* Drop back to full screen mode on failure */ this->hidden->bank[0] = old_bank[0]; this->hidden->bank[1] = old_bank[1]; this->hidden->alloc_bank = old_alloc_bank; if (buffer) SDL_free(buffer); RISCOS_StoreWimpMode(); FULLSCREEN_SetMode(width, height, bpp); } return 0; }