From fc7d63d3fc9f520cbd6c95ef2e070733dae4400d Mon Sep 17 00:00:00 2001 From: sparky4 Date: Tue, 20 May 2014 10:35:40 -0500 Subject: [PATCH] modified: 16/DOS_GFX.EXE modified: 16/Project 16.bfproject new file: 16/VGA8X8.FNT modified: 16/dos_gfx.cpp modified: 16/dos_gfx.h modified: 16/lib/lib_com.h deleted: 16/lib/x/MAKEFILE~ new file: 16/w_modex/BUDDHA.PCX new file: 16/w_modex/FIXED32.CPP new file: 16/w_modex/FIXED32.HPP new file: 16/w_modex/M.BAT new file: 16/w_modex/MODEX.CPP new file: 16/w_modex/MODEX.HPP new file: 16/w_modex/MONSTER.PCX new file: 16/w_modex/SINTAB.DAT new file: 16/w_modex/SPOCK.PCX new file: 16/w_modex/TEST.CPP new file: 16/w_modex/TEST.EXE new file: 16/w_modex/VGA8X8.FNT new file: 16/w_modex/XBLITBUF.CPP new file: 16/w_modex/XBLITBUF.HPP new file: 16/w_modex/XPAL.CPP new file: 16/w_modex/XPAL.HPP new file: 16/w_modex/XPRIM.CPP new file: 16/w_modex/XPRIM.HPP new file: 16/w_modex/XTYPES.HPP --- 16/DOS_GFX.EXE | Bin 27791 -> 35602 bytes 16/Project 16.bfproject | 57 ++- 16/VGA8X8.FNT | Bin 0 -> 2048 bytes 16/dos_gfx.cpp | 207 ++++---- 16/dos_gfx.h | 6 +- 16/lib/lib_com.h | 3 +- 16/lib/x/MAKEFILE~ | 82 ---- 16/w_modex/BUDDHA.PCX | Bin 0 -> 6482 bytes 16/w_modex/FIXED32.CPP | 114 +++++ 16/w_modex/FIXED32.HPP | 41 ++ 16/w_modex/M.BAT | 2 + 16/w_modex/MODEX.CPP | 913 ++++++++++++++++++++++++++++++++++ 16/w_modex/MODEX.HPP | 63 +++ 16/w_modex/MONSTER.PCX | Bin 0 -> 20257 bytes 16/w_modex/SINTAB.DAT | Bin 0 -> 2048 bytes 16/w_modex/SPOCK.PCX | Bin 0 -> 46122 bytes 16/w_modex/TEST.CPP | 634 ++++++++++++++++++++++++ 16/w_modex/TEST.EXE | Bin 0 -> 52264 bytes 16/w_modex/VGA8X8.FNT | Bin 0 -> 2048 bytes 16/w_modex/XBLITBUF.CPP | 1027 +++++++++++++++++++++++++++++++++++++++ 16/w_modex/XBLITBUF.HPP | 58 +++ 16/w_modex/XPAL.CPP | 265 ++++++++++ 16/w_modex/XPAL.HPP | 24 + 16/w_modex/XPRIM.CPP | 561 +++++++++++++++++++++ 16/w_modex/XPRIM.HPP | 31 ++ 16/w_modex/XTYPES.HPP | 17 + 26 files changed, 3898 insertions(+), 207 deletions(-) create mode 100644 16/VGA8X8.FNT delete mode 100644 16/lib/x/MAKEFILE~ create mode 100644 16/w_modex/BUDDHA.PCX create mode 100644 16/w_modex/FIXED32.CPP create mode 100644 16/w_modex/FIXED32.HPP create mode 100644 16/w_modex/M.BAT create mode 100644 16/w_modex/MODEX.CPP create mode 100644 16/w_modex/MODEX.HPP create mode 100644 16/w_modex/MONSTER.PCX create mode 100644 16/w_modex/SINTAB.DAT create mode 100644 16/w_modex/SPOCK.PCX create mode 100644 16/w_modex/TEST.CPP create mode 100644 16/w_modex/TEST.EXE create mode 100644 16/w_modex/VGA8X8.FNT create mode 100644 16/w_modex/XBLITBUF.CPP create mode 100644 16/w_modex/XBLITBUF.HPP create mode 100644 16/w_modex/XPAL.CPP create mode 100644 16/w_modex/XPAL.HPP create mode 100644 16/w_modex/XPRIM.CPP create mode 100644 16/w_modex/XPRIM.HPP create mode 100644 16/w_modex/XTYPES.HPP diff --git a/16/DOS_GFX.EXE b/16/DOS_GFX.EXE index f7e5dd4fd6852caf8e49577c662e8aba94ebdf2c..a7e672a4e7bc5cdb18332e9983ff15c555f6a102 100644 GIT binary patch literal 35602 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

