From: sparky4 <sparky4@cock.li> Date: Fri, 21 Apr 2017 13:46:23 +0000 (-0500) Subject: 16_ca needs huge amounts of work and I should remember what needs to be done soon... X-Git-Url: http://4ch.mooo.com/gitweb/?a=commitdiff_plain;h=7b204788231612250d286ca317dd942b78da91b6;p=16.git 16_ca needs huge amounts of work and I should remember what needs to be done soon[going to port rest of code to borland c some time so we can use the core components of id engine here ][going to add 16_us.c eventually but the debug system and CA_ PM_ and MM_ usage is priority now]older zcroll renamed to xcroll][zcroll is now the pre menu game loop system with PROPER data usage with CAMMPM] added 1st scroll back --- diff --git a/16/modex16/286@12.log b/16/modex16/286@12.log new file mode 100755 index 00000000..34027049 --- /dev/null +++ b/16/modex16/286@12.log @@ -0,0 +1,4 @@ +Old non-sprite: 7.032967 +New non-sprite: 1.043956 +Old Sprite: 6.648352 +New Sprite: 1.648352 diff --git a/16/modex16/286@8.log b/16/modex16/286@8.log new file mode 100755 index 00000000..a29ceffc --- /dev/null +++ b/16/modex16/286@8.log @@ -0,0 +1,4 @@ +Old non-sprite: 10.439561 +New non-sprite: 1.373626 +Old Sprite: 9.945055 +New Sprite: 2.362637 diff --git a/16/modex16/46113319.pcx b/16/modex16/46113319.pcx new file mode 100755 index 00000000..ce42ed87 Binary files /dev/null and b/16/modex16/46113319.pcx differ diff --git a/16/modex16/bitmap.c b/16/modex16/bitmap.c new file mode 100755 index 00000000..8287e57d --- /dev/null +++ b/16/modex16/bitmap.c @@ -0,0 +1,162 @@ +#include <stdio.h> +#include <stdlib.h> +#include "bitmap.h" +#include "modex16.h" + +static struct pcxHeader { + byte id; + byte version; + byte encoding; + byte bpp; + word xmin; + word ymin; + word xmax; + word ymax; + word hres; + word vres; + byte pal16[48]; + byte res1; + word bpplane; + word palType; + word hScreenSize; + word vScreenSize; + byte padding[54]; +} head; + + +static void loadPcxStage1(FILE *file, bitmap_t *result) { + long bufSize; + int index; + byte count, val; + long int pos; + + /* read the header */ + fread(&head, sizeof(char), sizeof(struct pcxHeader), file); + + /* get the width and height */ + result->width = head.xmax - head.xmin + 1; + result->height = head.ymax - head.ymin + 1; + + /* make sure this is 8bpp */ + if(head.bpp != 8) { + printf("I only know how to handle 8bpp pcx files!\n"); + fclose(file); + exit(-2); + } +} + + +static void loadPcxPalette(FILE *file, bitmap_t *result) { + byte val; + int index; + + /* handle the palette */ + fseek(file, -769, SEEK_END); + val = fgetc(file); + result->palette = modexNewPal(); + if(head.version == 5 && val == 12) { + /* use the vga palette */ + for(index=0; !feof(file) && index < PAL_SIZE; index++) { + val = fgetc(file); + result->palette[index] = val >> 2; + } + } else { + /* use the 16 color palette */ + for(index=0; index<48; index++) { + result->palette[index] = head.pal16[index]; + } + } +} + + +bitmap_t +bitmapLoadPcx(char *filename) { + FILE *file; + bitmap_t result; + long bufSize; + int index; + byte count, val; + + /* open the PCX file for reading */ + file = fopen(filename, "rb"); + if(!file) { + printf("Could not open %s for reading.\n", filename); + exit(-2); + } + + /* load the first part of the pcx file */ + loadPcxStage1(file, &result); + + /* allocate the buffer */ + bufSize = result.width * result.height; + result.data = malloc(bufSize); + if(!result.data) { + printf("Could not allocate memory for bitmap data."); + fclose(file); + exit(-1); + } + + /* read the buffer in */ + index = 0; + do { + /* get the run length and the value */ + count = fgetc(file); + if(0xC0 == (count & 0xC0)) { /* this is the run count */ + count &= 0x3f; + val = fgetc(file); + } else { + val = count; + count = 1; + } + + /* write the pixel the specified number of times */ + for(; count && index < bufSize; count--,index++) { + result.data[index] = val; + } + } while(index < bufSize); + + loadPcxPalette(file, &result); + + fclose(file); + + return result; +} + + +tileset_t +bitmapLoadPcxTiles(char *filename, word twidth, word theight) { + tileset_t ts; + FILE *file; + bitmap_t result; + int i; + + /* open the PCX file for reading */ + file = fopen(filename, "rb"); + if(!file) { + printf("Could not open %s for reading.\n", filename); + exit(-2); + } + + /* load the first part of the pcx file */ + loadPcxStage1(file, &result); + + /* get the number of tiles and set up the result structure */ + ts.twidth = twidth; + ts.theight = theight; + ts.ntiles = (result.width/twidth) * (result.height/theight); + ts.palette = result.palette; + + /* allocate the pixel storage for the tiles */ + ts.data = malloc(sizeof(byte*) * ts.ntiles); + ts.data[0] = malloc(sizeof(byte) * ts.ntiles * twidth * theight); + for(i=1; i < ts.ntiles; i++) { + ts.data[i] = ts.data[i-1] + twidth * theight; + } + + /* finish off the file */ + loadPcxPalette(file, &result); + + fclose(file); + + return ts; +} diff --git a/16/modex16/bitmap.h b/16/modex16/bitmap.h new file mode 100755 index 00000000..4c4af98e --- /dev/null +++ b/16/modex16/bitmap.h @@ -0,0 +1,24 @@ +/* + * Functions and types for loading and manipulating bitmaps. + */ +#ifndef BITMAP_H +#define BITMAP_H +#include "types.h" +typedef struct { + byte *data; + word width; + word height; + byte *palette; +} bitmap_t; + +typedef struct { + byte **data; + word ntiles; /* the number of tiles */ + word twidth; /* width of the tiles */ + word theight; /* height of the tiles */ + byte *palette; /* palette for the tile set */ +} tileset_t; + +bitmap_t bitmapLoadPcx(char *filename); +tileset_t bitmapLoadPcxTiles(char *filename, word twidth, word theight); +#endif diff --git a/16/modex16/chikyuu.pcx b/16/modex16/chikyuu.pcx new file mode 100755 index 00000000..61eac4cc Binary files /dev/null and b/16/modex16/chikyuu.pcx differ diff --git a/16/modex16/computer.pcx b/16/modex16/computer.pcx new file mode 100755 index 00000000..07da0a5c Binary files /dev/null and b/16/modex16/computer.pcx differ diff --git a/16/modex16/dos_kb.c b/16/modex16/dos_kb.c new file mode 100755 index 00000000..dd924189 --- /dev/null +++ b/16/modex16/dos_kb.c @@ -0,0 +1,142 @@ +/* Thanks to Alex Russell for example code */ +/* Thanks to Gary Neal for example code */ +#include "dos_kb.h" + +// keyboard buffer +static byte key[NUM_SCANCODES]; // pressed +static byte kea[NUM_SCANCODES]; // released + +#ifdef __cplusplus /* Function must be declared C style */ +extern "C" { +#endif +static void interrupt (far *oldkb)(void) = NULL; /* BIOS keyboard handler */ +#ifdef __cplusplus +} +#endif + +/* + * Comment out the following #define if you don't want the testing main() + * to be included. + */ +//#define TESTING +#define TESTING2 + +/*****************NEW KEYBOARD 09h ISR***********************/ +void interrupt newkb(void){ + byte kee; + register char qx; + + kee = inp(0x60); /* Read the keyboard scan code */ + + /* Clear keyboard controller on XT machines */ + qx = inp(0x61); /* Get keyboard control register */ + qx |= 0x82; + outp(0x61, qx); /* Toggle acknowledge bit high */ + qx &= 0x7F; + outp(0x61, qx); /* Toggle acknowledge bit low */ + + /* Interpret the scan code and set our flags */ + #ifdef TESTING2 + //printf("%d[%d]\n",kee,key[kee]); + printf("\0"); // bug + #endif + if(kee & 0x80) + key[kee & 0x7F] = 0; // a key is released + else + key[kee] = kea[kee] = 1; // a key is pressed + + /* Acknowledge the interrupt to the programmable interrupt controller */ + outp(0x20, 0x20); /* Signal non specific end of interrupt */ +} + +/* ---------------------- init_keyboard() ---------------- April 17,1993 */ +/* restore the bios keyboard handler */ +/* ---------------------- deinit_keyboard() -------------- April 17,1993 */ +void setkb(int vq){ + int i; /* Index variable */ + if(!vq){ // deinitiation + /* Abort if our function pointer has no valid address */ + if(oldkb == NULL) return; + /* Set address in our function pointer in interrupt vector table */ + _dos_setvect(9, oldkb); + /* Reset our function pointer to contain no valid address */ + oldkb = NULL; + #ifdef TESTING + /* Print the key heap */ + printf("\n"); + for(i=0; i<NUM_SCANCODES; i++){ + if(i==NUM_SCANCODES/2) printf("================================\n"); + printf("%03d[%d][%d]",i+1,key[i],kea[i]); + if(key[i]==1)printf("===="); + printf(",\n"); + } + #endif + }else if(vq == 1){ // initiation + byte far *lock_key; + + /* Abort if our function pointer has a valid address. */ + if(oldkb != NULL) return; + + /* Clear the keyboard buttons state arrays */ + for(i = 0; i < NUM_SCANCODES; i++) + key[i] = kea[i] = 0; + + /* save old BIOS key board handler */ + oldkb = _dos_getvect(9); + + // turn off num-lock via BIOS + lock_key = MK_FP(0x040, 0x017); // Pointing to the address of the bios shift state keys + *lock_key&=(~(16 | 32 | 64)); // toggle off the locks by changing the values of the 4th, 5th, and 6th bits of the address byte of 0040:0017 + oldkb(); // call BIOS keyhandler to change keyboard lights + + /* setup our own handler */ + _dos_setvect(9, newkb); + } +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ + * keyp * + * * + * Returns the status of the key requested. * + * The status is 1 if the key is pressed or has been pressed since the * + * last call to this function for that particular key. * +\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +int keyp(byte c){ + register char retVal; + + /* Key value in range of keyboard keys available */ + c &= 0x7F; + + /* Get the status of the key requested */ + retVal = key[c] | kea[c]; + + /* Reset the was pressed status for the requested key */ + kea[c] = 0; + + /* Return the requested key's state */ + return retVal; +} + + +/* + * The library testing routines follows below. + */ + +#ifdef TESTING + +/* + * Library test (program) entry point. + */ + +void main(void) +{ + byte q; + setkb(1); + while(!keyp(1)) + { + keyp(q); + } + setkb(0); +} + +#endif diff --git a/16/modex16/dos_kb.h b/16/modex16/dos_kb.h new file mode 100755 index 00000000..ea81462a --- /dev/null +++ b/16/modex16/dos_kb.h @@ -0,0 +1,23 @@ +#ifndef _DOSLIB_KB_H_ +#define _DOSLIB_KB_H_ +#include "lib\lib_com.h" + +/* Maximum number of scan codes on keyboard controllers */ +#define NUM_SCANCODES 128 + +#ifdef __cplusplus /* Functions must be declared C style */ +extern "C" { +#endif +void interrupt far newkb(void); +//extern void interrupt (far *oldkb)(void); +void setkb(int vq); +int keyp(byte c); + +/* Define macro */ +//#define kepn(c) key[c & 0x7F] + +#ifdef __cplusplus +} +#endif + +#endif/*_DOSLIB_KB_H_*/ diff --git a/16/modex16/ed.pcx b/16/modex16/ed.pcx new file mode 100755 index 00000000..41e56317 Binary files /dev/null and b/16/modex16/ed.pcx differ diff --git a/16/modex16/ed2.pcx b/16/modex16/ed2.pcx new file mode 100755 index 00000000..b35305e3 Binary files /dev/null and b/16/modex16/ed2.pcx differ diff --git a/16/modex16/edw.pcx b/16/modex16/edw.pcx new file mode 100755 index 00000000..2427b5da Binary files /dev/null and b/16/modex16/edw.pcx differ diff --git a/16/modex16/gfx.pal b/16/modex16/gfx.pal new file mode 100755 index 00000000..e98ae60e Binary files /dev/null and b/16/modex16/gfx.pal differ diff --git a/16/modex16/koishi.pcx b/16/modex16/koishi.pcx new file mode 100755 index 00000000..76d05160 Binary files /dev/null and b/16/modex16/koishi.pcx differ diff --git a/16/modex16/koishi^^.pcx b/16/modex16/koishi^^.pcx new file mode 100755 index 00000000..0dbbc0da Binary files /dev/null and b/16/modex16/koishi^^.pcx differ diff --git a/16/modex16/koishi~.pcx b/16/modex16/koishi~.pcx new file mode 100755 index 00000000..58a03bb4 Binary files /dev/null and b/16/modex16/koishi~.pcx differ diff --git a/16/modex16/lib/lib_com.cpp b/16/modex16/lib/lib_com.cpp new file mode 100755 index 00000000..19ad2ddf --- /dev/null +++ b/16/modex16/lib/lib_com.cpp @@ -0,0 +1,21 @@ +//#include "src\lib\lib_com.h" +#include "lib\lib_com.h" + +/* local function */ +void wait(clock_t wait); + +/* Function: Wait ********************************************************** +* +* Parameters: wait - time in microseconds +* +* Description: pauses for a specified number of microseconds. +* +*/ +void wait(clock_t wait){ + clock_t goal; + + if(!wait) return; + + goal = wait + clock(); + while((goal > clock()) && !kbhit()) ; +} /* End of wait */ \ No newline at end of file diff --git a/16/modex16/lib/lib_com.h b/16/modex16/lib/lib_com.h new file mode 100755 index 00000000..5a203b9d --- /dev/null +++ b/16/modex16/lib/lib_com.h @@ -0,0 +1,106 @@ +#ifndef _LIBCOM_H_ +#define _LIBCOM_H_ +#include <dos.h> +#include <stdio.h> +#include <conio.h> // just for wait +#include <time.h> // just for wait +#include "types.h" + +/* Control codes for all keys on the keyboard */ +//here temperarly +#define KEY_A (0x1E) +#define KEY_B (0x30) +#define KEY_C (0x2E) +#define KEY_D (0x20) +#define KEY_E (0x12) +#define KEY_F (0x21) +#define KEY_G (0x22) +#define KEY_H (0x23) +#define KEY_I (0x17) +#define KEY_J (0x24) +#define KEY_K (0x25) +#define KEY_L (0x26) +#define KEY_M (0x32) +#define KEY_N (0x31) +#define KEY_O (0x18) +#define KEY_P (0x19) +#define KEY_Q (0x10) +#define KEY_R (0x13) +#define KEY_S (0x1F) +#define KEY_T (0x14) +#define KEY_U (0x16) +#define KEY_V (0x2F) +#define KEY_W (0x11) +#define KEY_X (0x2D) +#define KEY_Y (0x15) +#define KEY_Z (0x2C) +#define KEY_1 (0x02) +#define KEY_2 (0x03) +#define KEY_3 (0x04) +#define KEY_4 (0x05) +#define KEY_5 (0x06) +#define KEY_6 (0x07) +#define KEY_7 (0x08) +#define KEY_8 (0x09) +#define KEY_9 (0x0A) +#define KEY_0 (0x0B) +#define KEY_DASH (0x0C) /* -_ */ +#define KEY_EQUAL (0x0D) /* =+ */ +#define KEY_LBRACKET (0x1A) /* [{ */ +#define KEY_RBRACKET (0x1B) /* ]} */ +#define KEY_SEMICOLON (0x27) /* ;: */ +#define KEY_RQUOTE (0x28) /* '" */ +#define KEY_LQUOTE (0x29) /* `~ */ +#define KEY_PERIOD (0x33) /* .> */ +#define KEY_COMMA (0x34) /* ,< */ +#define KEY_SLASH (0x35) /* /? */ +#define KEY_BACKSLASH (0x2B) /* \| */ +#define KEY_F1 (0x3B) +#define KEY_F2 (0x3C) +#define KEY_F3 (0x3D) +#define KEY_F4 (0x3E) +#define KEY_F5 (0x3F) +#define KEY_F6 (0x40) +#define KEY_F7 (0x41) +#define KEY_F8 (0x42) +#define KEY_F9 (0x43) +#define KEY_F10 (0x44) +#define KEY_ESC (0x01) +#define KEY_BACKSPACE (0x0E) +#define KEY_TAB (0x0F) +#define KEY_ENTER (0x1C) +#define KEY_CONTROL (0x1D) +#define KEY_LSHIFT (0x2A) +#define KEY_RSHIFT (0x36) +#define KEY_PRTSC (0x37) +#define KEY_ALT (0x38) +#define KEY_SPACE (0x39) +#define KEY_CAPSLOCK (0x3A) +#define KEY_NUMLOCK (0x45) +#define KEY_SCROLLLOCK (0x46) +#define KEY_HOME (0x47) +#define KEY_UP (0x48) +#define KEY_PGUP (0x49) +#define KEY_MINUS (0x4A) +#define KEY_LEFT (0x4B) +#define KEY_CENTER (0x4C) +#define KEY_RIGHT (0x4D) +#define KEY_PLUS (0x4E) +#define KEY_END (0x4F) +#define KEY_DOWN (0x50) +#define KEY_PGDOWN (0x51) +#define KEY_INS (0x52) +#define KEY_DEL (0x53) + +#define KEY_LWIN (0x73) +#define KEY_RWIN (0x74) +#define KEY_MENU (0x75) + + +//typedef unsigned char byte; +//typedef unsigned int word; +//typedef unsigned short syte; + +void wait(clock_t wait); + +#endif/*_LIBCOM_H_*/ diff --git a/16/modex16/makefile b/16/modex16/makefile new file mode 100755 index 00000000..b11f89a0 --- /dev/null +++ b/16/modex16/makefile @@ -0,0 +1,37 @@ +FLAGS=-0 +all: test.exe pcxtest.exe test2.exe scroll.exe + +scroll.exe: scroll.obj modex16.obj dos_kb.obj bitmap.obj + wcl $(FLAGS) scroll.obj modex16.obj dos_kb.obj bitmap.obj +scroll.obj: scroll.c + wcl $(FLAGS) -c scroll.c +test.exe: test.obj modex16.obj bitmap.obj + wcl $(FLAGS) test.obj modex16.obj bitmap.obj + +test2.exe: test2.obj modex16.obj bitmap.obj + wcl $(FLAGS) test2.obj modex16.obj bitmap.obj + +pcxtest.exe: pcxtest.obj modex16.obj bitmap.obj + wcl $(FLAGS) pcxtest.obj modex16.obj bitmap.obj + +test.obj: test.c modex16.h + wcl $(FLAGS) -c test.c + +test2.obj: test2.c modex16.h + wcl $(FLAGS) -c test2.c + +pcxtest.obj: pcxtest.c modex16.h + wcl $(FLAGS) -c pcxtest.c + +modex16.obj: modex16.h modex16.c + wcl $(FLAGS) -c modex16.c + +dos_kb.obj: dos_kb.h dos_kb.c + wcl $(FLAGS) -c dos_kb.c + +bitmap.obj: bitmap.h bitmap.c + wcl $(FLAGS) -c bitmap.c + +clean: + del *.obj + del *.exe diff --git a/16/modex16/mayu.pcx b/16/modex16/mayu.pcx new file mode 100755 index 00000000..025e7d4a Binary files /dev/null and b/16/modex16/mayu.pcx differ diff --git a/16/modex16/modex16.c b/16/modex16/modex16.c new file mode 100755 index 00000000..f01116b5 --- /dev/null +++ b/16/modex16/modex16.c @@ -0,0 +1,605 @@ +#include <dos.h> +#include <string.h> +#include <mem.h> +#include <conio.h> +#include <stdio.h> +#include <stdlib.h> +#include "modex16.h" + + +byte far* VGA=(byte far*) 0xA0000000; /* this points to video memory. */ + +static void fadePalette(sbyte fade, sbyte start, word iter, byte *palette); +static byte tmppal[PAL_SIZE]; + +static void +vgaSetMode(byte mode) +{ + union REGS regs; + + regs.h.ah = SET_MODE; + regs.h.al = mode; + int86(VIDEO_INT, ®s, ®s); +} + + +/* -========================= Entry Points ==========================- */ +void +modexEnter() { + word i; + dword far*ptr=(dword far*)VGA; /* used for faster screen clearing */ + word CRTParms[] = { + 0x0d06, /* vertical total */ + 0x3e07, /* overflow (bit 8 of vertical counts) */ + 0x4109, /* cell height (2 to double-scan */ + 0xea10, /* v sync start */ + 0xac11, /* v sync end and protect cr0-cr7 */ + 0xdf12, /* vertical displayed */ + 0x0014, /* turn off dword mode */ + 0xe715, /* v blank start */ + 0x0616, /* v blank end */ + 0xe317 /* turn on byte mode */ + }; + int CRTParmCount = sizeof(CRTParms) / sizeof(CRTParms[0]); + + /* TODO save current video mode and palette */ + vgaSetMode(VGA_256_COLOR_MODE); + + /* disable chain4 mode */ + outpw(SC_INDEX, 0x0604); + + /* synchronous reset while setting Misc Output */ + outpw(SC_INDEX, 0x0100); + + /* select 25 MHz dot clock & 60 Hz scanning rate */ + outp(MISC_OUTPUT, 0xe3); + + /* undo reset (restart sequencer) */ + outpw(SC_INDEX, 0x0300); + + /* reprogram the CRT controller */ + outp(CRTC_INDEX, 0x11); /* VSync End reg contains register write prot */ + outp(CRTC_DATA, 0x7f); /* get current write protect on varios regs */ + + /* send the CRTParms */ + for(i=0; i<CRTParmCount; i++) { + outpw(CRTC_INDEX, CRTParms[i]); + } + + /* clear video memory */ + outpw(SC_INDEX, 0x0f02); + for(i=0; i<0x8000; i++) { + ptr[i] = 0x0000; + } +} + + +void +modexLeave() { + /* TODO restore original mode and palette */ + vgaSetMode(TEXT_MODE); +} + + +page_t +modexDefaultPage() { + page_t page; + + /* default page values */ + page.data = VGA; + page.dx = 0; + page.dy = 0; + page.width = SCREEN_WIDTH; + page.height = SCREEN_HEIGHT; + + return page; +} + +/* returns the next page in contiguous memory + * the next page will be the same size as p, by default + */ +page_t +modexNextPage(page_t *p) { + page_t result; + + result.data = p->data + (p->width/4)*p->height; /* compute the offset */ + result.dx = 0; + result.dy = 0; + result.width = p->width; + result.height = p->height; + + return result; +} + + +void +modexShowPage(page_t *page) { + word high_address; + word low_address; + word offset; + byte crtcOffset; + + /* calculate offset */ + offset = (word) page->data; + offset += page->dy * (page->width >> 2 ); + offset += page->dx >> 2; + + /* calculate crtcOffset according to virtual width */ + crtcOffset = page->width >> 3; + + high_address = HIGH_ADDRESS | (offset & 0xff00); + low_address = LOW_ADDRESS | (offset << 8); + + /* wait for appropriate timing and then program CRTC */ + while ((inp(INPUT_STATUS_1) & DISPLAY_ENABLE)); + outpw(CRTC_INDEX, high_address); + outpw(CRTC_INDEX, low_address); + outp(CRTC_INDEX, 0x13); + outp(CRTC_DATA, crtcOffset); + + /* wait for one retrace */ + while (!(inp(INPUT_STATUS_1) & VRETRACE)); + + /* do PEL panning here */ + outp(AC_INDEX, 0x33); + outp(AC_INDEX, (page->dx & 0x03) << 1); +} + + +void +modexPanPage(page_t *page, int dx, int dy) { + page->dx = dx; + page->dy = dy; +} + + +void +modexSelectPlane(byte plane) { + outp(SC_INDEX, MAP_MASK); /* select plane */ + outp(SC_DATA, plane); +} + + +void +modexClearRegion(page_t *page, int x, int y, int w, int h, byte color) { + word pageOff = (word) page->data; + word xoff=x/4; /* xoffset that begins each row */ + word scanCount=w/4; /* number of iterations per row (excluding right clip)*/ + word poffset = pageOff + y*(page->width/4) + xoff; /* starting offset */ + word nextRow = page->width/4-scanCount-1; /* loc of next row */ + byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */ + byte rclip[] = {0x00, 0x01, 0x03, 0x07}; + byte left = lclip[x&0x03]; + byte right = rclip[(x+w)&0x03]; + + /* handle the case which requires an extra group */ + if((x & 0x03) && !((x+w) & 0x03)) { + right=0x0f; + } + + __asm { + MOV AX, SCREEN_SEG ; go to the VGA memory + MOV ES, AX + MOV DI, poffset ; go to the first pixel + MOV DX, SC_INDEX ; point to the map mask + MOV AL, MAP_MASK + OUT DX, AL + INC DX + MOV AL, color ; get ready to write colors + SCAN_START: + MOV CX, scanCount ; count the line + MOV BL, AL ; remember color + MOV AL, left ; do the left clip + OUT DX, AL ; set the left clip + MOV AL, BL ; restore color + STOSB ; write the color + DEC CX + JZ SCAN_DONE ; handle 1 group stuff + + ;-- write the main body of the scanline + MOV BL, AL ; remember color + MOV AL, 0x0f ; write to all pixels + OUT DX, AL + MOV AL, BL ; restore color + REP STOSB ; write the color + SCAN_DONE: + MOV BL, AL ; remeber color + MOV AL, right + OUT DX, AL ; do the right clip + MOV AL, BL ; restore color + STOSB ; write pixel + ADD DI, nextRow ; go to the next row + DEC h + JNZ SCAN_START + } +} + + +void +modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp) { + /* draw the region (the entire freakin bitmap) */ + modexDrawBmpRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp); +} + + +void +modexDrawBmpRegion(page_t *page, int x, int y, + int rx, int ry, int rw, int rh, bitmap_t *bmp) { + word poffset = (word) page->data + y*(page->width/4) + x/4; + byte *data = bmp->data; + word bmpOffset = (word) data + ry * bmp->width + rx; + word width = rw; + word height = rh; + byte plane = 1 << ((byte) x & 0x03); + word scanCount = width/4 + (width%4 ? 1 :0); + word nextPageRow = page->width/4 - scanCount; + word nextBmpRow = (word) bmp->width - width; + word rowCounter; + byte planeCounter = 4; + + __asm { + MOV AX, SCREEN_SEG ; go to the VGA memory + MOV ES, AX + + MOV DX, SC_INDEX ; point at the map mask register + MOV AL, MAP_MASK ; + OUT DX, AL ; + + PLANE_LOOP: + MOV DX, SC_DATA ; select the current plane + MOV AL, plane ; + OUT DX, AL ; + + ;-- begin plane painting + MOV AX, height ; start the row counter + MOV rowCounter, AX ; + MOV DI, poffset ; go to the first pixel + MOV SI, bmpOffset ; go to the bmp pixel + ROW_LOOP: + MOV CX, width ; count the columns + SCAN_LOOP: + MOVSB ; copy the pixel + SUB CX, 3 ; we skip the next 3 + ADD SI, 3 ; skip the bmp pixels + LOOP SCAN_LOOP ; finish the scan + + MOV AX, nextPageRow + ADD DI, AX ; go to the next row on screen + MOV AX, nextBmpRow + ADD SI, AX ; go to the next row on bmp + + DEC rowCounter + JNZ ROW_LOOP ; do all the rows + ;-- end plane painting + + MOV AL, plane ; advance to the next plane + SHL AL, 1 ; + AND AL, 0x0f ; mask the plane properly + MOV plane, AL ; store the plane + + INC bmpOffset ; start bmp at the right spot + + DEC planeCounter + JNZ PLANE_LOOP ; do all 4 planes + } +} + + +void +modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp) { + /* draw the whole sprite */ + modexDrawSpriteRegion(page, x, y, 0, 0, bmp->width, bmp->height, bmp); +} + +void +modexDrawSpriteRegion(page_t *page, int x, int y, + int rx, int ry, int rw, int rh, bitmap_t *bmp) { + word poffset = (word)page->data + y*(page->width/4) + x/4; + byte *data = bmp->data; + word bmpOffset = (word) data + ry * bmp->width + rx; + word width = rw; + word height = rh; + byte plane = 1 << ((byte) x & 0x03); + word scanCount = width/4 + (width%4 ? 1 :0); + word nextPageRow = page->width/4 - scanCount; + word nextBmpRow = (word) bmp->width - width; + word rowCounter; + byte planeCounter = 4; + + __asm { + MOV AX, SCREEN_SEG ; go to the VGA memory + MOV ES, AX + + MOV DX, SC_INDEX ; point at the map mask register + MOV AL, MAP_MASK ; + OUT DX, AL ; + + PLANE_LOOP: + MOV DX, SC_DATA ; select the current plane + MOV AL, plane ; + OUT DX, AL ; + + ;-- begin plane painting + MOV AX, height ; start the row counter + MOV rowCounter, AX ; + MOV DI, poffset ; go to the first pixel + MOV SI, bmpOffset ; go to the bmp pixel + ROW_LOOP: + MOV CX, width ; count the columns + SCAN_LOOP: + LODSB + DEC SI + CMP AL, 0 + JNE DRAW_PIXEL ; draw non-zero pixels + + INC DI ; skip the transparent pixel + ADD SI, 1 + JMP NEXT_PIXEL + DRAW_PIXEL: + MOVSB ; copy the pixel + NEXT_PIXEL: + SUB CX, 3 ; we skip the next 3 + ADD SI, 3 ; skip the bmp pixels + LOOP SCAN_LOOP ; finish the scan + + MOV AX, nextPageRow + ADD DI, AX ; go to the next row on screen + MOV AX, nextBmpRow + ADD SI, AX ; go to the next row on bmp + + DEC rowCounter + JNZ ROW_LOOP ; do all the rows + ;-- end plane painting + + MOV AL, plane ; advance to the next plane + SHL AL, 1 ; + AND AL, 0x0f ; mask the plane properly + MOV plane, AL ; store the plane + + INC bmpOffset ; start bmp at the right spot + + DEC planeCounter + JNZ PLANE_LOOP ; do all 4 planes + } +} + + +/* copy a region of video memory from one page to another. + * It assumes that the left edge of the tile is the same on both + * regions and the memory areas do not overlap. + */ +void +modexCopyPageRegion(page_t *dest, page_t *src, + word sx, word sy, + word dx, word dy, + word width, word height) +{ + word doffset = (word)dest->data + dy*(dest->width/4) + dx/4; + word soffset = (word)src->data + sy*(src->width/4) + sx/4; + word scans = width/4; + word nextSrcRow = src->width/4 - scans - 1; + word nextDestRow = dest->width/4 - scans - 1; + byte lclip[] = {0x0f, 0x0e, 0x0c, 0x08}; /* clips for rectangles not on 4s */ + byte rclip[] = {0x0f, 0x01, 0x03, 0x07}; + byte left = lclip[sx&0x03]; + byte right = rclip[(sx+width)&0x03]; + + __asm { + MOV AX, SCREEN_SEG ; work in the vga space + MOV ES, AX ; + MOV DI, doffset ; + MOV SI, soffset ; + + MOV DX, GC_INDEX ; turn off cpu bits + MOV AX, 0008h ; + OUT DX, AX + + MOV AX, SC_INDEX ; point to the mask register + MOV DX, AX ; + MOV AL, MAP_MASK ; + OUT DX, AL ; + INC DX ; + + ROW_START: + PUSH DS + MOV AX, ES + MOV DS, AX + MOV CX, scans ; the number of latches + + MOV AL, left ; do the left column + OUT DX, AL ; + MOVSB ; + DEC CX ; + + MOV AL, 0fh ; do the inner columns + OUT DX, AL + REP MOVSB ; copy the pixels + + MOV AL, right ; do the right column + OUT DX, AL + MOVSB + POP DS + + MOV AX, SI ; go the start of the next row + ADD AX, nextSrcRow ; + MOV SI, AX ; + MOV AX, DI ; + ADD AX, nextDestRow ; + MOV DI, AX ; + + DEC height ; do the rest of the actions + JNZ ROW_START ; + + MOV DX, GC_INDEX+1 ; go back to CPU data + MOV AL, 0ffh ; none from latches + OUT DX, AL ; + } +} + + +/* fade and flash */ +void +modexFadeOn(word fade, byte *palette) { + fadePalette(-fade, 64, 64/fade+1, palette); +} + + +void +modexFadeOff(word fade, byte *palette) { + fadePalette(fade, 0, 64/fade+1, palette); +} + + +void +modexFlashOn(word fade, byte *palette) { + fadePalette(fade, -64, 64/fade+1, palette); +} + + +void +modexFlashOff(word fade, byte *palette) { + fadePalette(-fade, 0, 64/fade+1, palette); +} + + +static void +fadePalette(sbyte fade, sbyte start, word iter, byte *palette) { + word i; + byte dim = start; + + /* handle the case where we just update */ + if(iter == 0) { + modexPalUpdate(palette); + return; + } + + while(iter > 0) { /* FadeLoop */ + for(i=0; i<PAL_SIZE; i++) { /* loadpal_loop */ + tmppal[i] = palette[i] - dim; + if(tmppal[i] > 127) { + tmppal[i] = 0; + } else if(tmppal[i] > 63) { + tmppal[i] = 63; + } + } + modexPalUpdate(tmppal); + iter--; + dim += fade; + } +} + + +/* save and load */ +void +modexPalSave(byte *palette) { + int i; + + outp(PAL_READ_REG, 0); /* start at palette entry 0 */ + for(i=0; i<PAL_SIZE; i++) { + palette[i] = inp(PAL_DATA_REG); /* read the palette data */ + } +} + + +byte * +modexNewPal() { + byte *ptr; + ptr = malloc(PAL_SIZE); + + /* handle errors */ + if(!ptr) { + printf("Could not allocate palette.\n"); + exit(-1); + } + + return ptr; +} + + +void +modexLoadPalFile(byte *filename, byte **palette) { + FILE *file; + byte *ptr; + + /* free the palette if it exists */ + if(*palette) { + free(*palette); + } + + /* allocate the new palette */ + *palette = modexNewPal(); + + /* open the file */ + file = fopen(filename, "rb"); + if(!file) { + printf("Could not open palette file: %s\n", filename); + exit(-2); + } + + /* read the file */ + ptr = *palette; + while(!feof(file)) { + *ptr++ = fgetc(file); + } + + fclose(file); +} + + +void +modexSavePalFile(char *filename, byte *pal) { + unsigned int i; + FILE *file; + + /* open the file for writing */ + file = fopen(filename, "wb"); + if(!file) { + printf("Could not open %s for writing\n", filename); + exit(-2); + } + + /* write the data to the file */ + fwrite(pal, 1, PAL_SIZE, file); + fclose(file); +} + + +/* blanking */ +void +modexPalBlack() { + fadePalette(-1, 64, 1, tmppal); +} + + +void +modexPalWhite() { + fadePalette(-1, -64, 1, tmppal); +} + + +/* utility */ +void +modexPalUpdate(byte *p) { + int i; + modexWaitBorder(); + outp(PAL_WRITE_REG, 0); /* start at the beginning of palette */ + for(i=0; i<PAL_SIZE/2; i++) { + outp(PAL_DATA_REG, p[i]); + } + modexWaitBorder(); /* waits one retrace -- less flicker */ + for(i=PAL_SIZE/2; i<PAL_SIZE; i++) { + outp(PAL_DATA_REG, p[i]); + } +} + + +void +modexWaitBorder() { + while(inp(INPUT_STATUS_1) & 8) { + /* spin */ + } + + while(!(inp(INPUT_STATUS_1) & 8)) { + /* spin */ + } +} diff --git a/16/modex16/modex16.h b/16/modex16/modex16.h new file mode 100755 index 00000000..77573105 --- /dev/null +++ b/16/modex16/modex16.h @@ -0,0 +1,86 @@ +/* + * Functions for handling modex and doing other basic graphics stuff. + */ +#ifndef MODEX16_H +#define MODEX16_H +#include <conio.h> +#include "types.h" +#include "bitmap.h" + +/* -========================== Types & Macros ==========================- */ +#define PAGE_OFFSET(x,y) (((y)<<6)+((y)<<4)+((x)>>2)) +#define PLANE(x) (1<< (x&3)) +#define SELECT_ALL_PLANES() outpw(0x03c4, 0xff02) + +typedef struct { + byte far* data; /* the data for the page */ + word dx; /* col we are viewing on the virtual screen */ + word dy; /* row we are viewing on the virtual screen */ + word width; /* virtual width of the page */ + word height; /* virtual height of the page */ +} page_t; + +/* -============================ Functions =============================- */ +/* mode switching, page, and plane functions */ +void modexEnter(); +void modexLeave(); +page_t modexDefaultPage(); +page_t modexNextPage(page_t *p); +void modexShowPage(page_t *page); +void modexPanPage(page_t *page, int dx, int dy); +void modexSelectPlane(byte plane); +void modexClearRegion(page_t *page, int x, int y, int w, int h, byte color); +void modexDrawBmp(page_t *page, int x, int y, bitmap_t *bmp); +void modexDrawBmpRegion(page_t *page, int x, int y, int rx, int ry, int rw, int rh, bitmap_t *bmp); +void modexDrawSprite(page_t *page, int x, int y, bitmap_t *bmp); +void modexDrawSpriteRegion(page_t *page, int x, int y, int rx, int ry, int rw, int rh, bitmap_t *bmp); + +/* Palette fade and flash effects */ +void modexFadeOn(word fade, byte *palette); +void modexFadeOff(word fade, byte *palette); +void modexFlashOn(word fade, byte *palette); +void modexFlashOff(word fade, byte *palette); + +/* palette loading and saving */ +void modexPalSave(byte *palette); +byte *modexNewPal(); +void modexLoadPalFile(char *filename, byte **palette); +void modexSavePalFile(char *filename, byte *palette); + +/* fixed palette functions */ +void modexPalBlack(); +void modexPalWhite(); + +/* utility functions */ +void modexPalUpdate(byte *p); +void modexWaitBorder(); + +/* -======================= Constants & Vars ==========================- */ +extern byte far* VGA; /* The VGA Memory */ +#define SCREEN_SEG 0xa000 +#define VIDEO_INT 0x10 +#define SET_MODE 0x00 +#define VGA_256_COLOR_MODE 0x13 +#define TEXT_MODE 0x03 +#define SCREEN_WIDTH 320 +#define SCREEN_HEIGHT 240 +#define PAGE_SIZE (word)(SCREEN_WIDTH/4 * SCREEN_HEIGHT) + +#define AC_INDEX 0x03c0 +#define SC_INDEX 0x03c4 +#define SC_DATA 0x03c5 +#define CRTC_INDEX 0x03d4 +#define CRTC_DATA 0x03d5 +#define GC_INDEX 0x03ce +#define MISC_OUTPUT 0x03c2 +#define HIGH_ADDRESS 0x0C +#define LOW_ADDRESS 0x0D +#define VRETRACE 0x08 +#define INPUT_STATUS_1 0x03da +#define DISPLAY_ENABLE 0x01 +#define MAP_MASK 0x02 +#define PAL_READ_REG 0x03C7 /* Color register, read address */ +#define PAL_WRITE_REG 0x03C8 /* Color register, write address */ +#define PAL_DATA_REG 0x03C9 /* Color register, data port */ +#define PAL_SIZE (256 * 3) +#endif diff --git a/16/modex16/palettec.c b/16/modex16/palettec.c new file mode 100755 index 00000000..340a9303 --- /dev/null +++ b/16/modex16/palettec.c @@ -0,0 +1,16 @@ +#include "modex16.h" + +void +main() { + byte *pal; + + modexEnter(); + + pal = modexNewPal(); + modexPalSave(pal); + + modexSavePalFile("gfx.pal", pal); + + modexLeave(); + +} diff --git a/16/modex16/pcxtest.c b/16/modex16/pcxtest.c new file mode 100755 index 00000000..7373e885 --- /dev/null +++ b/16/modex16/pcxtest.c @@ -0,0 +1,79 @@ +#include <stdio.h> +#include "modex16.h" +#include "bitmap.h" + +word far* clock= (word far*) 0x046C; /* 18.2hz clock */ + +void +oldDrawBmp(byte far* page, int x, int y, bitmap_t *bmp, byte sprite) { + byte plane; + word px, py; + word offset; + + /* TODO Make this fast. It's SLOOOOOOW */ + for(plane=0; plane < 4; plane++) { + modexSelectPlane(PLANE(plane+x)); + for(px = plane; px < bmp->width; px+=4) { + offset=px; + for(py=0; py<bmp->height; py++) { + if(!sprite || bmp->data[offset]) + page[PAGE_OFFSET(x+px, y+py)] = bmp->data[offset]; + offset+=bmp->width; + } + } + } +} + +void main() { + bitmap_t bmp; + int i; + page_t page; + word start; + float t1, t2; + + page=modexDefaultPage(); + + bmp = bitmapLoadPcx("46113319.pcx"); + modexEnter(); + + /* fix up the palette and everything */ + modexPalUpdate(bmp.palette); + + /* clear and draw one sprite and one bitmap */ + modexClearRegion(&page, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 1); + + /* non sprite comparison */ + start = *clock; + for(i=0; i<100 ;i++) { + oldDrawBmp(VGA, 20, 20, &bmp, 0); + } + + start = *clock; + for(i=0; i<100 ;i++) { + modexDrawBmp(&page, 20, 20, &bmp); + } + t1 = (*clock-start) /18.2; + + start = *clock; + for(i=0; i<100; i++) { + modexCopyPageRegion(&page, &page, 20, 20, 128, 20, 64, 64); + } + t2 = (*clock-start)/18.2; + + + start = *clock; + for(i=0; i<100 ;i++) { + oldDrawBmp(VGA, 20, 20, &bmp, 1); + } + + + start = *clock; + for(i=0; i<100 ;i++) { + modexDrawSprite(&page, 20, 20, &bmp); + } + modexLeave(); + + printf("CPU to VGA: %f\n", t1); + printf("VGA to VGA: %f\n", t2); + return; +} diff --git a/16/modex16/pcxtest.exe b/16/modex16/pcxtest.exe new file mode 100755 index 00000000..de765ece Binary files /dev/null and b/16/modex16/pcxtest.exe differ diff --git a/16/modex16/q.pcx b/16/modex16/q.pcx new file mode 100755 index 00000000..a51d634c Binary files /dev/null and b/16/modex16/q.pcx differ diff --git a/16/modex16/rarity.pcx b/16/modex16/rarity.pcx new file mode 100755 index 00000000..8e7e32fc Binary files /dev/null and b/16/modex16/rarity.pcx differ diff --git a/16/modex16/scroll.c b/16/modex16/scroll.c new file mode 100755 index 00000000..8a960eee --- /dev/null +++ b/16/modex16/scroll.c @@ -0,0 +1,363 @@ +#include "modex16.h" +#include <stdio.h> +#include <stdlib.h> +#include "dos_kb.h" + +//word far *clock= (word far*) 0x046C; /* 18.2hz clock */ + +typedef struct { + bitmap_t *data; + word tileHeight; + word tileWidth; + unsigned int rows; + unsigned int cols; + unsigned int tilex,tiley; // tile position on the map +} tiles_t; + + +typedef struct { + byte *data; + tiles_t *tiles; + int width; + int height; +} map_t; + + +typedef struct { + map_t *map; + page_t *page; + int tx; //???? appears to be the tile position on the viewable screen map + int ty; //???? appears to be the tile position on the viewable screen map + word dxThresh; //???? + word dyThresh; //???? +} map_view_t; + +struct { + int tx; //player position on the viewable map + int ty; //player position on the viewable map +} player; + + +map_t allocMap(int w, int h); +void initMap(map_t *map); +void mapScrollRight(map_view_t *mv, byte offset); +void mapScrollLeft(map_view_t *mv, byte offest); +void mapScrollUp(map_view_t *mv, byte offset); +void mapScrollDown(map_view_t *mv, byte offset); +void mapGoTo(map_view_t *mv, int tx, int ty); +void mapDrawTile(tiles_t *t, word i, page_t *page, word x, word y); +void mapDrawRow(map_view_t *mv, int tx, int ty, word y); +void mapDrawCol(map_view_t *mv, int tx, int ty, word x); + +#define TILEWH 16 +#define QUADWH (TILEWH/4) +//#define SWAP(a, b) tmp=a; a=b; b=tmp; +void main() { +// int show1=1; + int tx, ty; + int x, y; + //int ch=0x0; +// byte ch; + int q=0; + page_t screen;//,screen2; + map_t map; + map_view_t mv;//, mv2; + map_view_t *draw;//, *show, *tmp; + byte *ptr; + + //default player position on the viewable map + player.tx = 10; + player.ty = 8; + + setkb(1); + /* create the map */ + map = allocMap(160,120); //20x15 is the resolution of the screen you can make maps smaller than 20x15 but the null space needs to be drawn properly + initMap(&map); + mv.map = ↦ +// mv2.map = ↦ + + /* draw the tiles */ + ptr = map.data; + modexEnter(); + screen = modexDefaultPage(); + screen.width += (TILEWH*2); + mv.page = &screen; + mapGoTo(&mv, 16, 16); +// screen2=modexNextPage(mv.page); +// mv2.page = &screen2; +// mapGoTo(&mv2, 16, 16); +// modexShowPage(mv.page); + + /* set up paging */ +// show = &mv; +// draw = &mv2; + draw = &mv; + + //TODO: set player position data here according to the viewable map screen thingy + + while(!keyp(1)) { + //TODO: top left corner & bottem right corner of map veiw be set as map edge trigger since maps are actually square + //to stop scrolling and have the player position data move to the edge of the screen with respect to the direction + //when player.tx or player.ty == 0 or player.tx == 20 or player.ty == 15 then stop because that is edge of map and you do not want to walk of the map + if(keyp(77)){ +// for(q=0; q<TILEWH; q++) { + mapScrollRight(draw, 1); +// modexShowPage(draw->page); +// mapScrollRight(draw, 1); +// SWAP(draw, show); +// } + } + + if(keyp(75)){ +// for(q=0; q<TILEWH; q++) { + mapScrollLeft(draw, 1); +// modexShowPage(draw->page); +// mapScrollLeft(show, 1); +// SWAP(draw, show); +// } + } + + if(keyp(80)){ +// for(q=0; q<TILEWH; q++) { + mapScrollDown(draw, 1); +// modexShowPage(draw->page); +// mapScrollDown(show, 1); +// SWAP(draw, show); +// } + } + + if(keyp(72)){ +// for(q=0; q<TILEWH; q++) { + mapScrollUp(draw, 1); +// modexShowPage(draw->page); +// mapScrollUp(show, 1); +// SWAP(draw, show); +// } + } + + //keyp(ch); + modexShowPage(draw->page); + + } + + modexLeave(); + setkb(0); +} + + +map_t +allocMap(int w, int h) { + map_t result; + + result.width =w; + result.height=h; + result.data = malloc(sizeof(byte) * w * h); + + return result; +} + + +void +initMap(map_t *map) { + /* just a place holder to fill out an alternating pattern */ + int x, y; + int i; + int tile = 1; + map->tiles = malloc(sizeof(tiles_t)); + + /* create the tile set */ + map->tiles->data = malloc(sizeof(bitmap_t)); + map->tiles->data->width = (TILEWH*2); + map->tiles->data->height= TILEWH; + map->tiles->data->data = malloc((TILEWH*2)*TILEWH); + map->tiles->tileHeight = TILEWH; + map->tiles->tileWidth =TILEWH; + map->tiles->rows = 1; + map->tiles->cols = 2; + + i=0; + for(y=0; y<TILEWH; y++) { + for(x=0; x<(TILEWH*2); x++) { + if(x<TILEWH) + map->tiles->data->data[i] = 0x24; + else + map->tiles->data->data[i] = 0x34; + i++; + } + } + + i=0; + for(y=0; y<map->height; y++) { + for(x=0; x<map->width; x++) { + map->data[i] = tile; + tile = tile ? 0 : 1; + i++; + } + tile = tile ? 0 : 1; + } +} + + +void +mapScrollRight(map_view_t *mv, byte offset) { + word x, y; /* coordinate for drawing */ + + /* increment the pixel position and update the page */ + mv->page->dx += offset; + + /* check to see if this changes the tile */ + if(mv->page->dx >= mv->dxThresh ) { + /* go forward one tile */ + mv->tx++; + /* Snap the origin forward */ + mv->page->data += 4; + mv->page->dx = mv->map->tiles->tileWidth; + + + /* draw the next column */ + x= SCREEN_WIDTH + mv->map->tiles->tileWidth; + mapDrawCol(mv, mv->tx + 20 , mv->ty-1, x); + } +} + + +void +mapScrollLeft(map_view_t *mv, byte offset) { + word x, y; /* coordinate for drawing */ + + /* increment the pixel position and update the page */ + mv->page->dx -= offset; + + /* check to see if this changes the tile */ + if(mv->page->dx == 0) { + /* go backward one tile */ + mv->tx--; + + /* Snap the origin backward */ + mv->page->data -= 4; + mv->page->dx = mv->map->tiles->tileWidth; + + /* draw the next column */ + mapDrawCol(mv, mv->tx-1, mv->ty-1, 0); + } +} + + +void +mapScrollUp(map_view_t *mv, byte offset) { + word x, y; /* coordinate for drawing */ + + /* increment the pixel position and update the page */ + mv->page->dy -= offset; + + /* check to see if this changes the tile */ + if(mv->page->dy == 0 ) { + /* go down one tile */ + mv->ty--; + /* Snap the origin downward */ + mv->page->data -= mv->page->width*4; + mv->page->dy = mv->map->tiles->tileHeight; + + + /* draw the next row */ + y= 0; + mapDrawRow(mv, mv->tx-1 , mv->ty-1, y); + } +} + + +void +mapScrollDown(map_view_t *mv, byte offset) { + word x, y; /* coordinate for drawing */ + + /* increment the pixel position and update the page */ + mv->page->dy += offset; + + /* check to see if this changes the tile */ + if(mv->page->dy >= mv->dyThresh ) { + /* go down one tile */ + mv->ty++; + /* Snap the origin downward */ + mv->page->data += mv->page->width*4; + mv->page->dy = mv->map->tiles->tileHeight; + + + /* draw the next row */ + y= SCREEN_HEIGHT + mv->map->tiles->tileHeight; + mapDrawRow(mv, mv->tx-1 , mv->ty+15, y); + } + +} + + +void +mapGoTo(map_view_t *mv, int tx, int ty) { + int px, py; + unsigned int i; + + /* set up the coordinates */ + mv->tx = tx; + mv->ty = ty; + mv->page->dx = mv->map->tiles->tileWidth; + mv->page->dy = mv->map->tiles->tileHeight; + + /* set up the thresholds */ + mv->dxThresh = mv->map->tiles->tileWidth * 2; + mv->dyThresh = mv->map->tiles->tileHeight * 2; + + /* draw the tiles */ + modexClearRegion(mv->page, 0, 0, mv->page->width, mv->page->height, 0); + py=0; + i=mv->ty * mv->map->width + mv->tx; + for(ty=mv->ty-1; py < SCREEN_HEIGHT+mv->dyThresh && ty < mv->map->height; ty++, py+=mv->map->tiles->tileHeight) { + mapDrawRow(mv, tx-1, ty, py); + i+=mv->map->width - tx; + } +} + + +void +mapDrawTile(tiles_t *t, word i, page_t *page, word x, word y) { + word rx; + word ry; + rx = (i % t->cols) * t->tileWidth; + ry = (i / t->cols) * t->tileHeight; + modexDrawBmpRegion(page, x, y, rx, ry, t->tileWidth, t->tileHeight, t->data); +} + + +void +mapDrawRow(map_view_t *mv, int tx, int ty, word y) { + word x; + int i; + + /* the position within the map array */ + i=ty * mv->map->width + tx; + for(x=0; x<SCREEN_WIDTH+mv->dxThresh && tx < mv->map->width; x+=mv->map->tiles->tileWidth, tx++) { + if(i>=0) { + /* we are in the map, so copy! */ + mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y); + } + i++; /* next! */ + } +} + + +void +mapDrawCol(map_view_t *mv, int tx, int ty, word x) { + int y; + int i; + + /* location in the map array */ + i=ty * mv->map->width + tx; + + /* We'll copy all of the columns in the screen, + i + 1 row above and one below */ + for(y=0; y<SCREEN_HEIGHT+mv->dyThresh && ty < mv->map->height; y+=mv->map->tiles->tileHeight, ty++) { + if(i>=0) { + /* we are in the map, so copy away! */ + mapDrawTile(mv->map->tiles, mv->map->data[i], mv->page, x, y); + } + i += mv->map->width; + } +} diff --git a/16/modex16/scroll.exe b/16/modex16/scroll.exe new file mode 100755 index 00000000..23762520 Binary files /dev/null and b/16/modex16/scroll.exe differ diff --git a/16/modex16/test.c b/16/modex16/test.c new file mode 100755 index 00000000..c5b9d7dc --- /dev/null +++ b/16/modex16/test.c @@ -0,0 +1,75 @@ +#include "modex16.h" +#include <stdio.h> + +word far* clock= (word far*) 0x046C; /* 18.2hz clock */ + +void main() { + int i, j; + word start, end; + page_t page, page2; + byte *pal, *pal2=NULL; + + /* load our palette */ + modexLoadPalFile("gfx.pal", &pal2); + + /* save the palette */ + pal = modexNewPal(); + modexPalSave(pal); + modexFadeOff(1, pal); + modexPalBlack(); + + modexEnter(); + modexPalBlack(); + + /* set up the page, but with 16 pixels on all borders in offscreen mem */ + page=modexDefaultPage(); + page2 = modexNextPage(&page); + page.width += 32; + page.height += 32; + + + /* fill the page with one color, but with a black border */ + modexShowPage(&page2); + modexClearRegion(&page, 16, 16, SCREEN_WIDTH, SCREEN_HEIGHT, 128); + modexClearRegion(&page, 32, 32, SCREEN_WIDTH-32, SCREEN_HEIGHT-32, 42); + modexClearRegion(&page, 48, 48, SCREEN_WIDTH-64, SCREEN_HEIGHT-64, 128); + modexShowPage(&page); + + /* fade in */ + modexFadeOn(1, pal2); + + + start = *clock; + for(i=0; i<5; i++) { + /* go right */ + for(j=0; j<32; j++) { + page.dx++; + modexShowPage(&page); + } + /* go left */ + for(j=0; j<32; j++) { + page.dx--; + modexShowPage(&page); + } + /* go up */ + for(j=0; j<32; j++) { + page.dy++; + modexShowPage(&page); + } + + /* go down */ + for(j=0; j<32; j++) { + page.dy--; + modexShowPage(&page); + } + } + + end = *clock; + + /* fade back to text mode */ + modexFadeOff(1, pal2); + modexPalBlack(); + modexLeave(); + modexPalBlack(); + modexFadeOn(1, pal); +} diff --git a/16/modex16/test.exe b/16/modex16/test.exe new file mode 100755 index 00000000..99404b1a Binary files /dev/null and b/16/modex16/test.exe differ diff --git a/16/modex16/test.txt b/16/modex16/test.txt new file mode 100755 index 00000000..05adc9ec --- /dev/null +++ b/16/modex16/test.txt @@ -0,0 +1,258 @@ +64 x 64 Pixels + +0 0 0 +20 0 0 +0 20 0 +20 20 0 +0 0 20 +20 0 20 +0 20 20 +30 30 30 +30 37 30 +29 32 3c +3f 3f 33 +3f 3f 26 +3f 3f 19 +3f 3f c +3f 33 3f +3f 33 33 +3f 33 26 +3f 33 19 +3f 33 c +3f 33 0 +3f 26 3f +3f 26 33 +3f 26 26 +3f 26 19 +3f 26 c +3f 26 0 +3f 19 3f +3f 19 33 +3f 19 26 +3f 19 19 +3f 19 c +3f 19 0 +3f c 3f +3f c 33 +3f c 26 +3f c 19 +3f c c +3f c 0 +3f 0 33 +3f 0 26 +3f 0 19 +3f 0 c +33 3f 3f +33 3f 33 +33 3f 26 +33 3f 19 +33 3f c +33 3f 0 +33 33 3f +33 33 33 +33 33 26 +33 33 19 +33 33 c +33 33 0 +33 26 3f +33 26 33 +33 26 26 +33 26 19 +33 26 c +33 26 0 +33 19 3f +33 19 33 +33 19 26 +33 19 19 +33 19 c +33 19 0 +33 c 3f +33 c 33 +33 c 26 +33 c 19 +33 c c +33 c 0 +33 0 3f +33 0 33 +33 0 26 +33 0 19 +33 0 c +33 0 0 +26 3f 3f +26 3f 33 +26 3f 26 +26 3f 19 +26 3f c +26 3f 0 +26 33 3f +26 33 33 +26 33 26 +26 33 19 +26 33 c +26 33 0 +26 26 3f +26 26 33 +26 26 26 +26 26 19 +26 26 c +26 26 0 +26 19 3f +26 19 33 +26 19 26 +26 19 19 +26 19 c +26 19 0 +26 c 3f +26 c 33 +26 c 26 +26 c 19 +26 c c +26 c 0 +26 0 3f +26 0 33 +26 0 26 +26 0 19 +26 0 c +26 0 0 +19 3f 3f +19 3f 33 +19 3f 26 +19 3f 19 +19 3f c +19 3f 0 +19 33 3f +19 33 33 +19 33 26 +19 33 19 +19 33 c +19 33 0 +19 26 3f +19 26 33 +19 26 26 +19 26 19 +19 26 c +19 26 0 +19 19 3f +19 19 33 +19 19 26 +19 19 19 +19 19 c +19 19 0 +19 c 3f +19 c 33 +19 c 26 +19 c 19 +19 c c +19 c 0 +19 0 3f +19 0 33 +19 0 26 +19 0 19 +19 0 c +19 0 0 +c 3f 3f +c 3f 33 +c 3f 26 +c 3f 19 +c 3f c +c 3f 0 +c 33 3f +c 33 33 +c 33 26 +c 33 19 +c 33 c +c 33 0 +c 26 3f +c 26 33 +c 26 26 +c 26 19 +c 26 c +c 26 0 +c 19 3f +c 19 33 +c 19 26 +c 19 19 +c 19 c +c 19 0 +c c 3f +c c 33 +c c 26 +c c 19 +c c c +c c 0 +c 0 3f +c 0 33 +c 0 26 +c 0 19 +c 0 c +c 0 0 +0 3f 33 +0 3f 26 +0 3f 19 +0 3f c +0 33 3f +0 33 33 +0 33 26 +0 33 19 +0 33 c +0 33 0 +0 26 3f +0 26 33 +0 26 26 +0 26 19 +0 26 c +0 26 0 +0 19 3f +0 19 33 +0 19 26 +0 19 19 +0 19 c +0 19 0 +0 c 3f +0 c 33 +0 c 26 +0 c 19 +0 c c +0 c 0 +0 0 33 +0 0 26 +0 0 19 +0 0 c +20 3f 3f +10 20 20 +20 3f 0 +10 10 0 +3f 3f 20 +3f 20 0 +3f 20 20 +20 10 0 +20 0 3f +20 0 10 +10 20 3f +0 10 20 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +3f 3e 3c +28 28 29 +20 20 20 +3f 0 0 +0 3f 0 +3f 3f 0 +0 0 3f +3f 0 3f +0 3f 3f +3f 3f 3f \ No newline at end of file diff --git a/16/modex16/test2.c b/16/modex16/test2.c new file mode 100755 index 00000000..9118279f --- /dev/null +++ b/16/modex16/test2.c @@ -0,0 +1,19 @@ +#include "modex16.h" + +word far* clock= (word far*) 0x046C; /* 18.2hz clock */ + +void main() { + int i; + word start; + page_t page; + + page=modexDefaultPage(); + + modexEnter(); + start = *clock; + for(i=0; i<500; i++) { + modexShowPage(&page); + } + modexLeave(); + +} diff --git a/16/modex16/test2.exe b/16/modex16/test2.exe new file mode 100755 index 00000000..2b870eff Binary files /dev/null and b/16/modex16/test2.exe differ diff --git a/16/modex16/types.h b/16/modex16/types.h new file mode 100755 index 00000000..039653f2 --- /dev/null +++ b/16/modex16/types.h @@ -0,0 +1,11 @@ +/* + * Just some handy typedefs that make it easier to think about the low + * level code + */ + +typedef unsigned char byte; +typedef unsigned short word; +typedef unsigned long dword; +typedef signed char sbyte; +typedef signed short sword; +typedef signed long sdword; diff --git a/16/modex16/w.pcx b/16/modex16/w.pcx new file mode 100755 index 00000000..ad808796 Binary files /dev/null and b/16/modex16/w.pcx differ diff --git a/src/0croll.c b/src/0croll.c index 3a91e173..4ea630f8 100755 --- a/src/0croll.c +++ b/src/0croll.c @@ -1,4 +1,4 @@ -//from https://github.com/sparky4/16/commit/a19d7592507e5f7aa91f4a6b6611e021bd1a3e8d +//from https://github.com/sparky4/16/commit/7872dbf5d0240f01177588bd7966c3e042ced554 #include "16/src/lib/omodex16.h" #include "16/src/lib/bitmap.h" #include <stdio.h>