From ba4cbe5ebaeb907e465d1d7f1881b5a62c63c673 Mon Sep 17 00:00:00 2001 From: Andriy Shinkarchuck Date: Sun, 24 Jul 2011 18:46:42 +0300 Subject: [PATCH] vga.c vga.h moved to repo. Added license notification. --- vga.c | 358 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ vga.h | 238 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 596 insertions(+) create mode 100755 vga.c create mode 100755 vga.h diff --git a/vga.c b/vga.c new file mode 100755 index 0000000..e06baf4 --- /dev/null +++ b/vga.c @@ -0,0 +1,358 @@ +/* + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "glob.h" +#include "vga.h" +#include +#include "error.h" +#include "view.h" + + +// адрес экранного буфера +unsigned char *scra; + +// виртуальный экран +unsigned char scrbuf[64000]; + + +int SCRW = 800; +int SCRH = 600; + +SDL_Surface* screen = NULL; + +int cx1,cx2,cy1,cy2; + +char fullscreen = OFF; + +#define HQ 2 + +short V_init(void) +{ + Uint32 flags = SDL_SWSURFACE|SDL_DOUBLEBUF|SDL_HWPALETTE; + if (fullscreen) flags = flags | SDL_FULLSCREEN; + screen = SDL_SetVideoMode(SCRW, SCRH, 8, flags); + if (!screen) ERR_failinit("Unable to set video mode: %s\n", SDL_GetError()); + SCRW /= HQ; + SCRH /= HQ; + return 0; +} + +// переключение в текстовый режим +void V_done(void) +{ + SDL_Quit(); +} + +void draw_rect (int x, int y, int w, int h, int c) +{ + SDL_Rect dstrect; + dstrect.x = x*HQ; + dstrect.y = y*HQ; + dstrect.w = w*HQ; + dstrect.h = h*HQ; + SDL_FillRect(screen, &dstrect, c); +} + +// установить область вывода +void V_setrect(short x,short w,short y,short h) +{ + SDL_Rect r; + r.x=x*HQ; + r.y=y*HQ; + r.w=w*HQ; + r.h=h*HQ; + SDL_SetClipRect(screen, &r); + SDL_GetClipRect(screen, &r); + cx1 = x; + cx2 = x+w-1; + cy1 = y; + cy2 = y+h-1; + if (cx1<0) cx1=0; + if (cx2>=SCRW) cx2=SCRW-1; + if (cy1<0) cy1=0; + if (cy2>=SCRH) cy2=SCRH-1; +} + +void putpixel(int x, int y, Uint8 color) +{ + if(x>=cx1 && x<=cx2 && y>=cy1 && y<=cy2) { + x*=HQ; + y*=HQ; + Uint8 *p = (Uint8 *)screen->pixels + y*screen->pitch + x; + *p = color; + *(p+1) = color; + p += screen->pitch; + *p = color; + *(p+1) = color; + } +} + +byte getpixel(int x, int y) +{ + if(x>=cx1 && x<=cx2 && y>=cy1 && y<=cy2) { + x*=HQ; + y*=HQ; + return *((Uint8 *)screen->pixels + y*screen->pitch + x); + } + return 0; +} + +void mappixel(int x,int y,byte* cmap) +{ + byte c = getpixel(x,y); + putpixel(x,y,cmap[c]); +} + +int offx = 0; +int offy = 0; + +void V_center(int f) +{ + if (f) V_offset(SCRW/2-320/2, SCRH/2-200/2); + else V_offset(0, 0); +} + +void V_offset(int ox, int oy) +{ + offx=ox; + offy=oy; +} + +void draw_spr(short x,short y,vgaimg *i, int d, int c) +{ + if (i==NULL) return; + x += offx; + y += offy; + if (d & 1) x=x-i->w+i->sx; else x-=i->sx; + if (d & 2) y=y-i->h+i->sy; else y-=i->sy; + if(x+i->w>=cx1 && x<=cx2 && y+i->h>=cy1 && y<=cy2) { + int lx, ly; + byte *p = (byte*)i + sizeof(vgaimg); + for (ly=0; lyh; ly++) { + for(lx=0; lxw; lx++) { + int rx,ry; + rx = (d & 1) ? (i->w-lx-1) : (rx=lx); + ry = (d & 2) ? (i->h-ly-1) : (ry=ly); + if (*p) { + byte t = *p; + if (c) if (t>=0x70 && t<=0x7F) t=t-0x70+c; + putpixel(x+rx,y+ry,t); + } + p++; + } + } + } +} + +void V_rotspr (int x, int y, vgaimg* i, int d) +{ + x+=i->w*((d&1)?1:0); + y+=i->h*((d&2)?1:0); + draw_spr(x,y,i,d,0); +} + +void V_pic(short x,short y,vgaimg *i) +{ + draw_spr(x,y,i, 0, 0); +} + +void V_manspr(int x,int y,void *p, unsigned char c) +{ + draw_spr(x,y,p, 0, c); +} + +void V_manspr2(int x,int y,void *p, unsigned char c) +{ + draw_spr(x,y,p, 1, c); +} + +// вывести точку цвета c в координатах (x,y) +void V_dot(short x,short y, unsigned char c) +{ + putpixel(x,y,c); +} + + +extern byte bright[256]; +extern byte flametab[16]; +extern byte mixmap[256][256]; + +void smoke_sprf(int x, int y, byte c) +{ + byte t = getpixel(x,y); + c = c + bright[t]; + c += 0x60; + c ^= 0xF; + putpixel(x,y,mixmap[c][t]); +} + +void flame_sprf(int x, int y, byte c) +{ + byte t = getpixel(x,y); + c = c + bright[t]; + putpixel(x,y,flametab[c]); +} + +void V_sprf(short x,short y,vgaimg *i,spr_f *f) +{ + if (i==NULL) return; + x-=i->sx; + y-=i->sy; + int cx, cy; + byte *p = (byte*)i; + p+=sizeof(vgaimg); + for (cy=y; cyh; cy++) { + for(cx=x; cxw; cx++) { + if (*p) { + (*f)(cx, cy, *p); + } + p++; + } + } +} + +void V_spr(short x,short y,vgaimg *i) +{ + draw_spr(x,y,i,0, 0); +} + +void V_spr2(short x,short y,vgaimg *i) +{ + draw_spr(x,y,i,1,0); +} + +void V_clr(short x,short w,short y,short h,unsigned char c) +{ + draw_rect(x,y,w,h, c); +} + +// установить палитру из массива p +void VP_setall(void *p) +{ + VP_set(p, 0, 256); +} + +// установить n цветов, начиная с f, из массива p +void VP_set(void *p,short f,short n) +{ + byte *ptr = (byte*)p; + SDL_Color colors[256]; + int i; + for(i=f;iformat->palette->ncolors; + SDL_Color colors[256]; + int i; + for (i=0; iformat->palette->colors[i].r; + colors[i].g = screen->format->palette->colors[i].g; + colors[i].b = screen->format->palette->colors[i].b; + } + + Uint32 flags = screen->flags; + + SDL_FreeSurface(screen); + + screen = SDL_SetVideoMode(0, 0, 0, flags ^ SDL_FULLSCREEN); + if(screen == NULL) { + ERR_fatal("Unable to set video mode\n"); + exit(1); + } + + SDL_SetPalette(screen, SDL_LOGPAL|SDL_PHYSPAL, colors, 0, ncolors); + } +} diff --git a/vga.h b/vga.h new file mode 100755 index 0000000..132af8c --- /dev/null +++ b/vga.h @@ -0,0 +1,238 @@ +/* + Управление графикой VGA для DOS4GW + Модуль версии 1.0 + Copyright (C) Алексей Волынсков, 1996 + + Copyright (C) Prikol Software 1996-1997 + Copyright (C) Aleksey Volynskov 1996-1997 + Copyright (C) 2011 + + This file is part of the Doom2D:Rembo project. + + Doom2D:Rembo is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation. + + Doom2D:Rembo is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see or + write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +// заголовок изображения +#pragma pack(1) +typedef struct{ + unsigned short w,h; // W-ширина,H-высота + short sx,sy; // сдвиг центра изображения +}vgaimg; + +// R-красный,G-зеленый,B-синий +typedef struct{ + unsigned char r,g,b; +}rgb_t; +#pragma pack() + +// 256-и цветовая палитра VGA +typedef rgb_t vgapal[256]; + +// карта цветов +typedef unsigned char colormap[256]; + +// тип функции перерисовки экрана +typedef void redraw_f(void); + +typedef void spr_f(int, int, unsigned char);//typedef void spr_f(void); + +// переключение в режим VGA 320x200,256 цветов +// возвращает 0, если все о'кей +short V_init(void); + +// переключение в текстовый режим +void V_done(void); + +// ждать обратного хода луча развертки +void V_wait(void); + +// вывести картинку i в координатах (x,y) +void V_pic(short x,short y,vgaimg *i); + +// вывести спрайт i в координатах (x,y) при помощи функции f +// параметры: AL=цвет_точки_спрайта EDI=>экран +// !!! сохраняйте все регистры, кроме EAX +// !!! EDI должен быть переведен на точку вправо (INC EDI или STOSB) +void V_sprf(short x,short y,vgaimg *i,spr_f *f); + +void smoke_sprf(int x, int y, unsigned char c); +void flame_sprf(int x, int y, unsigned char c); + +// вывести спрайт i в координатах (x,y) +void V_spr(short x,short y,vgaimg *i); + +// вывести зеркально перевернутый спрайт i в координатах (x,y) +void V_spr2(short x,short y,vgaimg *i); + +// вывести форму спрайта i в координатах (x,y) одним цветом c +// (подходит для рисования теней) +void V_spr1color(short x,short y,vgaimg *i,unsigned char c); + +// вывести точку цвета c в координатах (x,y) +void V_dot(short x,short y,unsigned char c); + + +void V_manspr(int x,int y,void *p,unsigned char c); + +void V_manspr2(int x,int y,void *p,unsigned char c); + + +// очистить прямоугольник цветом c +// x-левая сторона,w-ширина,y-верх,h-высота +void V_clr(short x,short w,short y,short h,unsigned char c); + +// получить текущую палитру в массив p +void VP_getall(void *p); + +// установить палитру из массива p +void VP_setall(void *p); + +// установить n цветов, начиная с f, из массива p +void VP_set(void *p,short f,short n); + +// заполнить палитру одним цветом (r,g,b) +void VP_fill(char r,char g,char b); + +// приблизить палитру p к цвету (r,g,b) на s/n +// полученная палитра находится в pal_tmp +void VP_tocolor(void *p,char r,char g,char b,char n,char s); + +// приблизить палитру p к палитре p2 на s/n +// полученная палитра находится в pal_tmp +void VP_topal(void *p,void *p2,char n,char s); + +// вывести перемасштабированный к размерам (sx,sy) спрайт i в координатах (x,y) +void VM_spr(short x,short y,short sx,short sy,vgaimg *i); + +// установить область вывода +void V_setrect(short x,short w,short y,short h); + +// установить адрес экранного буфера +// NULL - реальный экран +void V_setscr(void *); + +// скопировать прямоугольник на экран +void V_copytoscr(short x,short w,short y,short h); + +void V_maptoscr(int,int,int,int,void *); + +// вывести символ c +void V_putch(short c); + +// вывести строку s +void V_puts(char *s); + +// вычислить длину строки s (в точках) +short V_strlen(char *s); + +// вычислить ширину символа c (в точках) +short V_chrlen(char c); + +// начать анимацию a +void V_start_anim(void *a); + +// нарисовать кадр анимации +// возвращает номер кадра или 0, если конец +short V_draw_anim(void); + + +// полное описание функций RD_* см. в файле REDRAW.DOC + +// инициализация экрана +void *RD_init(short x,short w,short y,short h); + +// начать перерисовку экрана s при помощи функции f +void RD_start(void *s,redraw_f *f); + +// перерисовать прямоугольник +void RD_rect(short x,short w,short y,short h); + +// перерисовать спрайт +void RD_spr(short x,short y,vgaimg *s); +void RD_spr2(short x,short y,vgaimg *s); + +// окончание перерисовки +void RD_end(void); + + +// возвращает яркость цвета (r,g,b) +short VP_brightness(char r,char g,char b); + +// начать поиск по палитре p, состоящей из n цветов, первый - f +void VP_start_search(rgb_t *p,short n,short f); + +// найти подходящий цвет +short VP_findcolor(short r,short g,short b); + +// переделать изображение i по карте цветов m +void V_remap(vgaimg *i,colormap m); + + +// загружает палитру p из файла f (VGAED 2.0) +// возвращает 0 при ошибке +short load_pal(char *f,void *p); + +// загружает изображение i из файла f (VGAED 2.0) +// возвращает NULL при ошибке +vgaimg *load_vga(char *f,char *i); + +// загружает анимацию из файла f +// возвращает NULL при ошибке +void *load_anim(char *f); + +// область вывода +extern short scrw,scrh,scrx,scry; + +// адрес экранного буфера +extern unsigned char *scra; + +// временная палитра +extern vgapal pal_tmp; + +// ждать ли обратного хода луча при установке палитры +// 0-нет, иначе-да +extern char vp_waitrr; + +// координаты для вывода следующего символа +extern short vf_x,vf_y; + +// расстояние между символами +extern short vf_step; + +// цвет символов +// если 0 - не используется +extern unsigned char vf_color; + +// шрифт +extern void *vf_font; + +// виртуальный экран +extern unsigned char scrbuf[64000]; + + +void V_toggle(); +void V_rotspr (int x, int y, vgaimg* i, int d); +void V_center(int f); +void V_offset(int ox, int oy); +extern char fullscreen; + + +#ifdef __cplusplus +} +#endif -- 2.29.2