/* Project 16 Source Code~\r
- * Copyright (C) 2012-2017 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ * Copyright (C) 2012-2022 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
*\r
* This file is part of Project 16.\r
*\r
- * Project 16 is free software; you can redistribute it and/or modify\r
+ * Project 16 is free software; you can redistribute it and/or modify\r
* it under the terms of the GNU General Public License as published by\r
* the Free Software Foundation; either version 3 of the License, or\r
* (at your option) any later version.\r
*\r
- * Project 16 is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
+ * Project 16 is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
*\r
* You should have received a copy of the GNU General Public License\r
* along with this program. If not, see <http://www.gnu.org/licenses/>, or\r
- * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
+ * write to the Free Software Foundation, Inc., 51 Franklin Street,\r
* Fifth Floor, Boston, MA 02110-1301 USA.\r
*\r
*/\r
#include <stdlib.h>\r
#include "src/lib/16_vl.h"\r
\r
+static word far* clockw= (word far*) 0x046C; /* 18.2hz clock */\r
+//#define VGASTRIDEVARIABLE vga_state.vga_stride\r
+#define VGASTRIDEVARIABLE gvar->video.page[0].stridew\r
+\r
+//===========================================================================\r
+\r
+//==============\r
+//\r
+// VL_SetScreen\r
+//\r
+//==============\r
+\r
+void VL_SetScreen (unsigned int crtc, int pelpan)\r
+{\r
+// PROC VL_SetScreen crtc:WORD, pel:WORD\r
+// PUBLIC VL_SetScreen\r
+ word TimeCount = *clockw;\r
+ __asm {\r
+ mov cx,[TimeCount] // if TimeCount goes up by two, the retrace\r
+ add cx,2 // period was missed (an interrupt covered it)\r
+\r
+ mov dx,STATUS_REGISTER_1\r
+\r
+ // wait for a display signal to make sure the raster isn't in the middle\r
+ // of a sync\r
+\r
+#ifdef __BORLANDC__\r
+ }\r
+#endif\r
+SetScreen_waitdisplay:\r
+#ifdef __BORLANDC__\r
+ __asm {\r
+#endif\r
+ in al,dx\r
+ test al,1 //1 = display is disabled (HBL / VBL)\r
+ jnz SetScreen_waitdisplay\r
+\r
+#ifdef __BORLANDC__\r
+ }\r
+#endif\r
+SetScreen_loop:\r
+#ifdef __BORLANDC__\r
+ __asm {\r
+#endif\r
+ sti\r
+ jmp SetScreen_skip1\r
+ cli\r
+#ifdef __BORLANDC__\r
+ }\r
+#endif\r
+SetScreen_skip1:\r
+#ifdef __BORLANDC__\r
+ __asm {\r
+#endif\r
+ cmp [TimeCount],cx // will only happen if an interrupt is\r
+ jae SetScreen_setcrtc // straddling the entire retrace period\r
+\r
+ // when several succesive display not enableds occur,\r
+ // the bottom of the screen has been hit\r
+\r
+ in al,dx\r
+ test al,8\r
+ jnz SetScreen_waitdisplay\r
+ test al,1\r
+ jz SetScreen_loop\r
+\r
+ in al,dx\r
+ test al,8\r
+ jnz SetScreen_waitdisplay\r
+ test al,1\r
+ jz SetScreen_loop\r
+\r
+ in al,dx\r
+ test al,8\r
+ jnz SetScreen_waitdisplay\r
+ test al,1\r
+ jz SetScreen_loop\r
+\r
+ in al,dx\r
+ test al,8\r
+ jnz SetScreen_waitdisplay\r
+ test al,1\r
+ jz SetScreen_loop\r
+\r
+ in al,dx\r
+ test al,8\r
+ jnz SetScreen_waitdisplay\r
+ test al,1\r
+ jz SetScreen_loop\r
+\r
+#ifdef __BORLANDC__\r
+ }\r
+#endif\r
+SetScreen_setcrtc:\r
+#ifdef __BORLANDC__\r
+ __asm {\r
+#endif\r
+ // set CRTC start\r
+ // for some reason, my XT's EGA card doesn't like word outs to the CRTC index...\r
+\r
+ mov cx,[crtc]\r
+ mov dx,CRTC_INDEX\r
+ mov al,0ch //start address high register\r
+ out dx,al\r
+ inc dx\r
+ mov al,ch\r
+ out dx,al\r
+ dec dx\r
+ mov al,0dh //start address low register\r
+ out dx,al\r
+ mov al,cl\r
+ inc dx\r
+ out dx,al\r
+\r
+\r
+ // set horizontal panning\r
+\r
+ mov dx,ATR_INDEX\r
+// mov al,ATR_PELPAN or 20h\r
+ out dx,al\r
+ jmp SetScreen_done\r
+ mov al,[BYTE PTR pelpan] //pel pan value\r
+ out dx,al\r
+#ifdef __BORLANDC__\r
+ }\r
+#endif\r
+SetScreen_done:\r
+#ifdef __BORLANDC__\r
+ __asm {\r
+#endif\r
+// sti\r
+\r
+// ret\r
+ }\r
+}\r
+\r
+/*\r
+====================\r
+=\r
+= VL_SetLineWidth\r
+=\r
+= Line witdh is in WORDS, 40 words is normal width for vgaplanegr\r
+=\r
+====================\r
+*/\r
+#if 0\r
+void VL_SetLineWidth (unsigned width, global_game_variables_t *gvar)\r
+{\r
+ int i,offset;\r
+\r
+//\r
+// set wide virtual screen\r
+//\r
+ outport (CRTC_INDEX,CRTC_OFFSET+width*256);\r
+\r
+//\r
+// set up lookup tables\r
+//\r
+ gvar->video.ofs.linewidth = width*2;\r
+\r
+ offset = 0;\r
+\r
+ for (i=0;i<MAXSCANLINES;i++)\r
+ {\r
+ gvar->video.ofs.ylookup[i]=offset;\r
+ offset += gvar->video.ofs.linewidth;\r
+ }\r
+}\r
+#endif\r
/*\r
=============================================================================\r
\r
int i;\r
\r
outportb (PAL_WRITE_REG,0);\r
- for (i=0;i<256;i++)\r
+ for (i=0;i<256;i++)\r
{\r
outportb (PAL_DATA_REG,red);\r
outportb (PAL_DATA_REG,green);\r
fastpalette=v->fastpalette;\r
\r
// outportb (PAL_WRITE_REG,0);\r
-// for (i=0;i<768;i++)\r
+// for (i=0;i<768;i++)\r
// outportb(PAL_DATA_REG,*palette++);\r
\r
__asm {\r
test [ss:fastpalette],1\r
jz slowset\r
//\r
-// set palette fast for cards that can take it\r
+// set palette fast for cards that can take it\r
//\r
//mov cx,768\r
//rep outsb\r
//jmp done\r
\r
//\r
-// set palette slowly for some video cards\r
+// set palette slowly for some video cards\r
//\r
#ifdef __BORLANDC__\r
}\r
int i;\r
\r
outportb (PAL_READ_REG,0);\r
- for (i=0;i<768;i++)\r
+ for (i=0;i<768;i++)\r
*palette++ = inportb(PAL_DATA_REG);\r
}\r
\r
=\r
= VL_FadeOut\r
=\r
-= Fades the current palette to the given color in the given number of steps\r
+= Fades the current palette to the given color in the given number of steps\r
=\r
=================\r
*/\r
//\r
// fade through intermediate frames\r
//\r
- for (i=0;i<steps;i++)\r
+ for (i=0;i<steps;i++)\r
{\r
origptr = &v->palette1[start][0];\r
newptr = &v->palette2[start][0];\r
- for (j=start;j<=end;j++)\r
+ for (j=start;j<=end;j++)\r
{\r
orig = *origptr++;\r
delta = red-orig;\r
//\r
// fade through intermediate frames\r
//\r
- for (i=0;i<steps;i++)\r
+ for (i=0;i<steps;i++)\r
{\r
- for (j=start;j<=end;j++)\r
+ for (j=start;j<=end;j++)\r
{\r
delta = palette[j]-v->palette1[0][j];\r
v->palette2[0][j] = v->palette1[0][j] + delta * i / steps;\r
=\r
= VL_TestPaletteSet\r
=\r
-= Sets the palette with outsb, then reads it in and compares\r
+= Sets the palette with outsb, then reads it in and compares\r
= If it compares ok, fastpalette is set to true.\r
=\r
=================\r
{\r
int i;\r
\r
- for (i=0;i<768;i++)\r
+ for (i=0;i<768;i++)\r
v->palette1[0][i] = i;\r
\r
v->fastpalette = true;\r
v->fastpalette = false;\r
}\r
\r
+/*\r
+==================\r
+=\r
+= VL_ColorBorder\r
+=\r
+==================\r
+*/\r
+\r
+void VL_ColorBorder (int color, video_t *v)\r
+{\r
+ union REGS in, out;\r
+\r
+ in.h.ah = 0x10;\r
+ in.h.al = 0x01;\r
+ in.h.bh = color;\r
+ int86(0x10, &in, &out);\r
+ v->bordercolor = color;\r
+}\r
+\r
\r
/*\r
=============================================================================\r
=================\r
*/\r
\r
-void VL_Plot (int x, int y, int color, ofs_t *ofs)\r
+void VL_Plot (int x, int y, int color, global_game_variables_t *gvar)\r
{\r
byte mask;\r
VCLIPDEF\r
\r
+ if(!gvar->video.VL_Started) return;\r
+\r
mask = pclip[x&3];\r
VGAMAPMASK(mask);\r
- *(byte far *)MK_FP(SCREENSEG,ofs->bufferofs+(ofs->ylookup[y]+(x>>2))) = color;\r
+ //*(byte far *)MK_FP(SCREENSEG,gvar->video.ofs.bufferofs+(gvar->video.ofs.ylookup[y]+(x>>2))) = color;\r
+ //*(byte far *)MK_FP(SCREENSEG,gvar->video.ofs.bufferofs+((y*VGASTRIDEVARIABLE)+(x>>2))) = color;\r
+ *(byte far *)MK_FP(SCREENSEG,BDOFSCONV gvar->video.BOFS+((y*VGASTRIDEVARIABLE)+(x>>2))) = color;\r
VGAMAPMASK(15);\r
}\r
\r
=================\r
*/\r
\r
-void VL_Hlin (unsigned x, unsigned y, unsigned width, unsigned color, ofs_t *ofs)\r
+void VL_Hlin (unsigned x, unsigned y, unsigned width, unsigned color, global_game_variables_t *gvar)\r
{\r
unsigned xbyte;\r
byte far *dest;\r
\r
LRCLIPDEF\r
\r
+ if(!gvar->video.VL_Started) return;\r
+\r
xbyte = x>>2;\r
leftmask = lclip[x&3];\r
rightmask = rclip[(x+width-1)&3];\r
midbytes = ((x+width+3)>>2) - xbyte - 2;\r
\r
- dest = MK_FP(SCREENSEG,ofs->bufferofs+ofs->ylookup[y]+xbyte);\r
+ //dest = MK_FP(SCREENSEG,gvar->video.ofs.bufferofs+gvar->video.ofs.ylookup[y]+xbyte);\r
+ dest = MK_FP(SCREENSEG,BDOFSCONV gvar->video.BOFS+(y*VGASTRIDEVARIABLE)+xbyte);\r
\r
if (midbytes<0)\r
{\r
- // all in one byte\r
+ // all in one byte\r
VGAMAPMASK(leftmask&rightmask);\r
*dest = color;\r
VGAMAPMASK(15);\r
=================\r
*/\r
\r
-void VL_Vlin (int x, int y, int height, int color, ofs_t *ofs)\r
+void VL_Vlin (int x, int y, int height, int color, global_game_variables_t *gvar)\r
{\r
byte far *dest,mask;\r
VCLIPDEF\r
\r
+ if(!gvar->video.VL_Started) return;\r
+\r
mask = pclip[x&3];\r
VGAMAPMASK(mask);\r
\r
- dest = MK_FP(SCREENSEG,ofs->bufferofs+ofs->ylookup[y]+(x>>2));\r
+ //dest = MK_FP(SCREENSEG,gvar->video.ofs.bufferofs+gvar->video.ofs.ylookup[y]+(x>>2));\r
+ dest = MK_FP(SCREENSEG,BDOFSCONV gvar->video.BOFS+(y*VGASTRIDEVARIABLE)+(x>>2));\r
\r
while (height--)\r
{\r
*dest = color;\r
- dest += ofs->linewidth;\r
+ //dest += gvar->video.ofs.linewidth;\r
+ dest += VGASTRIDEVARIABLE;\r
}\r
\r
VGAMAPMASK(15);\r
=================\r
*/\r
\r
-void VL_Bar (int x, int y, int width, int height, int color, ofs_t *ofs)\r
+void VL_Bar (int x, int y, int width, int height, int color, global_game_variables_t *gvar)\r
{\r
byte far *dest;\r
byte leftmask,rightmask;\r
\r
LRCLIPDEF\r
\r
+ if(!gvar->video.VL_Started) return;\r
+\r
leftmask = lclip[x&3];\r
rightmask = rclip[(x+width-1)&3];\r
midbytes = ((x+width+3)>>2) - (x>>2) - 2;\r
- linedelta = ofs->linewidth-(midbytes+1);\r
+ //linedelta = gvar->video.ofs.linewidth-(midbytes+1);\r
+ linedelta = VGASTRIDEVARIABLE-(midbytes+1);\r
\r
- dest = MK_FP(SCREENSEG,ofs->bufferofs+ofs->ylookup[y]+(x>>2));\r
+ //dest = MK_FP(SCREENSEG,gvar->video.ofs.bufferofs+gvar->video.ofs.ylookup[y]+(x>>2));\r
+ dest = MK_FP(SCREENSEG,BDOFSCONV gvar->video.BOFS+(y*VGASTRIDEVARIABLE)+(x>>2));\r
\r
if (midbytes<0)\r
{\r
- // all in one byte\r
+ // all in one byte\r
VGAMAPMASK(leftmask&rightmask);\r
while (height--)\r
{\r
*dest = color;\r
- dest += ofs->linewidth;\r
+ //dest += gvar->video.ofs.linewidth;\r
+ dest += VGASTRIDEVARIABLE;\r
}\r
VGAMAPMASK(15);\r
return;\r
VGAMAPMASK(15);\r
}\r
\r
+//==========================================================================\r
+\r
+/*\r
+=================\r
+=\r
+= VL_MemToScreen\r
+=\r
+= Draws a block of data to the screen.\r
+=\r
+=================\r
+*/\r
+\r
+void VL_MemToScreen (byte far *source, int width, int height, int x, int y, global_game_variables_t *gvar)\r
+{\r
+ byte far *screen,far *dest,mask;\r
+ int plane;\r
+\r
+ width>>=2;\r
+ //dest = MK_FP(SCREENSEG,gvar->video.ofs.bufferofs+gvar->video.ofs.ylookup[y]+(x>>2));\r
+ dest = MK_FP(SCREENSEG,BDOFSCONV gvar->video.BOFS+(y*VGASTRIDEVARIABLE)+(x>>2));\r
+ mask = 1 << (x&3);\r
+\r
+ for (plane = 0; plane<4; plane++)\r
+ {\r
+ VGAMAPMASK(mask);\r
+ mask <<= 1;\r
+ if (mask == 16)\r
+ mask = 1;\r
+\r
+ screen = dest;\r
+ //for (y=0;y<height;y++,screen+=gvar->video.ofs.linewidth,source+=width)\r
+ for (y=0;y<height;y++,screen+=VGASTRIDEVARIABLE,source+=width)\r
+ _fmemcpy (screen,source,width);\r
+ }\r
+}\r
+\r
+//==========================================================================\r
\r
/*\r
==============\r
\r
VL_WaitVBL ******** NEW *********\r
\r
- Wait for the vertical retrace (returns before the actual vertical sync)\r
+ Wait for the vertical retrace (returns before the actual vertical sync)\r
\r
==============\r
*/\r
\r
mov cx,[num]\r
//\r
- // wait for a display signal to make sure the raster isn't in the middle\r
+ // wait for a display signal to make sure the raster isn't in the middle\r
// of a sync\r
//\r
#ifdef __BORLANDC__\r
}\r
\r
//===========================================================================\r
+#if 0\r
+#define VGAWRITEMODE(x) asm{\r
+ cli\r
+ mov dx,GC_INDEX\r
+ mov al,GC_MODE\r
+ out dx,al\r
+ inc dx\r
+ in al,dx\r
+ and al,252\r
+ or al,x\r
+ out dx,al\r
+ sti\r
+}\r
\r
-void VGAMAPMASK(byte x)\r
-{\r
- __asm {\r
-// cli\r
+#define VGAMAPMASK(x) asm{\r
+ cli\r
mov dx,SC_INDEX\r
mov al,SC_MAPMASK\r
mov ah,x\r
out dx,ax\r
-// sti\r
- }\r
+ sti\r
+}\r
+\r
+#define VGAREADMAP(x) asm{\r
+ cli\r
+ mov dx,GC_INDEX\r
+ mov al,GC_READMAP\r
+ mov ah,x\r
+ out dx,ax\r
+ sti\r
}\r
\r
+#define EGABITMASK(x) asm{\r
+ mov dx,GC_INDEX\r
+ mov ax,GC_BITMASK+256*x\r
+ out dx,ax\r
+ sti\r
+}\r
+#endif\r
void VGAWRITEMODE(byte x)\r
{\r
__asm {\r
-// cli\r
+ cli\r
mov dx,GC_INDEX\r
mov al,GC_MODE\r
out dx,al\r
and al,252\r
or al,x\r
out dx,al\r
-// sti\r
+ sti\r
+ }\r
+}\r
+\r
+void VGAMAPMASK(byte x)\r
+{\r
+ __asm {\r
+ cli\r
+ mov dx,SC_INDEX\r
+ mov al,SC_MAPMASK\r
+ mov ah,x\r
+ out dx,ax\r
+ sti\r
}\r
}\r
\r
void VGAREADMAP(byte x)\r
{\r
__asm {\r
-// cli\r
+ cli\r
mov dx,GC_INDEX\r
mov al,GC_READMAP\r
mov ah,x\r
out dx,ax\r
-// sti\r
+ sti\r
+ }\r
+}\r
+\r
+void VGABITMASK(byte x)\r
+{\r
+ word q = 256*x;\r
+ __asm {\r
+ mov dx,GC_INDEX\r
+ mov ax,GC_BITMASK+q\r
+ out dx,ax\r
+ sti\r
}\r
}\r
\r