$FreeBSD$ --- sdl_vid.c.orig Mon Apr 3 23:42:42 2000 +++ sdl_vid.c Thu Sep 13 01:24:35 2001 @@ -1,5 +1,18 @@ -#include +/* + * --------------------------------------------------------------------------- + * "THE BEER-WARE LICENSE" (Revision 42, (c) Poul-Henning Kamp): Maxim + * Sobolev wrote this file. As long as you retain + * this notice you can do whatever you want with this stuff. If we meet + * some day, and you think this stuff is worth it, you can buy me a beer in + * return. + * + * Maxim Sobolev + * --------------------------------------------------------------------------- + */ +/* malloc() and friends */ +#include +/* Lovely SDL */ #include #include "def.h" @@ -48,8 +61,11 @@ SDL_Color *ipalettes[] = {vga16_pal1i, vga16_pal2i}; Sint4 currpal=0; +Uint32 addflag=0; + SDL_Surface *screen = NULL; +/* Data structure holding pending updates */ struct PendNode { void *prevnode; void *nextnode; @@ -77,6 +93,46 @@ { } +bool setmode(void) +{ + if((screen = SDL_SetVideoMode(640, 400, 8, \ + SDL_HWSURFACE | SDL_HWPALETTE | addflag)) == NULL) + return(FALSE); + else + return(TRUE); +} + +void switchmode(void) +{ + Uint32 saved; + SDL_Surface *tmp = NULL; + SDL_Surface *oldscreen; + + vgageti(0, 0, (Uint3 *)&tmp, 80, 200); + oldscreen = screen; + saved = addflag; + + if(addflag == 0) + addflag = SDL_FULLSCREEN; + else + addflag = 0; + if(setmode() == FALSE) { + addflag = saved; + if(setmode() == FALSE) { + fprintf(stderr, "Fatal: failed to change videomode and"\ + "fallback mode failed as well. Exitting.\n"); + exit(1); + } + } + + SDL_SetColors(screen, tmp->format->palette->colors, 0, \ + tmp->format->palette->ncolors); + vgaputi(0, 0, (Uint3 *)&tmp, 80, 200); + SDL_FreeSurface(tmp); + SDL_FreeSurface(oldscreen); +} + + void vgainit(void) { SDL_Surface *tmp = NULL; @@ -92,7 +148,7 @@ } SDL_WM_SetCaption("D I G G E R", NULL); SDL_WM_SetIcon(tmp, NULL); - if ((screen = SDL_SetVideoMode(640, 400, 8, SDL_HWSURFACE | SDL_HWPALETTE)) == NULL) { + if(setmode() == FALSE) { fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n", SDL_GetError()); exit(1); } @@ -131,7 +187,6 @@ { struct PendNode *p; - SDL_UnlockSurface(screen); for(p=First;p!=NULL;) { SDL_UpdateRect(screen,p->rect.x,p->rect.y,p->rect.w,p->rect.h); @@ -139,7 +194,6 @@ free(p); p = First; } - SDL_LockSurface(screen); pendnum = 0; } @@ -161,12 +215,26 @@ tmp->format->palette = screen->format->palette; SDL_BlitSurface(tmp, NULL, screen, &new->rect); tmp->format->palette = reserv; +/* + * Following piece of code comparing already pending updates with current with + * main goal to prevent redrawing overlapping rectangles several times. + */ for(ptr=First;ptr!=NULL;ptr=ptr->nextnode) { if((new->rect.x >= ptr->rect.x) && (new->rect.y >= ptr->rect.y) && - ((new->rect.x+new->rect.w)<=(ptr->rect.x+ptr->rect.w)) && - ((new->rect.y+new->rect.h)<=(ptr->rect.y+ptr->rect.h))) { + ((new->rect.x+new->rect.w) <= (ptr->rect.x+ptr->rect.w)) && + ((new->rect.y+new->rect.h) <= (ptr->rect.y+ptr->rect.h))) { + free(new); + return; + } else if((new->rect.x <= ptr->rect.x) && + (new->rect.y <= ptr->rect.y) && + ((new->rect.x+new->rect.w) >= (ptr->rect.x+ptr->rect.w)) && + ((new->rect.y+new->rect.h) >= (ptr->rect.y+ptr->rect.h))) { + ptr->rect.x = new->rect.x; + ptr->rect.y = new->rect.y; + ptr->rect.w = new->rect.w; + ptr->rect.h = new->rect.h; free(new); return; } @@ -211,6 +279,9 @@ Sint4 rval = 0; Uint8 *pixels; + if ((x > 319) || (y > 199)) + return (0xff); + vgageti(x, y, (Uint3 *)&tmp, 1, 1); pixels = (Uint8 *)tmp->pixels; for (yi=0;yih;yi++) @@ -260,6 +331,8 @@ Sint4 w=3, h=12, size; Sint4 i; + if(((ch - 32) >= 0x5f) || (ch < 32)) + return; tmp = ch2bmap(alphas[ch-32], w, h); size = tmp->w*tmp->h; copy = malloc(size);