static int FULLSCREEN_FlipHWSurface(_THIS, SDL_Surface *surface) { _kernel_swi_regs regs; regs.r[0] = 19; /* Wait for Vsync */ _kernel_swi(OS_Byte, ®s, ®s); FULLSCREEN_SetDisplayBank(this->hidden->current_bank); this->hidden->current_bank ^= 1; FULLSCREEN_SetWriteBank(this->hidden->current_bank); surface->pixels = this->hidden->bank[this->hidden->current_bank]; return(0); }
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 *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 OS's. ** This is turned on by setting the enviromental variable ** SDL$<name>$BackBuffer to 1 */ this->hidden->bank[0] = 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) free(this->hidden->alloc_bank); if (create_back_buffer) { this->hidden->alloc_bank = this->hidden->bank[0]; } else this->hidden->alloc_bank = 0; // Clear both banks to black memset(this->hidden->bank[0], 0, height * current->pitch); memset(this->hidden->bank[1], 0, height * current->pitch); this->hidden->current_bank = 0; current->pixels = this->hidden->bank[0]; /* Reset device functions for the wimp */ FULLSCREEN_SetDeviceMode(this); /* FULLSCREEN_DisableEscape(); */ /* We're done */ return(current); }