Yo+$e-!nAqJE&L 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 delta 13964 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 2*/); + outp(0x3D5, Cols >> 2); + outp(0x3D4, Cols); //setVisibleStart(visStart + (Cols * height)); setVisibleStart(visStart + (Cols * width)); } @@ -586,63 +579,77 @@ I'm sorry about this being so confusing but it's a bit difficult to explain. */ -//--------------------------------------------------- -// -// Use the bios to get the address of the 8x8 font -// -// You need a font if you are going to draw text. -// -/* -int far * -getFont() +int loadfontX(char *fname) { - union REGPACK rg; - int seg; - int off; - memset(&rg, 0, sizeof(rg)); - - rg.w.ax = 0x1130; - rg.h.bh = 0x03; - intr(0x10, &rg); - seg = rg.w.es; - off = rg.w.bp; - - - return (int far *)MK_FP(seg, off); + FILE *fp; + + fp = fopen(fname, "rb"); + + if (fp == NULL) { + return 0; + } else { + fread(Xfont, 8, 256, fp); + fclose(fp); + return 1; + } } -void drawChar(int x, int y, int color, byte c) +void putchX(cord x, cord y, char c, byte color) { - int i, j; - int mask; - int far *font = getFont() + (c * 8); - - for (i = 0; i < 8; i++) - { - mask = *font; - for (j = 0; j < 8; j++) - { - if (mask & 0x80) - { - //pixel(x + j, y + i, color); - putPixel_X(x + j, y + i, color); - } - mask <<= 1; - } - font++; - } + int i; + byte *vga_ptr; + byte *font_ptr; + byte temp; + + // 8x8 font + vga_ptr = RowsX[y << 3] + (x << 1) + actStart; + write_plane = -1; + + font_ptr = Xfont + (c << 3); + + i=8; + while (i--) { + temp = *font_ptr++; + outpw(SEQU_ADDR, text_mask[temp & 0x0F]); + *vga_ptr++ = color; + + outpw(SEQU_ADDR, text_mask[temp >> 4]); + *vga_ptr-- = color; + vga_ptr += widthBytes; + } } -void drawText(int x, int y, int color, byte string) +void putstringX(cord x, cord y, char *str, byte color) { - while (string) - { - drawChar(x, y, color, string); - x += 8; - string++; + int i, skip; + byte *vga_ptr; + byte *font_ptr; + byte c, temp; + + // 8x8 font + vga_ptr = RowsX[y << 3] + (x << 1) + actStart; + write_plane = -1; + + skip = 2 - (widthBytes << 3); + + while (c = *str++) { + font_ptr = Xfont + (c << 3); + + i=8; + while (i--) { + temp = *font_ptr++; + outpw(SEQU_ADDR, text_mask[temp & 0x0F]); + *vga_ptr++ = color; + + outpw(SEQU_ADDR, text_mask[temp >> 4]); + *vga_ptr-- = color; + vga_ptr += widthBytes; } + + vga_ptr += skip; + } } -*/ + ///////////////////////////////////////////////////////////////////////////// // // // setvideo() - This function Manages the video modes // @@ -936,6 +943,7 @@ void doTest(void) int main(void) { int key,d; + //short int temp; // main variables d=1; // switch variable key=4; // default screensaver number @@ -953,7 +961,12 @@ int main(void) //++++0000 setvideo(1); -//mxInit(); + /*temp = loadfontX("vga8x8.fnt"); + + if (temp) { + putstringX(0, 0, "bakapi!", 2); + } + getch();*/ // screen savers /*while(d!=0){ // on! @@ -970,7 +983,7 @@ int main(void) } }*/ // else off while(!kbhit()){ // conditions of screen saver - ding(4); + ding(2); } //end of screen savers // doTest(); @@ -978,9 +991,9 @@ int main(void) while(!kbhit()){ // conditions of screen saver // hScroll(1); -// scrolly(1); -// delay(100); - Play(); + scrolly(1); + delay(100); +// Play(); } //++++0000 setvideo(0); diff --git a/16/dos_gfx.h b/16/dos_gfx.h index 2368faee..bc536945 100644 --- a/16/dos_gfx.h +++ b/16/dos_gfx.h @@ -15,8 +15,7 @@ // Size = 80 = 2 across, 2 down // Size = 160 = 4 across, 1 down*/ //#define VMEM 0xA000 // = vga -//int width = 320; -//int height = 240; +byte Xfont[2048]; void drawChar(int x, int y, int color, byte c); void drawText(int x, int y, int color, byte string); @@ -30,7 +29,8 @@ void cls(byte color, byte *Where); void putPixel_X(int x, int y, byte color); void putColorBox_X(int x, int y, int w, int h, byte color); void vScroll(int rows); -void scrolly(int bong); +void scrolly(int bong); +void wait_for_retrace(void); // Waits for vertical retrace //void BlockMove(); //void eraseplayer(int x, int y); //void drawplayer(int x, int y, int color); diff --git a/16/lib/lib_com.h b/16/lib/lib_com.h index 232d4270..2910d687 100644 --- a/16/lib/lib_com.h +++ b/16/lib/lib_com.h @@ -97,7 +97,8 @@ typedef unsigned char byte; -typedef unsigned int word; +typedef unsigned int word; +typedef unsigned short cord; void wait(clock_t wait); diff --git a/16/lib/x/MAKEFILE~ b/16/lib/x/MAKEFILE~ deleted file mode 100644 index c5b20124..00000000 --- a/16/lib/x/MAKEFILE~ +++ /dev/null @@ -1,82 +0,0 @@ -# -# MODEX library makefile (for Borland MAKE) -# Copyright (c) 1993,1994 by Alessandro Scotti -# -LIBINCS = MODEX.DEF - -LIBOBJS = MXBB.OBJ - MXCC.OBJ - MXCG.OBJ - MXCL.OBJ - MXCR.OBJ - MXFB.OBJ - MXFP.OBJ - MXGC.OBJ - MXGI.OBJ - MXGM.OBJ - MXGP.OBJ - MXGV.OBJ - MXHL.OBJ - MXIT.OBJ - MXLL.OBJ - MXLN.OBJ - MXOT.OBJ - MXPB.OBJ - MXPF.OBJ - MXPG.OBJ - MXPI.OBJ - MXPN.OBJ - MXPP.OBJ - MXPT.OBJ - MXRA.OBJ - MXRP.OBJ - MXSA.OBJ - MXSC.OBJ - MXSI.OBJ - MXSL.OBJ - MXSM.OBJ - MXSP.OBJ - MXSS.OBJ - MXTL.OBJ - MXVS.OBJ - MXWD.OBJ - MXWM.OBJ - MXWP.OBJ - MXWR.OBJ - -# -# ASM compiler -# -ASMC = JWASMR -ASMO = -Zm -0 - -# -# PAS compiler -# -#PASC = bpc -#PASO = /m -$D- -$L- -$S- - -# -# LIB maker, uses response file -# -LIBC = JWlibd - -.asm.obj: - $(ASMC) $(ASMO) $< - -target: modex.lib -#modex.tpu modex.tpp - -#modex.tpu: $(LIBOBJS) modex.pas -# $(PASC) $(PASO) modex -# copy modex.tpu .. -# copy modex.pas .. - -#modex.tpp: $(LIBOBJS) modex.pas -# $(PASC) /cp $(PASO) modex -# copy modex.tpp .. - -modex.lib: modex.lib $(LIBOBJS) - $(LIBC) modex.lib# @modex.lbr - -$(LIBOBJS): modex.def diff --git a/16/w_modex/BUDDHA.PCX b/16/w_modex/BUDDHA.PCX new file mode 100644 index 0000000000000000000000000000000000000000..687beebfa9f60967852f0d2517b0b5074f8f0f08 GIT binary patch literal 6482 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 literal 0 HcmV?d00001 diff --git a/16/w_modex/FIXED32.CPP b/16/w_modex/FIXED32.CPP new file mode 100644 index 00000000..ae06630e --- /dev/null +++ b/16/w_modex/FIXED32.CPP @@ -0,0 +1,114 @@ +#include + +#include "fixed32.hpp" + +Fixed32 SinTab[256]; +Fixed32 CosTab[256]; + + +void +initFixed32(void) +{ + FILE *fp; + + fp = fopen("sintab.dat", "rb"); + fread(SinTab, 4, 256, fp); + fread(CosTab, 4, 256, fp); + fclose(fp); +} + + +Fixed32 +FixedMul(Fixed32 num1, Fixed32 num2) +{ + long Mm1, Mm2; + short int MM, mm; + short int hi1, hi2, lo1, lo2; + + hi1 = (num1 >> 16); + hi2 = (num2 >> 16); + lo1 = (num1 & 0xFFFF); + lo2 = (num2 & 0xFFFF); + + MM = (hi1 * hi2); + Mm1 = (lo2 * hi1); + Mm2 = (lo1 * hi2); + mm = (lo1 * lo2); + + return (Mm1 + Mm2 + mm + (((long)MM) << 16)); +} + + +Fixed32 +FixedDiv(Fixed32 numer, Fixed32 denom) +{ + return (numer / ROUND_FIXED_TO_INT(denom)); +} + + +void +CosSin(Iangle theta, Fixed32 *Cos, Fixed32 *Sin) +{ + *Sin = SinTab[theta]; + *Cos = CosTab[theta]; +} + + +/* ASM fixedpoint math routines +;-------------------------------------------------- +; Sqrt - Fixed Point Square Root (High/Normal Precision) +; IN : ecx +; OUT : eax +; Modified : ebx,ecx,edx +Sqrt PROC + +;This is the High Precision version for the sqrt. +;It gives the optimal 8.16 precision but takes +;a little longer (24 iterations, 48 bits intead of +;16 iterations and 32 bits) + + xor eax,eax ;eax is root + mov ebx,40000000h +sqrt1: + mov edx,ecx ;edx = val + sub edx,ebx ;val - bitsqr + jb sqrt2 + sub edx,eax ;val - root + jb sqrt2 + mov ecx,edx ;val >= (root+bitsqr) -> accept subs + shr eax,1 ;root >> 1 + or eax,ebx ;root | bitsqr + shr ebx,2 ;bitsqr>>2 + jnz sqrt1 + jz sqrt5 +sqrt2: + shr eax,1 ;val < (root+bitsqr) -> dont change val + shr ebx,2 ;bitsqr>>2 + jnz sqrt1 +; we now have the 8.8 precision + +sqrt5: + mov ebx,00004000h + shl eax,16 + shl ecx,16 +sqrt3: + mov edx,ecx ;edx = val + sub edx,ebx ;val - bitsqr + jb sqrt4 + sub edx,eax ;val - root + jb sqrt4 + mov ecx,edx ;val >= (root+bitsqr) -> accept subs + shr eax,1 ;root >> 1 + or eax,ebx ;root | bitsqr + shr ebx,2 ;bitsqr>>2 + jnz sqrt3 + ret +sqrt4: + shr eax,1 ;val < (root+bitsqr) -> dont change val + shr ebx,2 ;bitsqr>>2 + jnz sqrt3 + ret + +Sqrt ENDP +*/ + diff --git a/16/w_modex/FIXED32.HPP b/16/w_modex/FIXED32.HPP new file mode 100644 index 00000000..49a084fe --- /dev/null +++ b/16/w_modex/FIXED32.HPP @@ -0,0 +1,41 @@ +#ifndef FIXEDPOINT_HPP + #define FIXEDPOINT_HPP + +typedef long Fixed32; // 16.16 FixedPoint +typedef unsigned char Iangle; // Integer angle (0..255) + +/* Macros for Type Conversion */ +#define INT_TO_FIXED(x) ((x) << 16) +#define FIXED_TO_INT(x) ((x) >> 16) +#define ROUND_FIXED_TO_INT(x) (((x) + 0x8000) >> 16) + +// Loads Fixed32 datafiles +void initFixed32(void); + +// Common math functions +Fixed32 FixedMul(Fixed32 num1, Fixed32 num2); +Fixed32 FixedDiv(Fixed32 numer, Fixed32 denom); +void CosSin(Iangle theta, Fixed32 *Cos, Fixed32 *Sin); + +Fixed32 FixedMulASM(Fixed32 num1, Fixed32 num2); +#pragma aux FixedMulASM = \ + "imul edx" \ + "add eax, 8000h" \ + "adc edx, 0" \ + "shrd eax, edx, 16" \ + parm caller [eax] [edx] \ + value [eax] \ + modify [eax edx]; + +Fixed32 FixedDivASM(Fixed32 numer, Fixed32 denom); // No rounding! +#pragma aux FixedDivASM = \ + "xor eax, eax" \ + "shrd eax, edx, 16" \ + "sar edx, 16" \ + "idiv ebx" \ + parm caller [edx] [ebx] \ + value [eax] \ + modify [eax ebx edx]; + +#endif + diff --git a/16/w_modex/M.BAT b/16/w_modex/M.BAT new file mode 100644 index 00000000..5bcb63a5 --- /dev/null +++ b/16/w_modex/M.BAT @@ -0,0 +1,2 @@ +wcl386 test modex xprim xpal xblitbuf fixed32 +erase *.obj diff --git a/16/w_modex/MODEX.CPP b/16/w_modex/MODEX.CPP new file mode 100644 index 00000000..f266a986 --- /dev/null +++ b/16/w_modex/MODEX.CPP @@ -0,0 +1,913 @@ +#include +#include +#include + +#include "modex.hpp" + +#define ATTRCON_ADDR 0x3C0 +#define MISC_ADDR 0x3C2 +#define VGAENABLE_ADDR 0x3C3 +#define SEQU_ADDR 0x3C4 +#define GRACON_ADDR 0x3CE +#define CRTC_ADDR 0x3D4 +#define STATUS_ADDR 0x3DA + +unsigned short width, height, widthBytes, num_pages; +unsigned short pageSize, activeStart, visibleStart; +unsigned char write_plane, read_plane; +unsigned char *RowsX[600]; +unsigned char line_head[4] = { 0xFF, 0x0E, 0x0C, 0x08 }; +unsigned char line_tail[4] = { 0x00, 0x01, 0x03, 0x07 }; +unsigned short plane_mask[4] = { PLANE_0, PLANE_1, PLANE_2, PLANE_3 }; +unsigned short read_mask[4] = { READ_PLANE_0, READ_PLANE_1, + READ_PLANE_2, READ_PLANE_3 }; +unsigned short text_mask[16] = { 0x0002, 0x0102, 0x0202, 0x0302, + 0x0402, 0x0502, 0x0602, 0x0702, + 0x0802, 0x0902, 0x0A02, 0x0B02, + 0x0C02, 0x0D02, 0x0E02, 0x0F02 }; +unsigned short page_offset[5]; +unsigned short page_mask_high[5]; +unsigned short page_mask_low[5]; + + +unsigned short ModeX_256x224regs[75] = +{ + 0x3c2, 0x00, 0xe3, + 0x3d4, 0x00, 0x5f, + 0x3d4, 0x01, 0x3f, + 0x3d4, 0x02, 0x40, + 0x3d4, 0x03, 0x82, + 0x3d4, 0x04, 0x4a, + 0x3d4, 0x05, 0x9a, + 0x3d4, 0x06, 0x0b, + 0x3d4, 0x07, 0x3e, + 0x3d4, 0x08, 0x00, + 0x3d4, 0x09, 0x41, + 0x3d4, 0x10, 0xda, + 0x3d4, 0x11, 0x9c, + 0x3d4, 0x12, 0xbf, + 0x3d4, 0x13, 0x20, + 0x3d4, 0x14, 0x00, + 0x3d4, 0x15, 0xc7, + 0x3d4, 0x16, 0x04, + 0x3d4, 0x17, 0xe3, + 0x3c4, 0x01, 0x01, + 0x3c4, 0x04, 0x06, + 0x3ce, 0x05, 0x40, + 0x3ce, 0x06, 0x05, + 0x3c0, 0x10, 0x41, + 0x3c0, 0x13, 0x00 +}; + +unsigned short ModeX_256x240regs[75] = +{ + 0x3c2, 0x00, 0xe3, + 0x3d4, 0x00, 0x5f, + 0x3d4, 0x01, 0x3f, + 0x3d4, 0x02, 0x40, + 0x3d4, 0x03, 0x82, + 0x3d4, 0x04, 0x4e, + 0x3d4, 0x05, 0x96, + 0x3d4, 0x06, 0x0d, + 0x3d4, 0x07, 0x3e, + 0x3d4, 0x08, 0x00, + 0x3d4, 0x09, 0x41, + 0x3d4, 0x10, 0xea, + 0x3d4, 0x11, 0xac, + 0x3d4, 0x12, 0xdf, + 0x3d4, 0x13, 0x20, + 0x3d4, 0x14, 0x00, + 0x3d4, 0x15, 0xe7, + 0x3d4, 0x16, 0x06, + 0x3d4, 0x17, 0xe3, + 0x3c4, 0x01, 0x01, + 0x3c4, 0x04, 0x06, + 0x3ce, 0x05, 0x40, + 0x3ce, 0x06, 0x05, + 0x3c0, 0x10, 0x41, + 0x3c0, 0x13, 0x00 +}; + +unsigned short ModeX_256x256regs[75] = +{ + 0x3c2, 0x00, 0xe3, + 0x3d4, 0x00, 0x5f, + 0x3d4, 0x01, 0x3f, + 0x3d4, 0x02, 0x40, + 0x3d4, 0x03, 0x82, + 0x3d4, 0x04, 0x4a, + 0x3d4, 0x05, 0x9a, + 0x3d4, 0x06, 0x23, + 0x3d4, 0x07, 0xb2, + 0x3d4, 0x08, 0x00, + 0x3d4, 0x09, 0x61, + 0x3d4, 0x10, 0x0a, + 0x3d4, 0x11, 0xac, + 0x3d4, 0x12, 0xff, + 0x3d4, 0x13, 0x20, + 0x3d4, 0x14, 0x00, + 0x3d4, 0x15, 0x07, + 0x3d4, 0x16, 0x1a, + 0x3d4, 0x17, 0xe3, + 0x3c4, 0x01, 0x01, + 0x3c4, 0x04, 0x06, + 0x3ce, 0x05, 0x40, + 0x3ce, 0x06, 0x05, + 0x3c0, 0x10, 0x41, + 0x3c0, 0x13, 0x00 +}; + +unsigned short ModeX_256x480regs[75] = +{ + 0x3c2, 0x00, 0xe3, + 0x3d4, 0x00, 0x5f, + 0x3d4, 0x01, 0x3f, + 0x3d4, 0x02, 0x40, + 0x3d4, 0x03, 0x82, + 0x3d4, 0x04, 0x4e, + 0x3d4, 0x05, 0x96, + 0x3d4, 0x06, 0x0d, + 0x3d4, 0x07, 0x3e, + 0x3d4, 0x08, 0x00, + 0x3d4, 0x09, 0x40, + 0x3d4, 0x10, 0xea, + 0x3d4, 0x11, 0xac, + 0x3d4, 0x12, 0xdf, + 0x3d4, 0x13, 0x20, + 0x3d4, 0x14, 0x00, + 0x3d4, 0x15, 0xe7, + 0x3d4, 0x16, 0x06, + 0x3d4, 0x17, 0xe3, + 0x3c4, 0x01, 0x01, + 0x3c4, 0x04, 0x06, + 0x3ce, 0x05, 0x40, + 0x3ce, 0x06, 0x05, + 0x3c0, 0x10, 0x41, + 0x3c0, 0x13, 0x00 +}; + +unsigned short ModeX_320x200regs[75] = +{ + 0x3c2, 0x00, 0x63, + 0x3d4, 0x00, 0x5f, + 0x3d4, 0x01, 0x4f, + 0x3d4, 0x02, 0x50, + 0x3d4, 0x03, 0x82, + 0x3d4, 0x04, 0x54, + 0x3d4, 0x05, 0x80, + 0x3d4, 0x06, 0xbf, + 0x3d4, 0x07, 0x1f, + 0x3d4, 0x08, 0x00, + 0x3d4, 0x09, 0x41, + 0x3d4, 0x10, 0x9c, + 0x3d4, 0x11, 0x8e, + 0x3d4, 0x12, 0x8f, + 0x3d4, 0x13, 0x28, + 0x3d4, 0x14, 0x00, + 0x3d4, 0x15, 0x96, + 0x3d4, 0x16, 0xb9, + 0x3d4, 0x17, 0xe3, + 0x3c4, 0x01, 0x01, + 0x3c4, 0x04, 0x06, + 0x3ce, 0x05, 0x40, + 0x3ce, 0x06, 0x05, + 0x3c0, 0x10, 0x41, + 0x3c0, 0x13, 0x00 +}; + +unsigned short ModeX_320x240regs[75] = +{ + 0x3c2, 0x00, 0xe3, + 0x3d4, 0x00, 0x5f, + 0x3d4, 0x01, 0x4f, + 0x3d4, 0x02, 0x50, + 0x3d4, 0x03, 0x82, + 0x3d4, 0x04, 0x54, + 0x3d4, 0x05, 0x80, + 0x3d4, 0x06, 0x0d, + 0x3d4, 0x07, 0x3e, + 0x3d4, 0x08, 0x00, + 0x3d4, 0x09, 0x41, + 0x3d4, 0x10, 0xea, + 0x3d4, 0x11, 0xac, + 0x3d4, 0x12, 0xdf, + 0x3d4, 0x13, 0x28, + 0x3d4, 0x14, 0x00, + 0x3d4, 0x15, 0xe7, + 0x3d4, 0x16, 0x06, + 0x3d4, 0x17, 0xe3, + 0x3c4, 0x01, 0x01, + 0x3c4, 0x04, 0x06, + 0x3ce, 0x05, 0x40, + 0x3ce, 0x06, 0x05, + 0x3c0, 0x10, 0x41, + 0x3c0, 0x13, 0x00 +}; + +unsigned short ModeX_320x400regs[75] = +{ + 0x3c2, 0x00, 0x63, + 0x3d4, 0x00, 0x5f, + 0x3d4, 0x01, 0x4f, + 0x3d4, 0x02, 0x50, + 0x3d4, 0x03, 0x82, + 0x3d4, 0x04, 0x54, + 0x3d4, 0x05, 0x80, + 0x3d4, 0x06, 0xbf, + 0x3d4, 0x07, 0x1f, + 0x3d4, 0x08, 0x00, + 0x3d4, 0x09, 0x40, + 0x3d4, 0x10, 0x9c, + 0x3d4, 0x11, 0x8e, + 0x3d4, 0x12, 0x8f, + 0x3d4, 0x13, 0x28, + 0x3d4, 0x14, 0x00, + 0x3d4, 0x15, 0x96, + 0x3d4, 0x16, 0xb9, + 0x3d4, 0x17, 0xe3, + 0x3c4, 0x01, 0x01, + 0x3c4, 0x04, 0x06, + 0x3ce, 0x05, 0x40, + 0x3ce, 0x06, 0x05, + 0x3c0, 0x10, 0x41, + 0x3c0, 0x13, 0x00 +}; + +unsigned short ModeX_320x480regs[75] = +{ + 0x3c2, 0x00, 0xe3, + 0x3d4, 0x00, 0x5f, + 0x3d4, 0x01, 0x4f, + 0x3d4, 0x02, 0x50, + 0x3d4, 0x03, 0x82, + 0x3d4, 0x04, 0x54, + 0x3d4, 0x05, 0x80, + 0x3d4, 0x06, 0x0d, + 0x3d4, 0x07, 0x3e, + 0x3d4, 0x08, 0x00, + 0x3d4, 0x09, 0x40, + 0x3d4, 0x10, 0xea, + 0x3d4, 0x11, 0xac, + 0x3d4, 0x12, 0xdf, + 0x3d4, 0x13, 0x28, + 0x3d4, 0x14, 0x00, + 0x3d4, 0x15, 0xe7, + 0x3d4, 0x16, 0x06, + 0x3d4, 0x17, 0xe3, + 0x3c4, 0x01, 0x01, + 0x3c4, 0x04, 0x06, + 0x3ce, 0x05, 0x40, + 0x3ce, 0x06, 0x05, + 0x3c0, 0x10, 0x41, + 0x3c0, 0x13, 0x00 +}; + +unsigned short ModeX_360x200regs[75] = +{ + 0x3c2, 0x00, 0x67, + 0x3d4, 0x00, 0x6b, + 0x3d4, 0x01, 0x59, + 0x3d4, 0x02, 0x5a, + 0x3d4, 0x03, 0x8e, + 0x3d4, 0x04, 0x5e, + 0x3d4, 0x05, 0x8a, + 0x3d4, 0x06, 0xbf, + 0x3d4, 0x07, 0x1f, + 0x3d4, 0x08, 0x00, + 0x3d4, 0x09, 0x41, + 0x3d4, 0x10, 0x9c, + 0x3d4, 0x11, 0x8e, + 0x3d4, 0x12, 0x8f, + 0x3d4, 0x13, 0x2d, + 0x3d4, 0x14, 0x00, + 0x3d4, 0x15, 0x96, + 0x3d4, 0x16, 0xb9, + 0x3d4, 0x17, 0xe3, + 0x3c4, 0x01, 0x01, + 0x3c4, 0x04, 0x06, + 0x3ce, 0x05, 0x40, + 0x3ce, 0x06, 0x05, + 0x3c0, 0x10, 0x41, + 0x3c0, 0x13, 0x00 +}; + +unsigned short ModeX_360x240regs[75] = +{ + 0x3c2, 0x00, 0xe7, + 0x3d4, 0x00, 0x6b, + 0x3d4, 0x01, 0x59, + 0x3d4, 0x02, 0x5a, + 0x3d4, 0x03, 0x8e, + 0x3d4, 0x04, 0x5e, + 0x3d4, 0x05, 0x8a, + 0x3d4, 0x06, 0x0d, + 0x3d4, 0x07, 0x3e, + 0x3d4, 0x08, 0x00, + 0x3d4, 0x09, 0x41, + 0x3d4, 0x10, 0xea, + 0x3d4, 0x11, 0xac, + 0x3d4, 0x12, 0xdf, + 0x3d4, 0x13, 0x2d, + 0x3d4, 0x14, 0x00, + 0x3d4, 0x15, 0xe7, + 0x3d4, 0x16, 0x06, + 0x3d4, 0x17, 0xe3, + 0x3c4, 0x01, 0x01, + 0x3c4, 0x04, 0x06, + 0x3ce, 0x05, 0x40, + 0x3ce, 0x06, 0x05, + 0x3c0, 0x10, 0x41, + 0x3c0, 0x13, 0x00 +}; + +unsigned short ModeX_360x270regs[75] = +{ + 0x3c2, 0x00, 0xe7, + 0x3d4, 0x00, 0x6b, + 0x3d4, 0x01, 0x59, + 0x3d4, 0x02, 0x5a, + 0x3d4, 0x03, 0x8e, + 0x3d4, 0x04, 0x5e, + 0x3d4, 0x05, 0x8a, + 0x3d4, 0x06, 0x30, + 0x3d4, 0x07, 0xf0, + 0x3d4, 0x08, 0x00, + 0x3d4, 0x09, 0x61, + 0x3d4, 0x10, 0x20, + 0x3d4, 0x11, 0xa9, + 0x3d4, 0x12, 0x1b, + 0x3d4, 0x13, 0x2d, + 0x3d4, 0x14, 0x00, + 0x3d4, 0x15, 0x1f, + 0x3d4, 0x16, 0x2f, + 0x3d4, 0x17, 0xe3, + 0x3c4, 0x01, 0x01, + 0x3c4, 0x04, 0x06, + 0x3ce, 0x05, 0x40, + 0x3ce, 0x06, 0x05, + 0x3c0, 0x10, 0x41, + 0x3c0, 0x13, 0x00 +}; + +unsigned short ModeX_360x360regs[75] = +{ + 0x3c2, 0x00, 0x67, + 0x3d4, 0x00, 0x6b, + 0x3d4, 0x01, 0x59, + 0x3d4, 0x02, 0x5a, + 0x3d4, 0x03, 0x8e, + 0x3d4, 0x04, 0x5e, + 0x3d4, 0x05, 0x8a, + 0x3d4, 0x06, 0xbf, + 0x3d4, 0x07, 0x1f, + 0x3d4, 0x08, 0x00, + 0x3d4, 0x09, 0x40, + 0x3d4, 0x10, 0x88, + 0x3d4, 0x11, 0x85, + 0x3d4, 0x12, 0x67, + 0x3d4, 0x13, 0x2d, + 0x3d4, 0x14, 0x00, + 0x3d4, 0x15, 0x6d, + 0x3d4, 0x16, 0xba, + 0x3d4, 0x17, 0xe3, + 0x3c4, 0x01, 0x01, + 0x3c4, 0x04, 0x06, + 0x3ce, 0x05, 0x40, + 0x3ce, 0x06, 0x05, + 0x3c0, 0x10, 0x41, + 0x3c0, 0x13, 0x00 +}; + +unsigned short ModeX_360x400regs[75] = +{ + 0x3c2, 0x00, 0x67, + 0x3d4, 0x00, 0x6b, + 0x3d4, 0x01, 0x59, + 0x3d4, 0x02, 0x5a, + 0x3d4, 0x03, 0x8e, + 0x3d4, 0x04, 0x5e, + 0x3d4, 0x05, 0x8a, + 0x3d4, 0x06, 0xbf, + 0x3d4, 0x07, 0x1f, + 0x3d4, 0x08, 0x00, + 0x3d4, 0x09, 0x40, + 0x3d4, 0x10, 0x9c, + 0x3d4, 0x11, 0x8e, + 0x3d4, 0x12, 0x8f, + 0x3d4, 0x13, 0x2d, + 0x3d4, 0x14, 0x00, + 0x3d4, 0x15, 0x96, + 0x3d4, 0x16, 0xb9, + 0x3d4, 0x17, 0xe3, + 0x3c4, 0x01, 0x01, + 0x3c4, 0x04, 0x06, + 0x3ce, 0x05, 0x40, + 0x3ce, 0x06, 0x05, + 0x3c0, 0x10, 0x41, + 0x3c0, 0x13, 0x00 +}; + +unsigned short ModeX_360x480regs[75] = +{ + 0x3c2, 0x00, 0xe7, + 0x3d4, 0x00, 0x6b, + 0x3d4, 0x01, 0x59, + 0x3d4, 0x02, 0x5a, + 0x3d4, 0x03, 0x8e, + 0x3d4, 0x04, 0x5e, + 0x3d4, 0x05, 0x8a, + 0x3d4, 0x06, 0x0d, + 0x3d4, 0x07, 0x3e, + 0x3d4, 0x08, 0x00, + 0x3d4, 0x09, 0x40, + 0x3d4, 0x10, 0xea, + 0x3d4, 0x11, 0xac, + 0x3d4, 0x12, 0xdf, + 0x3d4, 0x13, 0x2d, + 0x3d4, 0x14, 0x00, + 0x3d4, 0x15, 0xe7, + 0x3d4, 0x16, 0x06, + 0x3d4, 0x17, 0xe3, + 0x3c4, 0x01, 0x01, + 0x3c4, 0x04, 0x06, + 0x3ce, 0x05, 0x40, + 0x3ce, 0x06, 0x05, + 0x3c0, 0x10, 0x41, + 0x3c0, 0x13, 0x00 +}; + +unsigned short ModeX_376x282regs[75] = +{ + 0x3c2, 0x00, 0xe7, + 0x3d4, 0x00, 0x6e, + 0x3d4, 0x01, 0x5d, + 0x3d4, 0x02, 0x5e, + 0x3d4, 0x03, 0x91, + 0x3d4, 0x04, 0x62, + 0x3d4, 0x05, 0x8f, + 0x3d4, 0x06, 0x62, + 0x3d4, 0x07, 0xf0, + 0x3d4, 0x08, 0x00, + 0x3d4, 0x09, 0x61, + 0x3d4, 0x10, 0x37, + 0x3d4, 0x11, 0x89, + 0x3d4, 0x12, 0x33, + 0x3d4, 0x13, 0x2f, + 0x3d4, 0x14, 0x00, + 0x3d4, 0x15, 0x3c, + 0x3d4, 0x16, 0x5c, + 0x3d4, 0x17, 0xe3, + 0x3c4, 0x01, 0x01, + 0x3c4, 0x04, 0x06, + 0x3ce, 0x05, 0x40, + 0x3ce, 0x06, 0x05, + 0x3c0, 0x10, 0x41, + 0x3c0, 0x13, 0x00 +}; + +unsigned short ModeX_376x564regs[75] = +{ + 0x3c2, 0x00, 0xe7, + 0x3d4, 0x00, 0x6e, + 0x3d4, 0x01, 0x5d, + 0x3d4, 0x02, 0x5e, + 0x3d4, 0x03, 0x91, + 0x3d4, 0x04, 0x62, + 0x3d4, 0x05, 0x8f, + 0x3d4, 0x06, 0x62, + 0x3d4, 0x07, 0xf0, + 0x3d4, 0x08, 0x00, + 0x3d4, 0x09, 0x60, + 0x3d4, 0x10, 0x37, + 0x3d4, 0x11, 0x89, + 0x3d4, 0x12, 0x33, + 0x3d4, 0x13, 0x2f, + 0x3d4, 0x14, 0x00, + 0x3d4, 0x15, 0x3c, + 0x3d4, 0x16, 0x5c, + 0x3d4, 0x17, 0xe3, + 0x3c4, 0x01, 0x01, + 0x3c4, 0x04, 0x06, + 0x3ce, 0x05, 0x40, + 0x3ce, 0x06, 0x05, + 0x3c0, 0x10, 0x41, + 0x3c0, 0x13, 0x00 +}; + +unsigned short ModeX_400x300regs[78] = +{ + 0x3c2, 0x00, 0xa7, + 0x3d4, 0x00, 0x71, + 0x3d4, 0x01, 0x63, + 0x3d4, 0x02, 0x64, + 0x3d4, 0x03, 0x92, + 0x3d4, 0x04, 0x65, + 0x3d4, 0x05, 0x82, + 0x3d4, 0x06, 0x46, + 0x3d4, 0x07, 0x1f, + 0x3d4, 0x08, 0x00, + 0x3d4, 0x09, 0x40, + 0x3d4, 0x10, 0x31, + 0x3d4, 0x11, 0x80, + 0x3d4, 0x12, 0x2b, + 0x3d4, 0x13, 0x32, + 0x3d4, 0x14, 0x00, + 0x3d4, 0x15, 0x2f, + 0x3d4, 0x16, 0x44, + 0x3d4, 0x17, 0xe3, + 0x3c4, 0x01, 0x01, + 0x3c4, 0x02, 0x0f, + 0x3c4, 0x04, 0x06, + 0x3ce, 0x05, 0x40, + 0x3ce, 0x06, 0x05, + 0x3c0, 0x10, 0x41, + 0x3c0, 0x13, 0x00 +}; + +unsigned short ModeX_400x600regs[78] = +{ + 0x3c2, 0x00, 0xe7, + 0x3d4, 0x00, 0x70, + 0x3d4, 0x01, 0x63, + 0x3d4, 0x02, 0x64, + 0x3d4, 0x03, 0x92, + 0x3d4, 0x04, 0x65, + 0x3d4, 0x05, 0x82, + 0x3d4, 0x06, 0x70, + 0x3d4, 0x07, 0xf0, + 0x3d4, 0x08, 0x00, + 0x3d4, 0x09, 0x60, + 0x3d4, 0x10, 0x5b, + 0x3d4, 0x11, 0x8c, + 0x3d4, 0x12, 0x57, + 0x3d4, 0x13, 0x32, + 0x3d4, 0x14, 0x00, + 0x3d4, 0x15, 0x58, + 0x3d4, 0x16, 0x70, + 0x3d4, 0x17, 0xe3, + 0x3c4, 0x01, 0x01, + 0x3c4, 0x02, 0x0f, + 0x3c4, 0x04, 0x06, + 0x3ce, 0x05, 0x40, + 0x3ce, 0x06, 0x05, + 0x3c0, 0x10, 0x41, + 0x3c0, 0x13, 0x00 +}; + + +void +calc_rows(void) +{ + int i; + + // Each byte addresses four pixels, so the width of a scan line + // in *bytes* is one fourth of the number of pixels on a line. + widthBytes = width / 4; + + pageSize = (widthBytes * height); + + for (i=0; i < height; i++) { + RowsX[i] = (unsigned char *)((0xA000 << 4) + (widthBytes * i)); + } + + // Clear entire video memory, by selecting all four planes, then + // writing 0 to entire segment. + outpw(SEQU_ADDR, ALL_PLANES); + memset((unsigned char *)(0xA000 << 4), 0x00, 0x00010000); + + // By default we want screen refreshing and drawing operations + // to be based at offset 0 in the video segment. + activeStart = visibleStart = 0; + + // Set current plane to invalid value + write_plane = -1; + read_plane = -1; + + // How many pages fit in 256K VGA Card? + num_pages = ((64 * 1024) / pageSize); + + for (i=0; i < num_pages; i++) { + page_offset[i] = (pageSize * i); + page_mask_high[i] = (0x0C | (page_offset[i] & 0xFF00)); + page_mask_low[i] = (0x0D | ((page_offset[i] & 0x00FF) << 8)); + } +} + + +// setBaseXMode() does the initialization to make the VGA ready to +// accept any combination of configuration register settings. This +// involves enabling writes to index 0 to 7 of the CRT controller (port +// 0x3D4), by clearing the most significant bit (bit 7) of index 0x11. +void +setBaseXMode(void) +{ + int temp; + union REGS r; + + r.x.eax = 0x0013; + int386(0x10, &r, &r); + + outp(0x3D4, 0x11); + temp = inp(0x3D5) & 0x7F; + outp(0x3D4, 0x11); + outp(0x3D5, temp); +} + + +void +outReg(unsigned short *r) +{ + switch (r[0]) { + // First handle special cases: + + case ATTRCON_ADDR: + // reset read/write flip-flop + inp(STATUS_ADDR); + outp(ATTRCON_ADDR, r[1] | 0x20); + // ensure VGA output is enabled + outp(ATTRCON_ADDR, r[2]); + break; + + case MISC_ADDR: + case VGAENABLE_ADDR: + // Copy directly to port + outp(r[0], r[2]); + break; + + case SEQU_ADDR: + case GRACON_ADDR: + case CRTC_ADDR: + default: + // Index to port + outp(r[0], r[1]); + // Value to port+1 + outp(r[0] + 1, r[2]); + break; + } +} + +void +outRegArray(unsigned short *r, int n) +{ + while (n--) { + outReg(r); + r += 3; + } +} + + +void +set80x25(void) +{ + union REGS r; + r.x.eax = 0x0003; + + int386(0x10, &r, &r); +} + +void +set256x224x256_X(void) +{ + setBaseXMode(); + outRegArray(ModeX_256x224regs, 25); + + width = 256; + height = 224; + + calc_rows(); +} + +void +set256x240x256_X(void) +{ + setBaseXMode(); + outRegArray(ModeX_256x240regs, 25); + + width = 256; + height = 240; + + calc_rows(); +} + +void +set256x256x256_X(void) +{ + setBaseXMode(); + outRegArray(ModeX_256x256regs, 25); + + width = 256; + height = 256; + + calc_rows(); +} + +void +set256x480x256_X(void) +{ + setBaseXMode(); + outRegArray(ModeX_256x480regs, 25); + + width = 256; + height = 480; + + calc_rows(); +} + +void +set320x200x256_X(void) +{ + setBaseXMode(); + outRegArray(ModeX_320x200regs, 25); + + width = 320; + height = 200; + + calc_rows(); +} + +void +set320x240x256_X(void) +{ + setBaseXMode(); + outRegArray(ModeX_320x240regs, 25); + + width = 320; + height = 240; + + calc_rows(); +} + +void +set320x400x256_X(void) +{ + setBaseXMode(); + outRegArray(ModeX_320x400regs, 25); + + width = 320; + height = 400; + + calc_rows(); +} + +void +set320x480x256_X(void) +{ + setBaseXMode(); + outRegArray(ModeX_320x480regs, 25); + + width = 320; + height = 480; + + calc_rows(); +} + +void +set360x200x256_X(void) +{ + setBaseXMode(); + outRegArray(ModeX_360x200regs, 25); + + width = 360; + height = 200; + + calc_rows(); +} + +void +set360x240x256_X(void) +{ + setBaseXMode(); + outRegArray(ModeX_360x240regs, 25); + + width = 360; + height = 240; + + calc_rows(); +} + +void +set360x270x256_X(void) +{ + setBaseXMode(); + outRegArray(ModeX_360x270regs, 25); + + width = 360; + height = 270; + + calc_rows(); +} + +void +set360x360x256_X(void) +{ + setBaseXMode(); + outRegArray(ModeX_360x360regs, 25); + + width = 360; + height = 360; + + calc_rows(); +} + +void +set360x400x256_X(void) +{ + setBaseXMode(); + outRegArray(ModeX_360x400regs, 25); + + width = 360; + height = 400; + + calc_rows(); +} + +void +set360x480x256_X(void) +{ + setBaseXMode(); + outRegArray(ModeX_360x480regs, 25); + + width = 360; + height = 480; + + calc_rows(); +} + +void +set376x282x256_X(void) +{ + setBaseXMode(); + outRegArray(ModeX_376x282regs, 25); + + width = 376; + height = 282; + + calc_rows(); +} + +void +set376x564x256_X(void) +{ + setBaseXMode(); + outRegArray(ModeX_376x564regs, 25); + + width = 376; + height = 564; + + calc_rows(); +} + +void +set400x300x256_X(void) +{ + setBaseXMode(); + outRegArray(ModeX_400x300regs, 26); + + width = 400; + height = 300; + + calc_rows(); +} + +void +set400x600x256_X(void) +{ + setBaseXMode(); + outRegArray(ModeX_400x600regs, 26); + + width = 400; + height = 600; + + calc_rows(); +} + + +COORD +get_xres(void) +{ + return width; +} + + +COORD +get_yres(void) +{ + return height; +} + + +void +set_write_plane(unsigned short int plane_mask) +{ + write_plane = -1; + outpw(SEQU_ADDR, plane_mask); +} + + +void +set_read_plane(unsigned short int plane_mask) +{ + read_plane = -1; + outpw(GRACON_ADDR, plane_mask); +} + diff --git a/16/w_modex/MODEX.HPP b/16/w_modex/MODEX.HPP new file mode 100644 index 00000000..d17c93b3 --- /dev/null +++ b/16/w_modex/MODEX.HPP @@ -0,0 +1,63 @@ +#ifndef MODEX_HPP + #define MODEX_HPP + +#include "xtypes.hpp" + +// Some defines +#define PLANE_0 0x0102 +#define PLANE_1 0x0202 +#define PLANE_2 0x0402 +#define PLANE_3 0x0802 +#define ALL_PLANES 0x0F02 +#define READ_PLANE_0 0x0004 +#define READ_PLANE_1 0x0104 +#define READ_PLANE_2 0x0204 +#define READ_PLANE_3 0x0304 + + +// External Variables needed by graphics routines +extern unsigned short width, height, widthBytes, num_pages; +extern unsigned short activeStart, visibleStart, pageSize; +extern unsigned char write_plane, read_plane; +extern unsigned char *RowsX[600]; +extern unsigned char line_head[4]; +extern unsigned char line_tail[4]; +extern unsigned short plane_mask[4]; +extern unsigned short read_mask[4]; +extern unsigned short text_mask[16]; +extern unsigned short page_offset[5]; +extern unsigned short page_mask_high[5]; +extern unsigned short page_mask_low[5]; + + +// Return to text mode +void set80x25(void); + +// Set various ModeX resolutions +void set256x224x256_X(void); +void set256x240x256_X(void); +void set256x256x256_X(void); +void set256x480x256_X(void); +void set320x200x256_X(void); +void set320x240x256_X(void); +void set320x400x256_X(void); +void set320x480x256_X(void); +void set360x200x256_X(void); +void set360x240x256_X(void); +void set360x270x256_X(void); +void set360x360x256_X(void); +void set360x400x256_X(void); +void set360x480x256_X(void); +void set376x282x256_X(void); +void set376x564x256_X(void); +void set400x300x256_X(void); +void set400x600x256_X(void); + +COORD get_xres(void); +COORD get_yres(void); + +void set_write_plane(unsigned short int plane_mask); +void set_read_plane(unsigned short int plane_mask); + +#endif + diff --git a/16/w_modex/MONSTER.PCX b/16/w_modex/MONSTER.PCX new file mode 100644 index 0000000000000000000000000000000000000000..59b8a3b8927125e6ca18d94cbb414c300a97168c GIT binary patch literal 20257 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

