/* Copyright (C) 1996-1997 Aleksey Volynskov
* Copyright (C) 2011 Rambo
* Copyright (C) 2020 SovietPony
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License ONLY.
*
* This program 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 .
*/
#include "glob.h"
#include "vga.h"
#include "error.h"
#include "view.h"
#include "memory.h"
#include "misc.h"
#include "files.h"
#include "system.h"
#include
#include
int SCRW = 800;
int SCRH = 600;
char fullscreen = OFF;
byte bright[256];
byte mixmap[256][256];
byte clrmap[256*12];
byte *buffer;
int buf_w, buf_h, pitch;
static int offx, offy;
static int cx1, cx2, cy1, cy2;
static byte flametab[16] = {
0xBC,0xBA,0xB8,0xB6,0xB4,0xB2,0xB0,0xD5,0xD6,0xD7,0xA1,0xA0,0xE3,0xE2,0xE1,0xE0
};
vgaimg *V_getvgaimg (int id) {
int loaded = M_was_locked(id);
vgaimg *v = M_lock(id);
if (v != NULL && !loaded) {
v->w = short2host(v->w);
v->h = short2host(v->h);
v->sx = short2host(v->sx);
v->sy = short2host(v->sy);
}
return v;
}
vgaimg *V_loadvgaimg (char *name) {
return V_getvgaimg(F_getresid(name));
}
void V_update_buffer (void) {
Y_get_buffer(&buffer, &buf_w, &buf_h, &pitch);
V_setrect(0, 0, buf_w, buf_h);
}
static void draw_rect (int x, int y, int w, int h, int c) {
int i;
int x0 = max(x, cx1);
int y0 = max(y, cy1);
int x1 = min(x + w - 1, cx2);
int y1 = min(y + h - 1, cy2);
int len = x1 - x0;
for (i = y0; i <= y1; i++) {
memset(&buffer[i * pitch + x0], c, len);
}
}
void V_setrect (short x, short w, short y, short h) {
assert(w >= 0);
assert(h >= 0);
cx1 = max(x, 0);
cx2 = min(x + w - 1, buf_w - 1);
cy1 = max(y, 0);
cy2 = min(y + h - 1, buf_h - 1);
}
static void putpixel (int x, int y, byte color) {
if (x >= cx1 && x <= cx2 && y >= cy1 && y <= cy2) {
buffer[y * pitch + x] = color;
}
}
static byte getpixel (int x, int y) {
return x >= cx1 && x <= cx2 && y >= cy1 && y <= cy2 ? buffer[y * pitch + x] : 0;
}
static void mappixel (int x, int y, byte *cmap) {
byte c = getpixel(x, y);
putpixel(x, y, cmap[c]);
}
void V_center (int f) {
if (f) {
V_offset(buf_w / 2 - 320 / 2, buf_h / 2 - 200 / 2);
} else {
V_offset(0, 0);
}
}
void V_offset (int ox, int oy) {
offx = ox;
offy = oy;
}
static 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) : (lx);
ry = (d & 2) ? (i->h-ly-1) : (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);
}
void V_dot (short x, short y, unsigned char c) {
putpixel(x, y, c);
}
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);
}
void V_setscr (void *p) {
Y_repaint();
}
void V_copytoscr (short x, short w, short y, short h) {
Y_repaint_rect(x, y, w, h);
}
void V_maptoscr (int x, int w, int y, int h, void *cmap) {
int cx,cy;
for (cx=x; cx