u2%EY*3xN>_Jr_U($SET=lJP}hT!5%> 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%0AE~LK5h;E@z#2LDxmxGOF&th2R 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 MVJ{i|;~)R{KepIQzyJUM literal 0 HcmV?d00001 diff --git a/16/w_modex/TEST.CPP b/16/w_modex/TEST.CPP new file mode 100644 index 00000000..d62d5b35 --- /dev/null +++ b/16/w_modex/TEST.CPP @@ -0,0 +1,634 @@ +#include +#include +#include +#include +#include +#include + +#include "fixed32.hpp" +#include "modex.hpp" +#include "xprim.hpp" +#include "xpal.hpp" +#include "xblitbuf.hpp" + +#define FIRE_DEMO 1 +#define ROTATE_DEMO 1 +#define MONSTER_DEMO_ONE 1 +#define MONSTER_DEMO_TWO 1 +#define MATH_DEMO 0 + +int +monster_demo1(void) +{ + clock_t begin, end; + short int i; + blitbuf sprite_image, blit_image; + + clearX(0); + + load_blitbufPCX("monster.pcx", &sprite_image); + aligned_bitblitX(0, 20, &sprite_image); + getch(); + + blit_image.image = NULL; + + i=99; + + begin = clock(); + + while (i > 0) { + scale_blitbuf(120 + (i << 1), (i << 1), &sprite_image, &blit_image); + boxX((99 - i), (119 - i), (220 + i), (120 + i), 0); + vanilla_bitblitX(100 - i, 120 - i, &blit_image); + i--; + } + + end = clock(); + + i=120; + while (i > 0) { + scale_blitbuf(i, 2, &sprite_image, &blit_image); + + putpixelX(159 - (i >> 1), 119, 0); + putpixelX(159 - (i >> 1), 120, 0); + putpixelX(160 + (i >> 1), 119, 0); + putpixelX(160 + (i >> 1), 120, 0); + + vanilla_bitblitX(160 - (i >> 1), 119, &blit_image); + delay(10); + i -= 2; + } + + filledboxX(156, 119, 163, 120, 0); + putpixelX(159, 120, 1); + delay(250); + putpixelX(159, 120, 0); + + filledboxX(156, 119, 163, 120, 0); + clear_blitbuf(&sprite_image); + clear_blitbuf(&blit_image); + + getch(); + + return (end - begin); +} + + +void +monster_demo2(void) +{ + short int i; + blitbuf sprite_image, blit_image; + + clearX(0); + + load_blitbufPCX("monster.pcx", &sprite_image); + aligned_bitblitX(0, 20, &sprite_image); + getch(); + + blit_image.image = NULL; + + i=99; + while (i) { + vertical_scale_blitbuf((i << 1), &sprite_image, &blit_image); + boxX(0, (119 - i), 319, (120 + i), 0); + aligned_bitblitX(0, 120 - i, &blit_image); + i--; + } + + filledboxX(0, 120, 319, 120, 0); + + i=318; + while (i > 0) { + scale_blitbuf(i, 1, &blit_image, &sprite_image); + + putpixelX(159 - (i >> 1), 119, 0); + putpixelX(159 - (i >> 1), 120, 0); + putpixelX(160 + (i >> 1), 119, 0); + putpixelX(160 + (i >> 1), 120, 0); + + vanilla_bitblitX(160 - (i >> 1), 119, &sprite_image); + delay(5); + i -= 2; + } + + filledboxX(156, 119, 163, 120, 0); + putpixelX(159, 120, 1); + delay(250); + putpixelX(159, 120, 0); + filledboxX(156, 119, 163, 120, 0); + clear_blitbuf(&sprite_image); + clear_blitbuf(&blit_image); + + getch(); +} + + +void +fire_demo(void) +{ + #define V_WIDTH 80 + #define V_HEIGHT 50 + #define BUF_WIDTH 80 + #define BUF_HEIGHT 56 + #define REWIND (V_WIDTH * 3) + #define BUF_SIZE (BUF_WIDTH * BUF_HEIGHT) + +unsigned char fire_pal[768] = { + 0, 0, 0, 0, 0, 24, 0, 0, 24, 0, 0, 28, + 0, 0, 32, 0, 0, 32, 0, 0, 36, 0, 0, 40, + 8, 0, 40, 16, 0, 36, 24, 0, 36, 32, 0, 32, + 40, 0, 28, 48, 0, 28, 56, 0, 24, 64, 0, 20, + 72, 0, 20, 80, 0, 16, 88, 0, 16, 96, 0, 12, + 104, 0, 8, 112, 0, 8, 120, 0, 4, 128, 0, 0, + 128, 0, 0, 132, 0, 0, 136, 0, 0, 140, 0, 0, + 144, 0, 0, 144, 0, 0, 148, 0, 0, 152, 0, 0, + 156, 0, 0, 160, 0, 0, 160, 0, 0, 164, 0, 0, + 168, 0, 0, 172, 0, 0, 176, 0, 0, 180, 0, 0, + 184, 4, 0, 188, 4, 0, 192, 8, 0, 196, 8, 0, + 200, 12, 0, 204, 12, 0, 208, 16, 0, 212, 16, 0, + 216, 20, 0, 220, 20, 0, 224, 24, 0, 228, 24, 0, + 232, 28, 0, 236, 28, 0, 240, 32, 0, 244, 32, 0, + 252, 36, 0, 252, 36, 0, 252, 40, 0, 252, 40, 0, + 252, 44, 0, 252, 44, 0, 252, 48, 0, 252, 48, 0, + 252, 52, 0, 252, 52, 0, 252, 56, 0, 252, 56, 0, + 252, 60, 0, 252, 60, 0, 252, 64, 0, 252, 64, 0, + 252, 68, 0, 252, 68, 0, 252, 72, 0, 252, 72, 0, + 252, 76, 0, 252, 76, 0, 252, 80, 0, 252, 80, 0, + 252, 84, 0, 252, 84, 0, 252, 88, 0, 252, 88, 0, + 252, 92, 0, 252, 96, 0, 252, 96, 0, 252, 100, 0, + 252, 100, 0, 252, 104, 0, 252, 104, 0, 252, 108, 0, + 252, 108, 0, 252, 112, 0, 252, 112, 0, 252, 116, 0, + 252, 116, 0, 252, 120, 0, 252, 120, 0, 252, 124, 0, + 252, 124, 0, 252, 128, 0, 252, 128, 0, 252, 132, 0, + 252, 132, 0, 252, 136, 0, 252, 136, 0, 252, 140, 0, + 252, 140, 0, 252, 144, 0, 252, 144, 0, 252, 148, 0, + 252, 152, 0, 252, 152, 0, 252, 156, 0, 252, 156, 0, + 252, 160, 0, 252, 160, 0, 252, 164, 0, 252, 164, 0, + 252, 168, 0, 252, 168, 0, 252, 172, 0, 252, 172, 0, + 252, 176, 0, 252, 176, 0, 252, 180, 0, 252, 180, 0, + 252, 184, 0, 252, 184, 0, 252, 188, 0, 252, 188, 0, + 252, 192, 0, 252, 192, 0, 252, 196, 0, 252, 196, 0, + 252, 200, 0, 252, 200, 0, 252, 204, 0, 252, 208, 0, + 252, 208, 0, 252, 208, 0, 252, 208, 0, 252, 208, 0, + 252, 212, 0, 252, 212, 0, 252, 212, 0, 252, 212, 0, + 252, 216, 0, 252, 216, 0, 252, 216, 0, 252, 216, 0, + 252, 216, 0, 252, 220, 0, 252, 220, 0, 252, 220, 0, + 252, 220, 0, 252, 224, 0, 252, 224, 0, 252, 224, 0, + 252, 224, 0, 252, 228, 0, 252, 228, 0, 252, 228, 0, + 252, 228, 0, 252, 228, 0, 252, 232, 0, 252, 232, 0, + 252, 232, 0, 252, 232, 0, 252, 236, 0, 252, 236, 0, + 252, 236, 0, 252, 236, 0, 252, 240, 0, 252, 240, 0, + 252, 240, 0, 252, 240, 0, 252, 240, 0, 252, 244, 0, + 252, 244, 0, 252, 244, 0, 252, 244, 0, 252, 248, 0, + 252, 248, 0, 252, 248, 0, 252, 248, 0, 252, 252, 0, + 252, 252, 4, 252, 252, 8, 252, 252, 12, 252, 252, 16, + 252, 252, 20, 252, 252, 24, 252, 252, 28, 252, 252, 32, + 252, 252, 36, 252, 252, 40, 252, 252, 40, 252, 252, 44, + 252, 252, 48, 252, 252, 52, 252, 252, 56, 252, 252, 60, + 252, 252, 64, 252, 252, 68, 252, 252, 72, 252, 252, 76, + 252, 252, 80, 252, 252, 84, 252, 252, 84, 252, 252, 88, + 252, 252, 92, 252, 252, 96, 252, 252, 100, 252, 252, 104, + 252, 252, 108, 252, 252, 112, 252, 252, 116, 252, 252, 120, + 252, 252, 124, 252, 252, 124, 252, 252, 128, 252, 252, 132, + 252, 252, 136, 252, 252, 140, 252, 252, 144, 252, 252, 148, + 252, 252, 152, 252, 252, 156, 252, 252, 160, 252, 252, 164, + 252, 252, 168, 252, 252, 168, 252, 252, 172, 252, 252, 176, + 252, 252, 180, 252, 252, 184, 252, 252, 188, 252, 252, 192, + 252, 252, 196, 252, 252, 200, 252, 252, 204, 252, 252, 208, + 252, 252, 208, 252, 252, 212, 252, 252, 216, 252, 252, 220, + 252, 252, 224, 252, 252, 228, 252, 252, 232, 252, 252, 236, + 252, 252, 240, 252, 252, 244, 252, 252, 248, 252, 252, 252 +}; + + unsigned char *screen; + unsigned char *flamebuf_ptr; + unsigned char *flamebuf; + unsigned char temp; + unsigned short int i, j, skip; + unsigned char temp_byte; + + set_paletteX(fire_pal); + set_write_plane(ALL_PLANES); + flamebuf = new unsigned char[BUF_SIZE]; + skip = V_WIDTH; + + // Initialize the video buffer to 0's + memset(flamebuf, 0, BUF_SIZE); + + while (!kbhit()) { + // Transform current buffer + flamebuf_ptr = flamebuf; + i = (BUF_HEIGHT - 2); + while (i--) { + *flamebuf_ptr = (*(flamebuf_ptr + BUF_WIDTH) + + *(flamebuf_ptr + (BUF_WIDTH - 1)) + + *(flamebuf_ptr + (BUF_WIDTH + 1)) + + *(flamebuf_ptr + (BUF_WIDTH * 2))) >> 2; + + flamebuf_ptr += BUF_WIDTH; + temp = *flamebuf_ptr; + if (temp > 11) { + *flamebuf_ptr -= 12; + } else if (temp > 3) { + *flamebuf_ptr -= 4; + } else { + *flamebuf_ptr = 0; + } + flamebuf_ptr += (1 - BUF_WIDTH); + + j = (BUF_WIDTH - 2); + while (j--) { + *flamebuf_ptr = (*(flamebuf_ptr + BUF_WIDTH) + + *(flamebuf_ptr + (BUF_WIDTH - 1)) + + *(flamebuf_ptr + (BUF_WIDTH + 1)) + + *(flamebuf_ptr + (BUF_WIDTH * 2))) >> 2; + + flamebuf_ptr += BUF_WIDTH; + temp = *flamebuf_ptr; + if (temp > 11) { + *flamebuf_ptr -= 12; + } else if (temp > 3) { + *flamebuf_ptr -= 4; + } else { + *flamebuf_ptr = 0; + } + flamebuf_ptr += (1 - BUF_WIDTH); + } + + *flamebuf_ptr = (*(flamebuf_ptr + BUF_WIDTH) + + *(flamebuf_ptr + (BUF_WIDTH - 1)) + + *(flamebuf_ptr + (BUF_WIDTH * 2)) + + *(flamebuf_ptr + (BUF_WIDTH * 2) + + (BUF_WIDTH - 1))) >> 2; + + flamebuf_ptr += BUF_WIDTH; + temp = *flamebuf_ptr; + if (temp > 11) { + *flamebuf_ptr -= 12; + } else if (temp > 3) { + *flamebuf_ptr -= 4; + } else { + *flamebuf_ptr = 0; + } + flamebuf_ptr += (1 - BUF_WIDTH); + } + + // Set new bottom line with random white or black + temp = 0; + flamebuf_ptr = flamebuf + (BUF_WIDTH * (BUF_HEIGHT - 2)); + + j = BUF_WIDTH; + temp = 0; + while (j--) { + // We change the value 1/4 of the time + if ((rand() & 0x03) == 3) { + temp = (255 - temp); + } + + *(flamebuf_ptr + BUF_WIDTH) = temp; + *flamebuf_ptr++ = temp; + } + + // Write the buffer to the screen +// wait_for_retrace(); + screen = RowsX[40]; + flamebuf_ptr = flamebuf; + i = V_HEIGHT; + while (i--) { + j = V_WIDTH; + while (j--) { + temp_byte = *flamebuf_ptr++; + *screen = temp_byte; + screen += skip; + *screen = temp_byte; + screen += skip; + *screen = temp_byte; + screen += skip; + *screen++ = temp_byte; + screen -= REWIND; + } + screen += REWIND; + } + } + + getch(); + + delete flamebuf; +} + + +void +main(void) +{ + FILE *fp; + char ch; + unsigned char pal[768]; + COORD x1, y1, x2, y2; + Iangle theta1, theta2; + Fixed32 trigSin, trigCos; + blitbuf blit_image, sprite_image; + clock_t begin, end; + short int x, y, temp, done; + long i, time1, time2, time3, count, mtime; + BYTE *ptr1; + BYTE *ptr2; + + set320x240x256_X(); + clearX(0); + + getch(); + + temp = loadfontX("vga8x8.fnt"); + + if (temp) { + putstringX(0, 0, "Hello!", 2); + } else { + return; + } + + getch(); + +#if ROTATE_DEMO + get_BIOSpaletteX(pal, 0); + set_paletteX(pal, 0); + + clearX(0); + for (x=0; x < 320; x++) { + for (y=0; y < 240; y++) { + putpixelX(x, y, (x & 0xFF)); + } + } + + getch(); + + while (!kbhit()) { + wait_for_retrace(); + rot_palette(-1); + } + + getch(); +#endif + + load_blitbufPCX("spock.pcx", &blit_image); + scale_blitbuf(160, 100, &blit_image); + aligned_bitblitX(0, 0, &blit_image); + + getch(); + + clearX(0); + + getch(); + + scale_blitbuf(224, 140, &blit_image); + aligned_bitblitX(0, 0, &blit_image); + + getch(); + + greyscale_blitbuf(&blit_image); + grey_paletteX(); + aligned_bitblitX(0, 0, &blit_image); + + getch(); + + clearX(0); + + getch(); + + scale_blitbuf(160, 100, &blit_image); + aligned_bitblitX(0, 0, &blit_image); + + getch(); + + clear_blitbuf(&blit_image); + load_blitbufPCX("spock.pcx", &blit_image); + greyscale_blitbuf(&blit_image); + smooth64_paletteX(1, 0, 1); + aligned_bitblitX(0, 0, &blit_image); + + getch(); + + flip_vertical_blitbuf(&blit_image); + aligned_bitblitX(0, 0, &blit_image); + + getch(); + + clear_blitbuf(&blit_image); + load_blitbufPCX("spock.pcx", &blit_image); + aligned_bitblitX(0, 0, &blit_image); + + done = 0; + while (!done) { + ch = getch(); + switch (ch) { + case 'q': + case 'Q': + done = 1; + break; + + case '+': + brighten_paletteX(1, 1, 1); + break; + + case '-': + brighten_paletteX(-1, -1, -1); + break; + + case '<': + stretch_paletteX(11, 11, 11); + break; + + case '>': + stretch_paletteX(24, 24, 24); + break; + + case 'S': + case 's': + save_blitbufPCX("dump.pcx", &blit_image); + break; + + case 'L': + case 'l': + load_blitbufPCX("spock.pcx", &blit_image); + break; + + case 'R': + brighten_paletteX(1, 0, 0); + break; + + case 'G': + brighten_paletteX(0, 1, 0); + break; + + case 'B': + brighten_paletteX(0, 0, 1); + break; + + case 'r': + brighten_paletteX(-1, 0, 0); + break; + + case 'g': + brighten_paletteX(0, -1, 0); + break; + + case 'b': + brighten_paletteX(0, 0, -1); + break; + + } + } + + clearX(0); + srand(0); + grey_paletteX(); + + begin = clock(); + + for (i=0; i < 10000; i++) { + x1 = rand() % 320; + y1 = rand() % 200; + x2 = rand() % 320; + y2 = rand() % 200; + + lineX(x1, y1, x2, y2, (i & 0x3F)); + } + + end = clock(); + + time1 = (end - begin); + + begin = end; + + for (i=0; i < 10000; i++) { + x1 = rand() % 320; + y1 = rand() % 200; + x2 = rand() % 320; + y2 = rand() % 200; + + temp = ((x1 + x2 + y1 + y2) & 0x3F); + } + + end = clock(); + + time2 = (end - begin); + + getch(); + + for (i=0; i < 120; i++) { + filledboxX(i, i, (319-i), (239-i), (i & 0x3F)); + } + + getch(); + + load_blitbufPCX("buddha.pcx", &sprite_image); + transparent_bitblitX(100, 100, &sprite_image); + + getch(); + + clearX(0); + clear_blitbuf(&blit_image); + scale_blitbuf(152, 168, &sprite_image); + alloc_blitbuf(&blit_image, 152, 168); + + // 152x168 image + aligned_bitblitX(84, 36, &sprite_image); + getch(); + + initFixed32(); + + theta1=0; + count=0; + + begin = clock(); + + while (!kbhit()) { + ptr1 = sprite_image.image; + ptr2 = blit_image.image; + theta2 = theta1; + + y=168; + while (y--) { + CosSin(theta2, &trigCos, &trigSin); + scale_scanline(ptr1, ptr2, 152, 152, (trigCos >> 10) + 88); +#if 0 + memcpy(ptr2+152, ptr2, 152); + ptr1 += 304; + ptr2 += 304; + theta2 += 4; + y--; +#else + ptr1 += 152; + ptr2 += 152; + theta2 += 2; +#endif + } + + theta1 += 2; + + aligned_bitblitX(84, 36, &blit_image); + count++; + } + + end = clock(); + + getch(); + getch(); + + clear_blitbuf(&blit_image); + clear_blitbuf(&sprite_image); + +#if FIRE_DEMO + clearX(0); + fire_demo(); +#endif + +#if MONSTER_DEMO_ONE + mtime = monster_demo1(); +#endif + +#if MONSTER_DEMO_TWO + monster_demo2(); +#endif + + set80x25(); + +#if MATH_DEMO + Fixed32 c1, c2, c3, a1, a2, a3; + + c1 = INT_TO_FIXED(50); + c2 = INT_TO_FIXED(70); + c3 = INT_TO_FIXED(50 * 70); + + a1 = FixedMul(c1, c2); + a2 = FixedMulASM(c1, c2); + + printf("MUL C version = %d\n", FIXED_TO_INT(a1)); + printf("MUL ASM version = %d\n", FIXED_TO_INT(a2)); + + getch(); + + a1 = FixedDiv(c3, c1); + a2 = FixedDivASM(c3, c1); + + printf("DIV C version = %d\n", FIXED_TO_INT(a1)); + printf("DIV ASM version = %d\n", FIXED_TO_INT(a2)); + + getch(); +#endif + + temp = (time1 - time2); + printf("10000 lines took %4d ticks\n", time1); + printf("rand() overhead = %4d ticks\n", time2); + printf("Time in lineX = %4d ticks\n", temp); + printf("%d lines per second!\n\n", (10000 * 1000) / (55 * temp)); + + temp = (end-begin); + printf("Buddha = %4d blits\n", count); + printf(" = %4d per second\n", (count * 1000) / (55 * temp)); + printf("Buddha = %4d scanline stretches\n", (count * 168)); + printf(" = %4d per second!\n\n", (count * 168000) / (55 * temp)); + + printf("Monster took %d ticks for 99 frames\n", mtime); +} + diff --git a/16/w_modex/TEST.EXE b/16/w_modex/TEST.EXE new file mode 100644 index 0000000000000000000000000000000000000000..c130bf508a2d5eee3f6897fbb4b0fc3798a59aeb GIT binary patch literal 52264 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 literal 0 HcmV?d00001 diff --git a/16/w_modex/VGA8X8.FNT b/16/w_modex/VGA8X8.FNT new file mode 100644 index 0000000000000000000000000000000000000000..d2bcc3921b00d24c4e9ac5d63f053b8a9e05854a GIT binary patch literal 2048 zcmah}J!>RK5G~FyIB3>#*5-tiIl5r*f;>U9k;6-!DDhxHJ83LMYr!=wDc29Met;AI z2ZLZ?oD3Ttf?b5bpiP9dAXqk7X8d0DD83qIYO1>W)kjyCNTzi4*VR8aS1I+2ezxjU z=(;Xed$LzWyov}Sx*u#-C}WncXubdA~x|hDSS#v?O@icy|rRNkVVS6t4o+!(;0|g(Y7Kyxpt8osV zDlFXAur9um*gS6T=TYpwW+2YjmGMb=?VX&R2jA6eNyVh5T$y6x!IK97a2y26_{6&0 zS8U=Bub~@T)^M8e2;-!R_$Bj=&1SPHfE${oYZ^&y8{0O?d0P}kdoGjEwr!Y5cm2VA zxb8AH2fF^)ZUv{5cv7ey$jQ1!n22ZI1{d179H2bcZ70oh*L?>L z${U<8{Bxi4qy01Hd7N?89QJGrk8_6nxqAj)6Dq_`JwkBOHNTdB!k>d*W1JLB`1Vp9 zj;Aag`Z=F3NRIp>>j6*X8NB$ji zK>?7z>Jbml`3L(k$(gkyYtPUIdN+guRI+4hBoqQC{&vnK?waD4Hs|SPtj7*FFmq!w zN5`ptsE>u6)&+LTVK>OR9{VSm8*OkW4cxNNswyh4%kJ8tuMqcLdY@!>H15aaS0OIz zLtJv=lDiog>R@z2EU^v|c{kcXQIHfUN?GoTVpo<`_;_IE304>^xRHnB@h>N@C;y=s z=odRezM79UIZozJKjnbG+~|SH@1L}BHT$LXLsS@hD6c870SOcZ3oEIvMP?`CPpu!X z!QVe^UTDdSqZ#Xnsj8zo!{r7gZxP)|kHZ!Pu2d*UZNnVs(1nJmAk zJ$Jnf>(o;wP6#imr?)JJko`giE}?qe7Xon+oyI4U{c?RbtkaHB<+zX;7eS1#ABZx4 zzZqyf5OrL`y_ +#include +#include + +#include "xtypes.hpp" +#include "modex.hpp" +#include "xpal.hpp" +#include "xblitbuf.hpp" + +#define SEQU_ADDR 0x3C4 +#define GRACON_ADDR 0x3CE + + +void +clear_blitbuf(blitbuf *buf) +{ + buf->xsize = 0; + buf->ysize = 0; + + delete buf->image; +} + + +void +fill_blitbuf(BYTE color, blitbuf *buf) +{ + memset(buf->image, color, buf->xsize * buf->ysize); +} + + +void +alloc_blitbuf(blitbuf *buf, DIST xsize, DIST ysize) +{ + buf->xsize = xsize; + buf->ysize = ysize; + buf->image = new BYTE[xsize * ysize]; +} + + +void +lin_2_pln_blitbuf(blitbuf *buf) +{ + int i, j, size; + BYTE *oldbuf; + BYTE *newbuf; + BYTE *src_ptr; + BYTE *dest_ptr; + + oldbuf = buf->image; + + size = (buf->xsize * buf->ysize); + newbuf = new BYTE[size]; + size = (size >> 2); + + dest_ptr = newbuf; + + for (i=0; i < 4; i++) { + src_ptr = oldbuf + i; + + j=size; + while (j--) { + *dest_ptr++ = *src_ptr; + src_ptr += 4; + } + } + + buf->image = newbuf; + delete oldbuf; +} + + +void +pln_2_lin_blitbuf(blitbuf *buf) +{ + int i, j, size; + BYTE *oldbuf; + BYTE *newbuf; + BYTE *src_ptr; + BYTE *dest_ptr; + + oldbuf = buf->image; + + size = (buf->xsize * buf->ysize); + newbuf = new BYTE[size]; + size = (size >> 2); + + src_ptr = oldbuf; + for (i=0; i < 4; i++) { + dest_ptr = newbuf + i; + + j=size; + while (j--) { + *dest_ptr = *src_ptr++; + dest_ptr += 4; + } + } + + buf->image = newbuf; + delete oldbuf; +} + + +void +vanilla_bitblitX(COORD x, COORD y, blitbuf *buf) +{ + short int ysize, plane, i, j, loop, skip, rewind, len; + short int xsize[4]; + BYTE *base_vga; + BYTE *vga_ptr; + BYTE *buf_ptr; + + // Length of bitmap in each plane + plane = (x & 3); + i = buf->xsize + plane - 1; + xsize[0] = ((i--) >> 2); + xsize[1] = ((i--) >> 2); + xsize[2] = ((i--) >> 2); + xsize[3] = (i >> 2) + 1; + + for (i=plane; i < 3; i++) { + xsize[i]++; + } + + ysize = buf->ysize; + base_vga = RowsX[y] + (x >> 2) + activeStart; + write_plane = -1; + + for (loop = 0; loop < 4; loop++) { + len = xsize[plane]; + rewind = buf->xsize - (len << 2); + skip = widthBytes - len; + buf_ptr = buf->image + loop; + vga_ptr = base_vga; + + outpw(SEQU_ADDR, plane_mask[plane++]); + if (plane == 4) { + plane = 0; + base_vga++; + } + + i=ysize; + while (i--) { + j=len; + while (j--) { + *vga_ptr++ = *buf_ptr; + buf_ptr += 4; + } + + buf_ptr += rewind; + vga_ptr += skip; + } + } +} + + +void +vanilla_getblitX(COORD x, COORD y, blitbuf *buf) +{ + // Do nothing +} + + +void +aligned_bitblitX(COORD x, COORD y, blitbuf *buf) +{ + short int i, j, plane, skip, xsize, ysize; + BYTE *base_vga; + BYTE *vga_ptr; + BYTE *buf_ptr; + + xsize = (buf->xsize >> 2); + ysize = buf->ysize; + skip = widthBytes - xsize; + base_vga = RowsX[y] + (x >> 2) + activeStart; + + for (plane=0; plane < 4; plane++) { + buf_ptr = buf->image + plane; + vga_ptr = base_vga; + + outpw(SEQU_ADDR, plane_mask[plane]); + + i=ysize; + while (i--) { + j=xsize; + while (j--) { + *vga_ptr++ = *buf_ptr; + buf_ptr += 4; + } + vga_ptr += skip; + } + } + + write_plane = 3; +} + + +void +aligned_getblitX(COORD x, COORD y, blitbuf *buf) +{ + short int i, j, plane, skip, xsize, ysize; + BYTE *base_vga; + BYTE *vga_ptr; + BYTE *buf_ptr; + + xsize = (buf->xsize >> 2); + ysize = buf->ysize; + skip = widthBytes - xsize; + base_vga = RowsX[y] + (x >> 2) + activeStart; + + for (plane=0; plane < 4; plane++) { + buf_ptr = buf->image + plane; + vga_ptr = base_vga; + + outpw(GRACON_ADDR, read_mask[plane]); + + i=ysize; + while (i--) { + j=xsize; + while (j--) { + *buf_ptr = *vga_ptr++; + buf_ptr += 4; + } + vga_ptr += skip; + } + } + + read_plane = 3; +} + + +void +transparent_bitblitX(COORD x, COORD y, blitbuf *buf) +{ + short int i, j, plane, skip, xsize, ysize; + BYTE *base_vga; + BYTE *vga_ptr; + BYTE *buf_ptr; + + xsize = (buf->xsize >> 2); + ysize = buf->ysize; + skip = widthBytes - xsize; + base_vga = RowsX[y] + (x >> 2) + activeStart; + + for (plane=0; plane < 4; plane++) { + buf_ptr = buf->image + plane; + vga_ptr = base_vga; + + outpw(SEQU_ADDR, plane_mask[plane]); + + i=ysize; + while (i--) { + j=xsize; + while (j--) { + if (*buf_ptr) { + *vga_ptr = *buf_ptr; + } + vga_ptr++; + buf_ptr += 4; + } + vga_ptr += skip; + } + } + + write_plane = 3; +} + + +void +planar_bitblitX(COORD x, COORD y, blitbuf *buf) +{ + short int i, plane, xsize, ysize; + BYTE *base_vga; + BYTE *vga_ptr; + BYTE *buf_ptr; + + xsize = (buf->xsize >> 2); + ysize = buf->ysize; + base_vga = RowsX[y] + (x >> 2) + activeStart; + buf_ptr = buf->image; + + for (plane=0; plane < 4; plane++) { + vga_ptr = base_vga; + + outpw(SEQU_ADDR, plane_mask[plane]); + + i=ysize; + while (i--) { + memcpy(vga_ptr, buf_ptr, xsize); + vga_ptr += widthBytes; + buf_ptr += xsize; + } + } + + write_plane = 3; +} + + +void +planar_getblitX(COORD x, COORD y, blitbuf *buf) +{ + short int i, plane, xsize, ysize; + BYTE *base_vga; + BYTE *vga_ptr; + BYTE *buf_ptr; + + xsize = (buf->xsize >> 2); + ysize = buf->ysize; + base_vga = RowsX[y] + (x >> 2) + activeStart; + buf_ptr = buf->image; + + for (plane=0; plane < 4; plane++) { + vga_ptr = base_vga; + + outpw(GRACON_ADDR, read_mask[plane]); + + i=ysize; + while (i--) { + memcpy(buf_ptr, vga_ptr, xsize); + vga_ptr += widthBytes; + buf_ptr += xsize; + } + } + + read_plane = 3; +} + + +void +wide_bitblitX(COORD y, blitbuf *buf) +{ + short int bufsize; + BYTE *vga_ptr; + BYTE *buf_ptr; + + write_plane = 3; + buf_ptr = buf->image; + vga_ptr = RowsX[y] + activeStart; + bufsize = (buf->ysize * widthBytes); + + outpw(SEQU_ADDR, PLANE_0); + memcpy(vga_ptr, buf_ptr, bufsize); + buf_ptr += bufsize; + + outpw(SEQU_ADDR, PLANE_1); + memcpy(vga_ptr, buf_ptr, bufsize); + buf_ptr += bufsize; + + outpw(SEQU_ADDR, PLANE_2); + memcpy(vga_ptr, buf_ptr, bufsize); + buf_ptr += bufsize; + + outpw(SEQU_ADDR, PLANE_3); + memcpy(vga_ptr, buf_ptr, bufsize); +} + + +void +wide_getblitX(COORD y, blitbuf *buf) +{ + short int bufsize; + BYTE *vga_ptr; + BYTE *buf_ptr; + + read_plane = 3; + buf_ptr = buf->image; + vga_ptr = RowsX[y] + activeStart; + bufsize = (buf->ysize * widthBytes); + + outpw(GRACON_ADDR, READ_PLANE_0); + memcpy(buf_ptr, vga_ptr, bufsize); + buf_ptr += bufsize; + + outpw(GRACON_ADDR, READ_PLANE_1); + memcpy(buf_ptr, vga_ptr, bufsize); + buf_ptr += bufsize; + + outpw(GRACON_ADDR, READ_PLANE_2); + memcpy(buf_ptr, vga_ptr, bufsize); + buf_ptr += bufsize; + + outpw(GRACON_ADDR, READ_PLANE_3); + memcpy(buf_ptr, vga_ptr, bufsize); +} + + +void +save_blitbufPCX(char *fname, blitbuf *buf) +{ + FILE *fp; + unsigned int i, size, temp_int; + BYTE VGA_pal[768]; + BYTE *buf_ptr; + BYTE temp_char, match, count; + + fp = fopen(fname, "wb"); + + if (fp != NULL) { + // Write manufacturer's byte + temp_char = 10; + fwrite(&temp_char, 1, 1, fp); + + // Write version of PCX. 5 = 256 color (PCX Version 5.0) + temp_char = 5; + fwrite(&temp_char, 1, 1, fp); + + // Write encoding type, always 1 for RLE. + temp_char = 1; + fwrite(&temp_char, 1, 1, fp); + + // Write bits_per_pixel = 8. + temp_char = 8; + fwrite(&temp_char, 1, 1, fp); + + // Write starting X and Y coords + temp_int = 0; + fwrite(&temp_int, 2, 1, fp); + fwrite(&temp_int, 2, 1, fp); + + // Write X size + temp_int = (buf->xsize - 1); + fwrite(&temp_int, 2, 1, fp); + + // Write Y size + temp_int = (buf->ysize - 1); + fwrite(&temp_int, 2, 1, fp); + + // Do HRES and VRES ** + temp_int = buf->xsize; + fwrite(&temp_int, 2, 1, fp); + temp_int = buf->ysize; + fwrite(&temp_int, 2, 1, fp); + + // Write 16 color palette, not used. + temp_int = 0; + i=24; + while (i--) { + fwrite(&temp_int, 2, 1, fp); + } + + // Write vmode byte. + temp_char = 0; + fwrite(&temp_char, 1, 1, fp); + + // Write bit_planes + temp_char = 1; + fwrite(&temp_char, 1, 1, fp); + + // Write bytes_per_line + temp_int = buf->xsize; + fwrite(&temp_int, 2, 1, fp); + + // Write palette type + temp_int = 1; + fwrite(&temp_int, 2, 1, fp); + + // Write junk filler + temp_int = 0; + i=29; + while (i--) { + fwrite(&temp_int, 2, 1, fp); + } + + // Write the actual image + buf_ptr = buf->image; + size = (buf->xsize * buf->ysize); + + count = 0; + match = *buf_ptr; + + i=size; + while (i--) { + temp_char = *buf_ptr++; + + if ((temp_char == match) && (count < 63)) { + count++; + } else { + if ((count == 1) && (match < 192)) { + // Write single byte + fwrite(&match,1,1,fp); + } else { + // Write run of pixels + count += 192; + fwrite(&count, 1, 1, fp); + fwrite(&match, 1, 1, fp); + } + count = 1; + match = temp_char; + } + } + + if ((count == 1) && (match < 192)) { + // Write single byte + fwrite(&match,1,1,fp); + } else { + // Write run of pixels + count += 192; + fwrite(&count, 1, 1, fp); + fwrite(&match, 1, 1, fp); + } + + // Write palette verification byte + temp_char = 12; + fwrite(&temp_char, 1, 1, fp); + + get_paletteX(VGA_pal); + + // Write 256 color palette + fwrite(VGA_pal, 1, 768, fp); + + fclose(fp); + } +} + + +int +load_blitbufPCX(char *fname, blitbuf *buf) +{ + FILE *fp; + int size; + BYTE VGA_pal[768]; + BYTE PCX_byte, RLE_byte; + BYTE *buf_ptr; + BYTE *end_of_buf; + + fp = fopen(fname, "rb"); + + if (fp == NULL) { + buf->xsize = 0; + buf->ysize = 0; + buf->image = NULL; + return 0; + } else { + fseek(fp, 8, SEEK_SET); + fread(&buf->xsize, 2, 1, fp); + fread(&buf->ysize, 2, 1, fp); + + buf->xsize++; + buf->ysize++; + + size = (buf->xsize * buf->ysize); + + buf->image = new BYTE[size]; + buf_ptr = buf->image; + end_of_buf = buf_ptr + size; + + // Load 256 color PCX palette + fseek(fp, -768, SEEK_END); + fread(VGA_pal, 1, 768, fp); + + set_paletteX(VGA_pal); + + fseek(fp, 128, SEEK_SET); + + while (buf_ptr < end_of_buf) { + // Read next packet + fread(&PCX_byte, 1, 1, fp); + + if (PCX_byte < 192) { + // Raw Pixel + *buf_ptr++ = PCX_byte; + } else { + // RLE Pixels + PCX_byte = PCX_byte & 0x3F; + fread(&RLE_byte, 1, 1, fp); + memset(buf_ptr, RLE_byte, PCX_byte); + buf_ptr += PCX_byte; + } + } + + fclose(fp); + return 1; + } +} + + +void +scale_blitbuf(DIST dest_x, DIST dest_y, blitbuf *buf1, blitbuf *buf2) +{ + unsigned long ErrorAccX, ErrorAccY, ErrorAdjX, ErrorAdjY; + DIST oldx, oldy, newx, newy; + short int i, j, count; + BYTE *src_base; + BYTE *src_ptr; + BYTE *dest_ptr; + BYTE *newbuf; + + oldx = buf1->xsize; + oldy = buf1->ysize; + newx = dest_x; + newy = dest_y; + + newbuf = new BYTE[newx * newy]; + + src_base = buf1->image; + dest_ptr = newbuf; + + // My bitmap scaling routine. As you probably noticed, it's + // pretty Bresenhammy! + + ErrorAccY = 0x8000; + + if (newx > oldx) { + // Biggering + ErrorAdjX = ((((unsigned long)newx) << 16) / + (((unsigned long)oldx))); + + ErrorAdjY = ((((unsigned long)newy) << 16) / + (((unsigned long)oldy))); + + i=oldy; + while (i--) { + ErrorAccX = 0x8000; + src_ptr = src_base; + + j=oldx; + while (j--) { + ErrorAccX += ErrorAdjX; + if (count = (ErrorAccX >> 16)) { + ErrorAccX &= 0xFFFFL; + while (count--) { + *dest_ptr++ = *src_ptr; + } + } + src_ptr++; + } + + ErrorAccY += ErrorAdjY; + count = (ErrorAccY >> 16) - 1; + while (count--) { + memcpy(dest_ptr, dest_ptr - newx, newx); + dest_ptr += newx; + } + ErrorAccY &= 0xFFFFL; + src_base += oldx; + } + } else { + // Smallering + ErrorAdjX = ((((unsigned long)oldx) << 16) / + (((unsigned long)newx))); + + ErrorAdjY = ((((unsigned long)oldy) << 16) / + (((unsigned long)newy))); + + i=newy; + while (i--) { + ErrorAccX = 0x8000; + src_ptr = src_base; + + j=newx; + while (j--) { + *dest_ptr++ = *src_ptr; + ErrorAccX += ErrorAdjX; + src_ptr += (ErrorAccX >> 16); + ErrorAccX &= 0xFFFFL; + } + + ErrorAccY += ErrorAdjY; + src_base += (oldx * (ErrorAccY >> 16)); + ErrorAccY &= 0xFFFFL; + } + } + + if (buf2 == NULL) { + delete buf1->image; + buf1->xsize = newx; + buf1->ysize = newy; + buf1->image = newbuf; + } else { + if (buf2->image != NULL) { + delete buf2->image; + } + buf2->xsize = newx; + buf2->ysize = newy; + buf2->image = newbuf; + } +} + + +void +vertical_scale_blitbuf(DIST dest_y, blitbuf *buf1, blitbuf *buf2) +{ + unsigned long ErrorAccY, ErrorAdjY; + DIST xsize, oldy, newy; + short int i, count; + BYTE *src_ptr; + BYTE *dest_ptr; + BYTE *newbuf; + + xsize = buf1->xsize; + oldy = buf1->ysize; + newy = dest_y; + + newbuf = new BYTE[xsize * newy]; + + src_ptr = buf1->image; + dest_ptr = newbuf; + + // My bitmap scaling routine. As you probably noticed, it's + // pretty Bresenhammy! + + ErrorAccY = 0x8000; + ErrorAdjY = ((((unsigned long)newy) << 16) / + (((unsigned long)oldy))); + + if (newy >= oldy) { + // Biggering + i=oldy; + while (i--) { + ErrorAccY += ErrorAdjY; + if (count = (ErrorAccY >> 16)) { + ErrorAccY &= 0xFFFFL; + + while (count--) { + memcpy(dest_ptr, src_ptr, xsize); + dest_ptr += xsize; + } + } + + src_ptr += xsize; + } + } else { + // Smallering + i=oldy; + while (i--) { + ErrorAccY += ErrorAdjY; + if (ErrorAccY & ~0xFFFFL) { + ErrorAccY &= 0xFFFFL; + memcpy(dest_ptr, src_ptr, xsize); + dest_ptr += xsize; + } + + src_ptr += xsize; + } + } + + if (buf2 == NULL) { + delete buf1->image; + buf1->ysize = newy; + buf1->image = newbuf; + } else { + if (buf2->image != NULL) { + delete buf2->image; + } + buf2->xsize = xsize; + buf2->ysize = newy; + buf2->image = newbuf; + } +} + + +void +greyscale_blitbuf(blitbuf *buf) +{ + BYTE temp_pal[768]; + BYTE *buf_ptr; + BYTE *temp; + BYTE r, g; + unsigned int i; + + buf_ptr = buf->image; + + get_paletteX(temp_pal, 0); + + for (i = (buf->xsize * buf->ysize); i; i--) { + temp = temp_pal + ((*buf_ptr) * 3); + r = *temp++; + g = *temp++; + + *buf_ptr++ = ((r * 19) + (g * 37) + (*temp << 3)) >> 6; + } +} + + +void +RGB_blitbuf(blitbuf *buf) +{ + BYTE temp_pal[768]; + BYTE *buf_ptr; + BYTE *temp; + BYTE r, g, b; + unsigned int i; + + buf_ptr = buf->image; + + get_paletteX(temp_pal, 0); + + for (i = (buf->xsize * buf->ysize); i; i--) { + temp = temp_pal + ((*buf_ptr) * 3); + r = (*temp) + 4; + temp++; + g = (*temp) + 4; + temp++; + b = (*temp) + 8; + + *buf_ptr++ = ((r >> 3) << 5) + ((g >> 3) << 2) + (b >> 4); + } +} + + +void +flip_vertical_blitbuf(blitbuf *buf) +{ + BYTE *top; + BYTE *bottom; + BYTE *temp; + DIST i, x, y;; + + x = buf->xsize; + y = buf->ysize; + + temp = new BYTE[x]; + + top = buf->image; + bottom = buf->image + (x * (y-1)); + + i = (y >> 1); + while (i--) { + memcpy(temp, top, x); + memcpy(top, bottom, x); + memcpy(bottom, temp, x); + top += x; + bottom -= x; + } + + delete temp; +} + + +void +flip_horizontal_blitbuf(blitbuf *buf) +{ + BYTE *buf_ptr; + BYTE *temp_ptr; + BYTE *temp; + DIST i, j, x; + + x = buf->xsize; + + temp = new BYTE[x]; + + buf_ptr = buf->image; + + i = buf->ysize; + while (i--) { + memcpy(temp, buf_ptr, x); + temp_ptr = temp + (x - 1); + j=x; + while (j--) { + *buf_ptr++ = *temp_ptr--; + } + } + + delete temp; +} + + +void +brighten_blitbuf(SBYTE factor, blitbuf *buf) +{ + BYTE *buf_ptr; + short int scratch; + unsigned int i; + + buf_ptr = buf->image; + + for (i = (buf->xsize * buf->ysize); i; i--) { + scratch = (*buf_ptr + factor); + if (scratch <= 0) { + *buf_ptr++ = 0; + } else if (scratch >= 63) { + *buf_ptr++ = 63; + } else { + *buf_ptr++ = scratch; + } + } +} + + +void +stretch_blitbuf(BYTE factor, blitbuf *buf) +{ + BYTE *buf_ptr; + short int scratch; + unsigned int i; + + buf_ptr = buf->image; + + for (i = (buf->xsize * buf->ysize); i; i--) { + scratch = ((((*buf_ptr - 32) * factor) + 8) >> 4) + 32; + if (scratch <= 0) { + *buf_ptr++ = 0; + } else if (scratch >= 63) { + *buf_ptr++ = 63; + } else { + *buf_ptr++ = scratch; + } + } +} + + +void +pixelize(DIST pixfactor, blitbuf *buf) +{ + // Do nothing +} + + +void +GREYconvolve_blitbuf(BYTE *kernel, blitbuf *buf) +{ + // Do nothing +} + + +void +RGBconvolve_blitbuf(BYTE *kernel, blitbuf *buf) +{ + // Do nothing +} + + +void +scale_scanline(BYTE *source, BYTE *dest, DIST smap_size, DIST dmap_size, + DIST dline_size) +{ + unsigned long ErrorAcc, ErrorAdj; + short int i, temp, invert; + + ErrorAcc = 0x8000; + + // Prepare for backwards scanlines + if (dline_size >= 0) { + invert = 0; + } else { + invert = 1; + dline_size = -dline_size; + } + + if (dline_size > smap_size) { + // Biggering + if (smap_size == 0) { + return; + } + ErrorAdj = ((((unsigned long)dline_size) << 16) / + (((unsigned long)smap_size))); + + i=smap_size; + while (i--) { + ErrorAcc += ErrorAdj; + temp = (ErrorAcc >> 16); + ErrorAcc &= 0xFFFFL; + while (temp--) { + *dest++ = *source; + } + source++; + } + } else { + // Smallering + if (dline_size == 0) { + memset(dest, 0, dmap_size); + } else { + temp = dmap_size - dline_size; + i = temp >> 1; + temp -= i; + while (i--) { + *dest++ = 0; + } + + ErrorAdj = ((((unsigned long)smap_size) << 16) / + (((unsigned long)dline_size))); + + i=dline_size; + + while (i--) { + *dest++ = *source; + ErrorAcc += ErrorAdj; + source += (ErrorAcc >> 16); + ErrorAcc &= 0xFFFFL; + } + + while (temp--) { + *dest++ = 0; + } + } + } +} + + +int +load_blitbufRAW(char *rawname, char *palname, blitbuf *buf) +{ + FILE *fp; + BYTE VGA_pal[768]; + + fp = fopen(rawname, "rb"); + + if (fp == NULL) { + buf->xsize = 0; + buf->ysize = 0; + buf->image = NULL; + return 0; + } else { + buf->xsize = 320; + buf->ysize = 200; + buf->image = new BYTE[64000L]; + + // Load image + fread(buf->image, 64000L, 1, fp); + + if (palname == NULL) { + fread(VGA_pal, 1, 768, fp); + set_paletteX(VGA_pal); + fclose(fp); + } else { + fclose(fp); + fp = fopen(palname, "rb"); + if (fp != NULL) { + fread(VGA_pal, 1, 768, fp); + set_paletteX(VGA_pal); + fclose(fp); + } + } + + return 1; + } +} + diff --git a/16/w_modex/XBLITBUF.HPP b/16/w_modex/XBLITBUF.HPP new file mode 100644 index 00000000..9907c5f3 --- /dev/null +++ b/16/w_modex/XBLITBUF.HPP @@ -0,0 +1,58 @@ +#ifndef X_BLITBUF_HPP + #define X_BLITBUF_HPP + +// Basic BlitBuf functions +void clear_blitbuf(blitbuf *buf); +void fill_blitbuf(BYTE color, blitbuf *buf); +void alloc_blitbuf(blitbuf *buf, DIST xsize, DIST ysize); +void lin_2_pln_blitbuf(blitbuf *buf); +void pln_2_lin_blitbuf(blitbuf *buf); + +// Adjust color in blitbuf +void greyscale_blitbuf(blitbuf *buf); +void RGB_blitbuf(blitbuf *buf); +void brighten_blitbuf(SBYTE factor, blitbuf *buf); +void stretch_blitbuf(BYTE factor, blitbuf *buf); // factor = 1/16 units + +// Image processing: These expect a linear blitbuf +void scale_blitbuf(DIST dest_x, DIST dest_y, + blitbuf *buf1, blitbuf *buf2 = NULL); +void vertical_scale_blitbuf(DIST dest_y, blitbuf *buf1, blitbuf *buf2 = NULL); +void flip_vertical_blitbuf(blitbuf *buf); +void flip_horizontal_blitbuf(blitbuf *buf); +void pixelize(DIST pixfactor, blitbuf *buf); // Not written yet +void scale_scanline(BYTE *source, BYTE *dest, DIST smap_size, + DIST dmap_size, DIST dline_size); + +// Image Convolution by a 3x3 kernel (linear) +void GREYconvolve_blitbuf(BYTE *kernel, blitbuf *buf); // Not written yet +void RGBconvolve_blitbuf(BYTE *kernel, blitbuf *buf); // Not written yet + +// Vanilla blits can be any size, anywhere +void vanilla_bitblitX(COORD x, COORD y, blitbuf *buf); +void vanilla_getblitX(COORD x, COORD y, blitbuf *buf); + +// Transparent blits must be aligned and 0 is the "transparent" value +void transparent_bitblitX(COORD x, COORD y, blitbuf *buf); + +// Aligned blits must have X and XSIZE evenly divisible by 4 +void aligned_bitblitX(COORD x, COORD y, blitbuf *buf); +void aligned_getblitX(COORD x, COORD y, blitbuf *buf); + +// Planar blits must be aligned and also be ordered in 4-planar fashion +void planar_bitblitX(COORD x, COORD y, blitbuf *buf); +void planar_getblitX(COORD x, COORD y, blitbuf *buf); + +// Wide blits must be planar and are assumed to be as wide as the screen +void wide_bitblitX(COORD y, blitbuf *buf); +void wide_getblitX(COORD y, blitbuf *buf); + +// PCX functions +void save_blitbufPCX(char *fname, blitbuf *buf); +int load_blitbufPCX(char *fname, blitbuf *buf); + +// RAW file functions (320x200 only) +int load_blitbufRAW(char *rawname, char *palname, blitbuf *buf); + +#endif + diff --git a/16/w_modex/XPAL.CPP b/16/w_modex/XPAL.CPP new file mode 100644 index 00000000..b052855f --- /dev/null +++ b/16/w_modex/XPAL.CPP @@ -0,0 +1,265 @@ +#include +#include +#include + +#include "modex.hpp" +#include "xpal.hpp" + +BYTE Xpal[768]; + +void +set_paletteX(BYTE *pal, FLAG downgrade) +{ + short int i; + BYTE *buf; + + memcpy(Xpal, pal, 768); + + buf = Xpal; + if (downgrade) { + i=768; + while (i--) { + *buf++ = (*buf >> 2); + } + } + + outp(0x03c8, 0); // Start with color 0 + buf = Xpal; + i=256; + while (i--) { + outp(0x03c9, *buf++); + outp(0x03c9, *buf++); + outp(0x03c9, *buf++); + } +} + + +void +get_paletteX(BYTE *pal, FLAG upgrade) +{ + int i; + + memcpy(pal, Xpal, 768); + + if (upgrade) { + i=768; + while (i--) { + *pal++ = (*pal << 2); + } + } +} + + +void +get_BIOSpaletteX(BYTE *pal, FLAG upgrade) +{ + int i; + union REGS r; + + r.x.eax = 0x1017; + r.x.ebx = 0; + r.x.ecx = 256; + r.x.edx = (unsigned long) pal; + + int386(0x10, &r, &r); + + if (upgrade) { + i=768; + while (i--) { + *pal++ = (*pal << 2); + } + } +} + + +void +photo_negativeX(void) +{ + short int i; + BYTE temp_pal[768]; + BYTE *temp; + + get_paletteX(temp_pal, 0); + temp = temp_pal; + + for (i=0; i < 256; i++) { + *temp++ = (64 - (*temp)); + *temp++ = (64 - (*temp)); + *temp++ = (64 - (*temp)); + } + + set_paletteX(temp_pal, 0); +} + + +void +grey_paletteX(void) +{ + smooth64_paletteX(1, 1, 1); +} + + +void +RGB_paletteX(void) +{ + BYTE r, g, b; + BYTE temp_pal[768]; + BYTE *temp; + + temp = temp_pal; + + for (r=0; r < 8; r++) { + for (g=0; g < 8; g++) { + for (b=0; b < 4; b++) { + *temp++ = (r << 3); + *temp++ = (g << 3); + *temp++ = (b << 4); + } + } + } + + set_paletteX(temp_pal, 0); +} + + +void +smooth64_paletteX(BYTE r, BYTE g, BYTE b) +{ + short int i; + BYTE temp_pal[768]; + BYTE *temp; + + memset(temp_pal, 0, 768); + + + if (r) { + temp = temp_pal; + for (i=0; i < 64; i++) { + *temp = i; + temp += 3; + } + } + + if (g) { + temp = temp_pal + 1; + for (i=0; i < 64; i++) { + *temp = i; + temp += 3; + } + } + + if (b) { + temp = temp_pal + 2; + for (i=0; i < 64; i++) { + *temp = i; + temp += 3; + } + } + + set_paletteX(temp_pal, 0); +} + + +void +brighten_paletteX(SBYTE r, SBYTE g, SBYTE b) +{ + short int i, j, scratch; + BYTE temp_pal[768]; + BYTE *temp; + SBYTE dummy[3]; + + get_paletteX(temp_pal, 0); + temp = temp_pal; + + dummy[0] = r; + dummy[1] = g; + dummy[2] = b; + + for (i=0; i < 256; i++) { + for (j=0; j < 3; j++) { + scratch = *temp + dummy[j]; + if (scratch <= 0) { + *temp++ = 0; + } else if (scratch >= 63) { + *temp++ = 63; + } else { + *temp++ = scratch; + } + } + } + + set_paletteX(temp_pal, 0); +} + + +void +stretch_paletteX(BYTE r, BYTE g, BYTE b) +{ + short int i, j, scratch; + BYTE temp_pal[768]; + BYTE *temp; + BYTE dummy[3]; + + get_paletteX(temp_pal, 0); + temp = temp_pal; + + dummy[0] = r; + dummy[1] = g; + dummy[2] = b; + + for (i=0; i < 256; i++) { + for (j=0; j < 3; j++) { + scratch = ((((*temp - 32) * dummy[j]) + 8) >> 4) + 32; + if (scratch <= 0) { + *temp++ = 0; + } else if (scratch >= 63) { + *temp++ = 63; + } else { + *temp++ = scratch; + } + } + } + + set_paletteX(temp_pal, 0); +} + + +void +rot_palette(BYTE dist) +{ + int shift, i; + BYTE temp_pal[768]; + + shift = (dist * 3); + memcpy(temp_pal, Xpal + shift, 768 - shift); + memcpy(temp_pal + (768 - shift), Xpal, shift); + + set_paletteX(temp_pal, 0); +} + + +BYTE +find_RGB(BYTE r, BYTE g, BYTE b) +{ + long shortest_dist, temp_dist; + short int i, shortest_pal; + + shortest_pal = 0; + shortest_dist = (r - Xpal[0]) * (r - Xpal[0]) + + (g - Xpal[1]) * (g - Xpal[1]) + + (b - Xpal[2]) * (b - Xpal[2]); + + for (i=1; i < 256; i++) { + temp_dist = (r - Xpal[(i * 3) + 0]) * (r - Xpal[(i * 3) + 0]) + + (g - Xpal[(i * 3) + 1]) * (g - Xpal[(i * 3) + 1]) + + (b - Xpal[(i * 3) + 2]) * (b - Xpal[(i * 3) + 2]); + + if (temp_dist < shortest_dist) { + shortest_dist = temp_dist; + shortest_pal = i; + } + } + + return i; +} + diff --git a/16/w_modex/XPAL.HPP b/16/w_modex/XPAL.HPP new file mode 100644 index 00000000..a04dd48c --- /dev/null +++ b/16/w_modex/XPAL.HPP @@ -0,0 +1,24 @@ +#ifndef X_PALETTE_HPP + #define X_PALETTE_HPP + +#include "xtypes.hpp" + +// Palette setting/getting functions +void set_paletteX(BYTE *pal, FLAG downgrade = 1); +void get_paletteX(BYTE *pal, FLAG upgrade = 1); +void get_BIOSpaletteX(BYTE *pal, FLAG upgrade = 1); + +// Palette adjusting functions +void photo_negativeX(void); +void grey_paletteX(void); +void RGB_paletteX(void); +void smooth64_paletteX(BYTE r, BYTE g, BYTE b); +void brighten_paletteX(SBYTE r, SBYTE g, SBYTE b); +void stretch_paletteX(BYTE r, BYTE g, BYTE b); // 1/16 units + +// Misc palette functions +void rot_palette(BYTE distance); +BYTE find_RGB(BYTE r, BYTE g, BYTE b); + +#endif + diff --git a/16/w_modex/XPRIM.CPP b/16/w_modex/XPRIM.CPP new file mode 100644 index 00000000..66e2f72a --- /dev/null +++ b/16/w_modex/XPRIM.CPP @@ -0,0 +1,561 @@ +#include +#include +#include +#include + +#include "modex.hpp" +#include "xprim.hpp" + +#define SEQU_ADDR 0x3C4 +#define GRACON_ADDR 0x3CE +#define CRTC_ADDR 0x3D4 +#define STATUS_ADDR 0x3DA + +BYTE Xfont[2048]; + + +void +wait_for_retrace(void) +{ + while (!(inp(STATUS_ADDR) & 0x08)); +} + + +void +setDrawPage(unsigned int page) +{ + activeStart = page_offset[page]; +} + + +void +setVisiblePage(unsigned int page) +{ + // setVisibleStart() tells the VGA from which byte to fetch the first + // pixel when starting refresh at the top of the screen. + visibleStart = page_offset[page]; + + // set high byte + outpw(CRTC_ADDR, page_mask_high[page]); + + // set low byte + outpw(CRTC_ADDR, page_mask_low[page]); +} + + +void +clearX(BYTE color) +{ + outpw(SEQU_ADDR, 0x0F02); + memset((unsigned char *)(0xA000 << 4) + activeStart, color, 0x00010000); +} + + +void +putpixelX(COORD x, COORD y, BYTE color) +{ + BYTE temp; + + if (write_plane != (temp = (x & 3))) { + write_plane = temp; + outpw(SEQU_ADDR, plane_mask[temp]); + } + + *(RowsX[y] + (x >> 2) + activeStart) = color; +} + + +BYTE +getpixelX(COORD x, COORD y) +{ + BYTE temp; + + if (read_plane != (temp = (x & 3))) { + read_plane = temp; + outpw(GRACON_ADDR, read_mask[temp]); + } + + return (*(RowsX[y] + (x >> 2) + activeStart)); +} + + +void +internal_vert_lineX(COORD x, COORD top_y, int len, BYTE color) +{ + BYTE *ptr; + BYTE temp; + + if (write_plane != (temp = (x & 3))) { + write_plane = temp; + outpw(SEQU_ADDR, plane_mask[temp]); + } + + ptr = RowsX[top_y] + (x >> 2) + activeStart; + + while (len--) { + *ptr = color; + ptr += widthBytes; + } +} + + +void +internal_horiz_lineX(COORD left_x, COORD y, int len, BYTE color) +{ + BYTE *ptr; + BYTE temp; + + ptr = RowsX[y] + (left_x >> 2) + activeStart; + + // Set current plane to invalid value + write_plane = -1; + + if (temp = (left_x & 3)) { + outp(SEQU_ADDR, 0x02); + outp(0x3C5, line_head[temp]); + *ptr++ = color; + len -= (4 - temp); + } + + if (temp = (len >> 2)) { + outpw(SEQU_ADDR, 0x0F02); + + len &= 3; + + memset(ptr, color, temp); + ptr += temp; + } + + if (len) { + outp(SEQU_ADDR, 0x02); + outp(0x3C5, line_tail[len]); + *ptr = color; + } +} + + +void +boxX(COORD x1, COORD y1, COORD x2, COORD y2, BYTE color) +{ + int xsize, ysize; + + xsize = (x2 - x1) + 1; + internal_horiz_lineX(x1, y1, xsize, color); + internal_horiz_lineX(x1, y2, xsize, color); + + y1++; + ysize = (y2 - y1); + + internal_vert_lineX(x1, y1, ysize, color); + internal_vert_lineX(x2, y1, ysize, color); +} + + +void +filledboxX(COORD x1, COORD y1, COORD x2, COORD y2, BYTE color) +{ + BYTE *base_ptr; + BYTE *ptr; + BYTE temp; + short int i, xsize, ysize; + + // Set current plane to invalid value + write_plane = -1; + + xsize = (x2 - x1) + 1; + ysize = (y2 - y1) + 1; + + if (ysize == 1) { + internal_horiz_lineX(x1, y1, xsize, color); + return; + } + + base_ptr = RowsX[y1] + (x1 >> 2) + activeStart; + + if (temp = (x1 & 3)) { + outp(SEQU_ADDR, 0x02); + outp(0x3C5, line_head[temp]); + ptr = base_ptr; + i=ysize; + while (i--) { + *ptr = color; + ptr += widthBytes; + } + xsize -= (4 - temp); + base_ptr++; + } + + if (temp = (xsize >> 2)) { + outpw(SEQU_ADDR, 0x0F02); + + xsize &= 3; + ptr = base_ptr; + i=ysize; + while (i--) { + memset(ptr, color, temp); + ptr += widthBytes; + } + base_ptr += temp; + } + + if (xsize) { + outp(SEQU_ADDR, 0x02); + outp(0x3C5, line_tail[xsize]); + while (ysize--) { + *base_ptr = color; + base_ptr += widthBytes; + } + } +} + + +void +circleX(COORD x, COORD y, DIST r, BYTE color) +{ + int ix, iy, d, deltaE, deltaSE; + + ix = 0; + iy = r; + d = 1 - r; + deltaE = 3; + deltaSE = (-2 * r) + 5; + + putpixelX(x + ix, y + iy, color); + putpixelX(x + ix, y - iy, color); + putpixelX(x + iy, y + ix, color); + putpixelX(x + iy, y - ix, color); + putpixelX(x - ix, y + iy, color); + putpixelX(x - ix, y - iy, color); + putpixelX(x - iy, y + ix, color); + putpixelX(x - iy, y - ix, color); + + while (iy > ix++) { + if (d < 0) { + d += deltaE; + deltaE += 2; + deltaSE += 2; + } else { + d += deltaSE; + deltaE += 2; + deltaSE += 4; + iy--; + } + + putpixelX(x + ix, y + iy, color); + putpixelX(x + ix, y - iy, color); + putpixelX(x + iy, y + ix, color); + putpixelX(x + iy, y - ix, color); + putpixelX(x - ix, y + iy, color); + putpixelX(x - ix, y - iy, color); + putpixelX(x - iy, y + ix, color); + putpixelX(x - iy, y - ix, color); + } +} + + +void +filledcircleX(COORD x, COORD y, DIST r, BYTE color) +{ + int ix, iy, d, deltaE, deltaSE; + + ix = 0; + iy = r; + d = 1 - r; + deltaE = 3; + deltaSE = (-2 * r) + 5; + + internal_horiz_lineX(x - ix, y + iy, (ix << 1) + 1, color); + internal_horiz_lineX(x - ix, y - iy, (ix << 1) + 1, color); + internal_horiz_lineX(x - iy, y + ix, (iy << 1) + 1, color); + internal_horiz_lineX(x - iy, y - ix, (iy << 1) + 1, color); + + while (iy > ix++) { + if (d < 0) { + d += deltaE; + deltaE += 2; + deltaSE += 2; + } else { + d += deltaSE; + deltaE += 2; + deltaSE += 4; + iy--; + } + + internal_horiz_lineX(x - ix, y + iy, (ix << 1) + 1, color); + internal_horiz_lineX(x - ix, y - iy, (ix << 1) + 1, color); + internal_horiz_lineX(x - iy, y + ix, (iy << 1) + 1, color); + internal_horiz_lineX(x - iy, y - ix, (iy << 1) + 1, color); + } +} + + +void +internal_xmajor(BYTE *vga_ptr, short int len, short int yskip, + unsigned long ErrorAcc, unsigned long ErrorAdj, BYTE color) +{ + if (len) { + len--; + while (len--) { + *vga_ptr++ = color; + ErrorAcc += ErrorAdj; + + if (ErrorAcc & ~0xFFFFL) { + ErrorAcc &= 0xFFFFL; + vga_ptr += yskip; + } + } + *vga_ptr = color; + } +} + + +void +internal_middle(BYTE *vga_ptr, short int len, short int yskip, + unsigned long ErrorAcc, unsigned long ErrorAdj, BYTE color) +{ + if (len) { + len--; + while (len--) { + *vga_ptr++ = color; + ErrorAcc += ErrorAdj; + vga_ptr += (yskip * (ErrorAcc >> 16)); + ErrorAcc &= 0xFFFFL; + } + *vga_ptr = color; + } +} + + +void +internal_ymajor(BYTE *vga_ptr, short int len, short int yskip, + unsigned long ErrorAcc, unsigned long ErrorAdj, BYTE color) +{ + unsigned long TinyAdj; + short int i; + + if (len) { + TinyAdj = (ErrorAdj >> 2); + ErrorAdj -= TinyAdj; + + len--; + while (len--) { + ErrorAcc += TinyAdj; + i = (ErrorAcc >> 16); + ErrorAcc &= 0xFFFFL; + + while (i--) { + *vga_ptr = color; + vga_ptr += yskip; + } + + ErrorAcc += ErrorAdj; + vga_ptr += (yskip * (ErrorAcc >> 16)) + 1; + ErrorAcc &= 0xFFFFL; + } + ErrorAcc += TinyAdj; + i = (ErrorAcc >> 16); + while (i--) { + *vga_ptr = color; + vga_ptr += yskip; + } + } +} + + +void +lineX(COORD x1, COORD y1, COORD x2, COORD y2, BYTE color) +{ + unsigned long ErrorAcc, ErrorAdj, TinyAdj; + short int i, DeltaX, DeltaY, yskip; + short int len[4]; + BYTE *vga_ptr; + COORD temp; + + // Mode X 4-way folded Bresenham line function - by David Boeren + + // Set invalid plane, because we're screwing with the plane mask + write_plane = -1; + + // Make sure the line runs left to right + if (x1 > x2) { + temp = x1; x1 = x2; x2 = temp; + temp = y1; y1 = y2; y2 = temp; + } + + DeltaX = (x2 - x1); + DeltaY = (y2 - y1); + + if (DeltaY >= 0) { + yskip = widthBytes; + } else { + DeltaY = -DeltaY; // Make DeltaY positive + yskip = -widthBytes; + } + + if (DeltaX == 0) { + // Vertical Line (and one pixel lines) + if (yskip > 0) { + internal_vert_lineX(x1, y1, (DeltaY + 1), color); + } else { + internal_vert_lineX(x1, y2, (DeltaY + 1), color); + } + return; + } + + if (DeltaY == 0) { + // Horizontal Line + internal_horiz_lineX(x1, y1, (DeltaX + 1), color); + return; + } + + vga_ptr = RowsX[y1] + (x1 >> 2) + activeStart; + ErrorAcc = 0x8000; + + // Length of sub-line in each plane + temp = (x1 & 3); + i = DeltaX + temp; + len[0] = ((i--) >> 2); + len[1] = ((i--) >> 2); + len[2] = ((i--) >> 2); + len[3] = (i >> 2) + 1; + + for (i=temp; i < 3; i++) { + len[i]++; + } + + if ((DeltaX >> 2) >= DeltaY) { + // X-Major line (0.00 < slope <= 0.25) + ErrorAdj = ((((unsigned long)DeltaY << 18) / (unsigned long)DeltaX)); + TinyAdj = (ErrorAdj >> 2); + while (i--) { + outpw(SEQU_ADDR, plane_mask[temp]); + internal_xmajor(vga_ptr, len[temp++], yskip, ErrorAcc, ErrorAdj, color); + if (temp == 4) { + temp = 0; + vga_ptr++; + } + ErrorAcc += TinyAdj; + if (ErrorAcc & ~0xFFFFL) { + ErrorAcc &= 0xFFFFL; + vga_ptr += yskip; + } + } + outpw(SEQU_ADDR, plane_mask[temp]); + internal_xmajor(vga_ptr, len[temp], yskip, ErrorAcc, ErrorAdj, color); + } else if (DeltaX >= DeltaY) { + // Middle line (0.25 < slope <= 1.00) + ErrorAdj = ((((unsigned long)DeltaY << 18) / (unsigned long)DeltaX)); + TinyAdj = (ErrorAdj >> 2); + while (i--) { + outpw(SEQU_ADDR, plane_mask[temp]); + internal_middle(vga_ptr, len[temp++], yskip, ErrorAcc, ErrorAdj, color); + if (temp == 4) { + temp = 0; + vga_ptr++; + } + ErrorAcc += TinyAdj; + if (ErrorAcc & ~0xFFFFL) { + vga_ptr += yskip; + ErrorAcc &= 0xFFFFL; + } + } + outpw(SEQU_ADDR, plane_mask[temp]); + internal_middle(vga_ptr, len[temp], yskip, ErrorAcc, ErrorAdj, color); + } else { + // Y-Major line (slope > 1) + ErrorAdj = ((((unsigned long)(DeltaY+1) << 18) / + (unsigned long)(DeltaX+1))); + TinyAdj = (ErrorAdj >> 2); + while (i--) { + outpw(SEQU_ADDR, plane_mask[temp]); + internal_ymajor(vga_ptr, len[temp++], yskip, ErrorAcc, ErrorAdj, color); + if (temp == 4) { + temp = 0; + vga_ptr++; + } + ErrorAcc += TinyAdj; + vga_ptr += (yskip * (ErrorAcc >> 16)); + ErrorAcc &= 0xFFFFL; + } + outpw(SEQU_ADDR, plane_mask[temp]); + internal_ymajor(vga_ptr, len[temp], yskip, ErrorAcc, ErrorAdj, color); + } +} + + +int +loadfontX(char *fname) +{ + FILE *fp; + + fp = fopen(fname, "rb"); + + if (fp == NULL) { + return 0; + } else { + fread(Xfont, 8, 256, fp); + fclose(fp); + return 1; + } +} + + +void +putchX(COORD x, COORD y, char c, BYTE color) +{ + int i; + BYTE *vga_ptr; + BYTE *font_ptr; + BYTE temp; + + // 8x8 font + vga_ptr = RowsX[y << 3] + (x << 1) + activeStart; + write_plane = -1; + + font_ptr = Xfont + (c << 3); + + i=8; + while (i--) { + temp = *font_ptr++; + outpw(SEQU_ADDR, text_mask[temp & 0x0F]); + *vga_ptr++ = color; + + outpw(SEQU_ADDR, text_mask[temp >> 4]); + *vga_ptr-- = color; + vga_ptr += widthBytes; + } +} + + +void +putstringX(COORD x, COORD y, char *str, BYTE color) +{ + int i, skip; + BYTE *vga_ptr; + BYTE *font_ptr; + BYTE c, temp; + + // 8x8 font + vga_ptr = RowsX[y << 3] + (x << 1) + activeStart; + write_plane = -1; + + skip = 2 - (widthBytes << 3); + + while (c = *str++) { + font_ptr = Xfont + (c << 3); + + i=8; + while (i--) { + temp = *font_ptr++; + outpw(SEQU_ADDR, text_mask[temp & 0x0F]); + *vga_ptr++ = color; + + outpw(SEQU_ADDR, text_mask[temp >> 4]); + *vga_ptr-- = color; + vga_ptr += widthBytes; + } + + vga_ptr += skip; + } +} + diff --git a/16/w_modex/XPRIM.HPP b/16/w_modex/XPRIM.HPP new file mode 100644 index 00000000..e9948369 --- /dev/null +++ b/16/w_modex/XPRIM.HPP @@ -0,0 +1,31 @@ +#ifndef X_PRIMITIVES_HPP + #define X_PRIMITIVES_HPP + +#include "xtypes.hpp" + +// Waits for vertical retrace +void wait_for_retrace(void); + +// Page setting functions +void setDrawPage(unsigned int page); +void setVisiblePage(unsigned int page); + +// Screen clearing functions +void clearX(BYTE color); + +// Drawing functions +void putpixelX(COORD x, COORD y, BYTE color); +BYTE getpixelX(COORD x, COORD y); +void boxX(COORD x1, COORD y1, COORD x2, COORD y2, BYTE color); +void filledboxX(COORD x1, COORD y1, COORD x2, COORD y2, BYTE color); +void circleX(COORD x, COORD y, DIST r, BYTE color); +void filledcircleX(COORD x, COORD y, DIST r, BYTE color); +void lineX(COORD lx1, COORD ly1, COORD lx2, COORD ly2, BYTE color); + +// Text output functions +int loadfontX(char *fname); +void putchX(COORD x, COORD y, char c, BYTE color); +void putstringX(COORD x, COORD y, char *str, BYTE color); + +#endif + diff --git a/16/w_modex/XTYPES.HPP b/16/w_modex/XTYPES.HPP new file mode 100644 index 00000000..1a0d8e69 --- /dev/null +++ b/16/w_modex/XTYPES.HPP @@ -0,0 +1,17 @@ +#ifndef XTYPES_HPP + #define XTYPES_HPP + +typedef unsigned char BYTE; +typedef signed char SBYTE; +typedef unsigned char FLAG; +typedef unsigned short COORD; +typedef unsigned short DIST; + +struct blitbuf { + DIST xsize; + DIST ysize; + BYTE *image; +}; + +#endif + -- 2.39.2