mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2025-02-16 17:30:27 +00:00
Raster/VectorVideo classes; aclib.[ch]
This commit is contained in:
parent
4e77088ca1
commit
1e5b2dcab8
@ -73,19 +73,17 @@ TODO:
|
||||
- granular control over time scrubbing, show CPU state
|
||||
- error showing replay div before rom starts
|
||||
- compiler flags for final ROM build
|
||||
- coleco sprites need brev
|
||||
- workermain: split build functions, better msg types
|
||||
- vcs: INPTx needs to be added to control state
|
||||
- rename, delete, save as
|
||||
- sdcc: can't link asm files before c files
|
||||
- what if >1 file with same name? (local/nonlocal/directory)
|
||||
- can't upload files already exist
|
||||
- upload files w/o new project
|
||||
- what if .c and .s names collide?
|
||||
- live coding URL
|
||||
- memory viewer: ROM/RAM/VRAM/etc
|
||||
- resize memory browser when split resize
|
||||
- preroll the emulator so optimizer does its thing before loading rom
|
||||
- wasm dynamic linking of emulators (https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md)
|
||||
|
||||
|
||||
WEB WORKER FORMAT
|
||||
|
128
presets/astrocade/aclib.c
Normal file
128
presets/astrocade/aclib.c
Normal file
@ -0,0 +1,128 @@
|
||||
|
||||
#include <string.h>
|
||||
#include "aclib.h"
|
||||
|
||||
#define EXIT_CLIPDEST(addr) if ((((word)addr)&0xfff) >= 0xe10) return
|
||||
|
||||
// clear screen and set graphics mode
|
||||
void clrscr() {
|
||||
memset(vidmem, 0, VHEIGHT*VBWIDTH); // clear page 1
|
||||
}
|
||||
|
||||
// draw vertical line
|
||||
void vline(byte x, byte y1, byte y2, byte col, byte op) {
|
||||
byte xb = x>>2; // divide x by 4
|
||||
byte* dest = &vmagic[y1][xb]; // destination address
|
||||
byte y;
|
||||
hw_magic = M_SHIFT(x) | op; // set magic register
|
||||
col <<= 6; // put color in high pixel
|
||||
for (y=y1; y<=y2; y++) {
|
||||
EXIT_CLIPDEST(dest);
|
||||
*dest = col; // shift + xor color
|
||||
dest += VBWIDTH; // dest address to next scanline
|
||||
}
|
||||
}
|
||||
|
||||
// draw a pixel
|
||||
void pixel(byte x, byte y, byte col, byte op) {
|
||||
vline(x, y, y, col, op); // draw line with 1-pixel height
|
||||
}
|
||||
|
||||
// render a sprite with the given graphics operation
|
||||
void render_sprite(const byte* src, byte x, byte y, byte op) {
|
||||
byte i,j;
|
||||
byte w = *src++; // get width from 1st byte of sprite
|
||||
byte h = *src++; // get height from 2nd byte of sprite
|
||||
byte xb = x>>2; // divide x by 4
|
||||
byte* dest = &vmagic[y][xb]; // destination address
|
||||
hw_magic = M_SHIFT(x) | op; // set magic register
|
||||
for (j=0; j<h; j++) {
|
||||
EXIT_CLIPDEST(dest);
|
||||
for (i=0; i<w; i++) {
|
||||
*dest++ = *src++;
|
||||
}
|
||||
*dest = 0; // rest of shifted byte
|
||||
dest += VBWIDTH-w; // dest address to next scanline
|
||||
}
|
||||
}
|
||||
|
||||
// erase a sprite
|
||||
void erase_sprite(const byte* src, byte x, byte y) {
|
||||
byte i,j;
|
||||
byte w = *src++; // get width from 1st byte of sprite
|
||||
byte h = *src++; // get height from 2nd byte of sprite
|
||||
byte xb = x>>2; // divide x by 4
|
||||
byte* dest = &vidmem[y][xb]; // destination address
|
||||
for (j=0; j<h; j++) {
|
||||
EXIT_CLIPDEST(dest);
|
||||
for (i=0; i<w; i++) {
|
||||
*dest++ = 0;
|
||||
}
|
||||
*dest = 0; // rest of shifted byte
|
||||
dest += VBWIDTH-w; // dest address to next scanline
|
||||
}
|
||||
}
|
||||
|
||||
// FONT FUNCTIONS
|
||||
|
||||
const char FONT[HICHAR-LOCHAR+1][FONT_HEIGHT*FONT_BWIDTH] = {
|
||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, },{ 0x00,0x00,0x00,0x20,0x20,0x20,0x00,0x20, },{ 0x00,0x00,0x50,0x50,0x50,0x00,0x00,0x00, },{ 0x00,0x00,0x00,0x50,0xF8,0x50,0xF8,0x50, },{ 0x00,0x00,0x00,0xF8,0xA0,0xF8,0x28,0xF8, },{ 0x00,0x00,0x00,0xC8,0xD0,0x20,0x58,0x98, },{ 0x00,0x00,0x00,0xE0,0xA8,0xF8,0x90,0xF8, },{ 0x00,0x00,0x40,0x40,0x40,0x00,0x00,0x00, },{ 0x00,0x00,0x30,0x20,0x20,0x20,0x20,0x20, },{ 0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x20, },{ 0x00,0x00,0x00,0x20,0xA8,0x70,0xA8,0x20, },{ 0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20, },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60, },{ 0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00, },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60, },{ 0x00,0x00,0x00,0x08,0x10,0x20,0x40,0x80, },{ 0x00,0x00,0x00,0xF8,0x88,0xE8,0x88,0xF8, },{ 0x00,0x00,0x00,0x10,0x30,0x50,0x10,0x10, },{ 0x00,0x00,0x00,0xF8,0x08,0xF8,0x80,0xF8, },{ 0x00,0x00,0x00,0xF8,0x08,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0x38,0x48,0x88,0xF8,0x08, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x08,0x10,0x20,0x40, },{ 0x00,0x00,0x00,0xF8,0x88,0xF8,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x88,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0x30,0x30,0x00,0x30,0x30, },{ 0x00,0x00,0x00,0x30,0x30,0x00,0x30,0x30, },{ 0x00,0x00,0x08,0x10,0x20,0x40,0x20,0x10, },{ 0x00,0x00,0x00,0x00,0xF8,0x00,0xF8,0x00, },{ 0x00,0x00,0x40,0x20,0x10,0x08,0x10,0x20, },{ 0x00,0x00,0x00,0xF8,0x08,0x78,0x00,0x60, },{ 0x00,0x00,0x00,0xF8,0xA8,0xB8,0x80,0xF8, },{ 0x00,0x00,0x00,0xF8,0x88,0xF8,0x88,0x88, },{ 0x00,0x00,0x00,0xF0,0x90,0xF8,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0x80,0x80,0xF8, },{ 0x00,0x00,0x00,0xE0,0x90,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x80,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x80,0x80, },{ 0x00,0x00,0x00,0xF8,0x80,0xB8,0x88,0xF8, },{ 0x00,0x00,0x00,0x88,0x88,0xF8,0x88,0x88, },{ 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40, },{ 0x00,0x00,0x00,0x08,0x08,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0x88,0x90,0xA0,0x90,0x88, },{ 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0xF8, },{ 0x00,0x00,0x00,0xFE,0x92,0x92,0x92,0x92, },{ 0x00,0x00,0x00,0x88,0xC8,0xA8,0x98,0x88, },{ 0x00,0x00,0x00,0xF8,0x88,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x88,0x88,0xF8,0x80, },{ 0x00,0x00,0x00,0xF8,0x88,0xA8,0xA8,0xF8, },{ 0x00,0x00,0x00,0xF8,0x88,0xF8,0x90,0x88, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0xF8,0x20,0x20,0x20,0x20, },{ 0x00,0x00,0x00,0x88,0x88,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0x88,0x88,0x90,0xA0,0xC0, },{ 0x00,0x00,0x00,0x92,0x92,0x92,0x92,0xFE, },{ 0x00,0x00,0x00,0x88,0x50,0x20,0x50,0x88, },{ 0x00,0x00,0x00,0x88,0x88,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0xF8,0x10,0x20,0x40,0xF8, },{ 0x00,0x00,0x38,0x20,0x20,0x20,0x20,0x20, },{ 0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x08, },{ 0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10, },{ 0x00,0x00,0x00,0x20,0x50,0x88,0x00,0x00, },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, },{ 0x00,0x00,0x40,0x20,0x10,0x00,0x00,0x00, },{ 0x00,0x00,0x00,0xF8,0x88,0xF8,0x88,0x88, },{ 0x00,0x00,0x00,0xF0,0x90,0xF8,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0x80,0x80,0xF8, },{ 0x00,0x00,0x00,0xE0,0x90,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x80,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x80,0x80, },{ 0x00,0x00,0x00,0xF8,0x80,0xB8,0x88,0xF8, },{ 0x00,0x00,0x00,0x88,0x88,0xF8,0x88,0x88, },{ 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40, },{ 0x00,0x00,0x00,0x08,0x08,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0x88,0x90,0xA0,0x90,0x88, },{ 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0xF8, },{ 0x00,0x00,0x00,0xFE,0x92,0x92,0x92,0x92, },{ 0x00,0x00,0x00,0x88,0xC8,0xA8,0x98,0x88, },{ 0x00,0x00,0x00,0xF8,0x88,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x88,0x88,0xF8,0x80, },{ 0x00,0x00,0x00,0xF8,0x88,0xA8,0xA8,0xF8, },{ 0x00,0x00,0x00,0xF8,0x88,0xF8,0x90,0x88, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0xF8,0x20,0x20,0x20,0x20, },{ 0x00,0x00,0x00,0x88,0x88,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0x88,0x88,0x90,0xA0,0xC0, },{ 0x00,0x00,0x00,0x92,0x92,0x92,0x92,0xFE, },{ 0x00,0x00,0x00,0x88,0x50,0x20,0x50,0x88, },{ 0x00,0x00,0x00,0x88,0x88,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0xF8,0x10,0x20,0x40,0xF8, },{ 0x00,0x00,0x38,0x20,0x20,0xE0,0x20,0x20, },{ 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20, },{ 0x00,0x00,0xE0,0x20,0x20,0x38,0x20,0x20, },{ 0x00,0x00,0x00,0xE8,0xB8,0x00,0x00,0x00, },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, },};
|
||||
|
||||
// draw a letter
|
||||
void draw_char(byte ch, byte x, byte y, byte op) {
|
||||
const byte* src = &FONT[(ch-LOCHAR)][0];
|
||||
byte xb = x>>2; // divide x by 4
|
||||
byte* dest = &vmagic[y][xb]; // destination address
|
||||
hw_magic = M_SHIFT(x) | M_XPAND | op;
|
||||
for (byte i=0; i<8; i++) {
|
||||
char b = *src++;
|
||||
EXIT_CLIPDEST(dest);
|
||||
*dest++ = b; // expand lower nibble -> 1st byte
|
||||
*dest++ = b; // expand upper nibble -> 2nd byte
|
||||
*dest++ = 0; // leftover -> 3rd byte
|
||||
*dest = 0; // reset upper/lower flag
|
||||
dest += VBWIDTH-3; // we incremented 3 bytes for this line
|
||||
}
|
||||
}
|
||||
|
||||
void draw_string(const char* str, byte x, byte y) {
|
||||
do {
|
||||
byte ch = *str++;
|
||||
if (!ch) break;
|
||||
draw_char(ch, x, y, M_MOVE);
|
||||
x += 8;
|
||||
} while (1);
|
||||
}
|
||||
|
||||
void draw_bcd_word(word bcd, byte x, byte y, byte op) {
|
||||
byte j;
|
||||
x += 3*8;
|
||||
for (j=0; j<4; j++) {
|
||||
draw_char('0'+(bcd&0xf), x, y, op);
|
||||
x -= 8;
|
||||
bcd >>= 4;
|
||||
}
|
||||
}
|
||||
|
||||
// add two 16-bit BCD values
|
||||
word bcd_add(word a, word b) {
|
||||
a; b; // to avoid warning
|
||||
__asm
|
||||
ld hl,#4
|
||||
add hl,sp
|
||||
ld iy,#2
|
||||
add iy,sp
|
||||
ld a,0 (iy)
|
||||
add a, (hl)
|
||||
daa
|
||||
ld c,a
|
||||
ld a,1 (iy)
|
||||
inc hl
|
||||
adc a, (hl)
|
||||
daa
|
||||
ld b,a
|
||||
ld l, c
|
||||
ld h, b
|
||||
__endasm;
|
||||
}
|
||||
|
68
presets/astrocade/aclib.h
Normal file
68
presets/astrocade/aclib.h
Normal file
@ -0,0 +1,68 @@
|
||||
|
||||
#ifndef _ACLIB_H
|
||||
#define _ACLIB_H
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef signed char sbyte;
|
||||
typedef unsigned short word;
|
||||
|
||||
/// HARDWARE
|
||||
|
||||
__sfr __at(0x00) hw_col0r; // palette 0
|
||||
__sfr __at(0x01) hw_col1r;
|
||||
__sfr __at(0x02) hw_col2r;
|
||||
__sfr __at(0x03) hw_col3r;
|
||||
__sfr __at(0x04) hw_col0l;
|
||||
__sfr __at(0x05) hw_col1l;
|
||||
__sfr __at(0x06) hw_col2l;
|
||||
__sfr __at(0x07) hw_col3l; // palette 7
|
||||
|
||||
__sfr __at(0x09) hw_horcb; // horiz color boundary
|
||||
__sfr __at(0x0a) hw_verbl; // vertical blanking line * 2
|
||||
__sfr __at(0x0c) hw_magic; // magic register
|
||||
__sfr __at(0x19) hw_xpand; // expander register
|
||||
|
||||
__sfr __at(0x08) hw_intst; // intercept test feedback
|
||||
|
||||
__sfr __at(0x10) hw_p1ctrl; // player controls
|
||||
__sfr __at(0x11) hw_p2ctrl; // player controls
|
||||
__sfr __at(0x12) hw_p3ctrl; // player controls
|
||||
__sfr __at(0x13) hw_p4ctrl; // player controls
|
||||
|
||||
#define M_SHIFT0 0x00
|
||||
#define M_SHIFT1 0x01
|
||||
#define M_SHIFT2 0x02
|
||||
#define M_SHIFT3 0x03
|
||||
#define M_XPAND 0x08
|
||||
#define M_MOVE 0x00
|
||||
#define M_OR 0x10
|
||||
#define M_XOR 0x20
|
||||
#define M_FLOP 0x40
|
||||
#define M_SHIFT(x) ((x)&3)
|
||||
#define XPAND_COLORS(off,on) (((off)&3) | (((on)&3)<<2))
|
||||
|
||||
#define VHEIGHT 89 // number of scanlines
|
||||
#define VBWIDTH 40 // number of bytes per scanline
|
||||
#define PIXWIDTH 160 // 4 pixels per byte
|
||||
|
||||
byte __at (0x0000) vmagic[VHEIGHT][VBWIDTH];
|
||||
byte __at (0x4000) vidmem[VHEIGHT][VBWIDTH];
|
||||
|
||||
#define LOCHAR 32
|
||||
#define HICHAR 127
|
||||
#define FONT_BWIDTH 1
|
||||
#define FONT_HEIGHT 8
|
||||
|
||||
/// GRAPHICS FUNCTIONS
|
||||
|
||||
void clrscr();
|
||||
void vline(byte x, byte y1, byte y2, byte col, byte op);
|
||||
void pixel(byte x, byte y, byte col, byte op);
|
||||
void render_sprite(const byte* src, byte x, byte y, byte op);
|
||||
void erase_sprite(const byte* src, byte x, byte y);
|
||||
void draw_char(byte ch, byte x, byte y, byte op);
|
||||
void draw_string(const char* str, byte x, byte y);
|
||||
void draw_bcd_word(word bcd, byte x, byte y, byte op);
|
||||
word bcd_add(word a, word b);
|
||||
|
||||
#endif
|
@ -1,192 +1,18 @@
|
||||
|
||||
|
||||
/*
|
||||
* An Astrocade port of the Cosmic Impalas game
|
||||
* described in the book
|
||||
* "Making 8-bit Arcade Games in C"
|
||||
*/
|
||||
|
||||
//#link "acheader.s"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define EXIT_CLIPY(y) if (((unsigned char)y)>=VHEIGHT) return
|
||||
#define EXIT_CLIPDEST(addr) if ((((word)addr)&0xfff) >= 0xe10) return
|
||||
#include "aclib.h"
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef signed char sbyte;
|
||||
typedef unsigned short word;
|
||||
//#link "aclib.c"
|
||||
|
||||
/// HARDWARE
|
||||
//#link "acheader.s"
|
||||
|
||||
__sfr __at(0x00) hw_col0r; // palette 0
|
||||
__sfr __at(0x01) hw_col1r;
|
||||
__sfr __at(0x02) hw_col2r;
|
||||
__sfr __at(0x03) hw_col3r;
|
||||
__sfr __at(0x04) hw_col0l;
|
||||
__sfr __at(0x05) hw_col1l;
|
||||
__sfr __at(0x06) hw_col2l;
|
||||
__sfr __at(0x07) hw_col3l; // palette 7
|
||||
|
||||
__sfr __at(0x09) hw_horcb; // horiz color boundary
|
||||
__sfr __at(0x0a) hw_verbl; // vertical blanking line * 2
|
||||
__sfr __at(0x0c) hw_magic; // magic register
|
||||
__sfr __at(0x19) hw_xpand; // expander register
|
||||
|
||||
__sfr __at(0x08) hw_intst; // intercept test feedback
|
||||
|
||||
__sfr __at(0x10) hw_p1ctrl; // player controls
|
||||
__sfr __at(0x11) hw_p2ctrl; // player controls
|
||||
__sfr __at(0x12) hw_p3ctrl; // player controls
|
||||
__sfr __at(0x13) hw_p4ctrl; // player controls
|
||||
|
||||
#define M_SHIFT0 0x00
|
||||
#define M_SHIFT1 0x01
|
||||
#define M_SHIFT2 0x02
|
||||
#define M_SHIFT3 0x03
|
||||
#define M_XPAND 0x08
|
||||
#define M_MOVE 0x00
|
||||
#define M_OR 0x10
|
||||
#define M_XOR 0x20
|
||||
#define M_FLOP 0x40
|
||||
#define M_SHIFT(x) ((x)&3)
|
||||
#define XPAND_COLORS(off,on) (((off)&3) | (((on)&3)<<2))
|
||||
|
||||
/// GRAPHICS FUNCTIONS
|
||||
|
||||
#define VHEIGHT 89 // number of scanlines
|
||||
#define VBWIDTH 40 // number of bytes per scanline
|
||||
#define PIXWIDTH 160 // 4 pixels per byte
|
||||
|
||||
byte __at (0x0000) vmagic[VHEIGHT][VBWIDTH];
|
||||
byte __at (0x4000) vidmem[VHEIGHT][VBWIDTH];
|
||||
|
||||
// clear screen and set graphics mode
|
||||
void clrscr() {
|
||||
memset(vidmem, 0, VHEIGHT*VBWIDTH); // clear page 1
|
||||
}
|
||||
|
||||
// draw vertical line
|
||||
void vline(byte x, byte y1, byte y2, byte col, byte op) {
|
||||
byte xb = x>>2; // divide x by 4
|
||||
byte* dest = &vmagic[y1][xb]; // destination address
|
||||
byte y;
|
||||
hw_magic = M_SHIFT(x) | op; // set magic register
|
||||
col <<= 6; // put color in high pixel
|
||||
for (y=y1; y<=y2; y++) {
|
||||
EXIT_CLIPDEST(dest);
|
||||
*dest = col; // shift + xor color
|
||||
dest += VBWIDTH; // dest address to next scanline
|
||||
}
|
||||
}
|
||||
|
||||
// draw a pixel
|
||||
void pixel(byte x, byte y, byte col, byte op) {
|
||||
vline(x, y, y, col, op); // draw line with 1-pixel height
|
||||
}
|
||||
|
||||
// render a sprite with the given graphics operation
|
||||
void render_sprite(const byte* src, byte x, byte y, byte op) {
|
||||
byte i,j;
|
||||
byte w = *src++; // get width from 1st byte of sprite
|
||||
byte h = *src++; // get height from 2nd byte of sprite
|
||||
byte xb = x>>2; // divide x by 4
|
||||
byte* dest = &vmagic[y][xb]; // destination address
|
||||
hw_magic = M_SHIFT(x) | op; // set magic register
|
||||
for (j=0; j<h; j++) {
|
||||
EXIT_CLIPDEST(dest);
|
||||
for (i=0; i<w; i++) {
|
||||
*dest++ = *src++;
|
||||
}
|
||||
*dest = 0; // rest of shifted byte
|
||||
dest += VBWIDTH-w; // dest address to next scanline
|
||||
}
|
||||
}
|
||||
|
||||
// erase a sprite
|
||||
void erase_sprite(const byte* src, byte x, byte y) {
|
||||
byte i,j;
|
||||
byte w = *src++; // get width from 1st byte of sprite
|
||||
byte h = *src++; // get height from 2nd byte of sprite
|
||||
byte xb = x>>2; // divide x by 4
|
||||
byte* dest = &vidmem[y][xb]; // destination address
|
||||
for (j=0; j<h; j++) {
|
||||
EXIT_CLIPDEST(dest);
|
||||
for (i=0; i<w; i++) {
|
||||
*dest++ = 0;
|
||||
}
|
||||
*dest = 0; // rest of shifted byte
|
||||
dest += VBWIDTH-w; // dest address to next scanline
|
||||
}
|
||||
}
|
||||
|
||||
// FONT FUNCTIONS
|
||||
|
||||
#define LOCHAR 32
|
||||
#define HICHAR 127
|
||||
#define FONT_BWIDTH 1
|
||||
#define FONT_HEIGHT 8
|
||||
const char FONT[HICHAR-LOCHAR+1][FONT_HEIGHT*FONT_BWIDTH] = {
|
||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, },{ 0x00,0x00,0x00,0x20,0x20,0x20,0x00,0x20, },{ 0x00,0x00,0x50,0x50,0x50,0x00,0x00,0x00, },{ 0x00,0x00,0x00,0x50,0xF8,0x50,0xF8,0x50, },{ 0x00,0x00,0x00,0xF8,0xA0,0xF8,0x28,0xF8, },{ 0x00,0x00,0x00,0xC8,0xD0,0x20,0x58,0x98, },{ 0x00,0x00,0x00,0xE0,0xA8,0xF8,0x90,0xF8, },{ 0x00,0x00,0x40,0x40,0x40,0x00,0x00,0x00, },{ 0x00,0x00,0x30,0x20,0x20,0x20,0x20,0x20, },{ 0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x20, },{ 0x00,0x00,0x00,0x20,0xA8,0x70,0xA8,0x20, },{ 0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20, },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60, },{ 0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00, },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60, },{ 0x00,0x00,0x00,0x08,0x10,0x20,0x40,0x80, },{ 0x00,0x00,0x00,0xF8,0x88,0xE8,0x88,0xF8, },{ 0x00,0x00,0x00,0x10,0x30,0x50,0x10,0x10, },{ 0x00,0x00,0x00,0xF8,0x08,0xF8,0x80,0xF8, },{ 0x00,0x00,0x00,0xF8,0x08,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0x38,0x48,0x88,0xF8,0x08, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x08,0x10,0x20,0x40, },{ 0x00,0x00,0x00,0xF8,0x88,0xF8,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x88,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0x30,0x30,0x00,0x30,0x30, },{ 0x00,0x00,0x00,0x30,0x30,0x00,0x30,0x30, },{ 0x00,0x00,0x08,0x10,0x20,0x40,0x20,0x10, },{ 0x00,0x00,0x00,0x00,0xF8,0x00,0xF8,0x00, },{ 0x00,0x00,0x40,0x20,0x10,0x08,0x10,0x20, },{ 0x00,0x00,0x00,0xF8,0x08,0x78,0x00,0x60, },{ 0x00,0x00,0x00,0xF8,0xA8,0xB8,0x80,0xF8, },{ 0x00,0x00,0x00,0xF8,0x88,0xF8,0x88,0x88, },{ 0x00,0x00,0x00,0xF0,0x90,0xF8,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0x80,0x80,0xF8, },{ 0x00,0x00,0x00,0xE0,0x90,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x80,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x80,0x80, },{ 0x00,0x00,0x00,0xF8,0x80,0xB8,0x88,0xF8, },{ 0x00,0x00,0x00,0x88,0x88,0xF8,0x88,0x88, },{ 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40, },{ 0x00,0x00,0x00,0x08,0x08,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0x88,0x90,0xA0,0x90,0x88, },{ 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0xF8, },{ 0x00,0x00,0x00,0xFE,0x92,0x92,0x92,0x92, },{ 0x00,0x00,0x00,0x88,0xC8,0xA8,0x98,0x88, },{ 0x00,0x00,0x00,0xF8,0x88,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x88,0x88,0xF8,0x80, },{ 0x00,0x00,0x00,0xF8,0x88,0xA8,0xA8,0xF8, },{ 0x00,0x00,0x00,0xF8,0x88,0xF8,0x90,0x88, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0xF8,0x20,0x20,0x20,0x20, },{ 0x00,0x00,0x00,0x88,0x88,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0x88,0x88,0x90,0xA0,0xC0, },{ 0x00,0x00,0x00,0x92,0x92,0x92,0x92,0xFE, },{ 0x00,0x00,0x00,0x88,0x50,0x20,0x50,0x88, },{ 0x00,0x00,0x00,0x88,0x88,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0xF8,0x10,0x20,0x40,0xF8, },{ 0x00,0x00,0x38,0x20,0x20,0x20,0x20,0x20, },{ 0x00,0x00,0x00,0x80,0x40,0x20,0x10,0x08, },{ 0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10, },{ 0x00,0x00,0x00,0x20,0x50,0x88,0x00,0x00, },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, },{ 0x00,0x00,0x40,0x20,0x10,0x00,0x00,0x00, },{ 0x00,0x00,0x00,0xF8,0x88,0xF8,0x88,0x88, },{ 0x00,0x00,0x00,0xF0,0x90,0xF8,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0x80,0x80,0xF8, },{ 0x00,0x00,0x00,0xE0,0x90,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x80,0xF8, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x80,0x80, },{ 0x00,0x00,0x00,0xF8,0x80,0xB8,0x88,0xF8, },{ 0x00,0x00,0x00,0x88,0x88,0xF8,0x88,0x88, },{ 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40, },{ 0x00,0x00,0x00,0x08,0x08,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0x88,0x90,0xA0,0x90,0x88, },{ 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0xF8, },{ 0x00,0x00,0x00,0xFE,0x92,0x92,0x92,0x92, },{ 0x00,0x00,0x00,0x88,0xC8,0xA8,0x98,0x88, },{ 0x00,0x00,0x00,0xF8,0x88,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0xF8,0x88,0x88,0xF8,0x80, },{ 0x00,0x00,0x00,0xF8,0x88,0xA8,0xA8,0xF8, },{ 0x00,0x00,0x00,0xF8,0x88,0xF8,0x90,0x88, },{ 0x00,0x00,0x00,0xF8,0x80,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0xF8,0x20,0x20,0x20,0x20, },{ 0x00,0x00,0x00,0x88,0x88,0x88,0x88,0xF8, },{ 0x00,0x00,0x00,0x88,0x88,0x90,0xA0,0xC0, },{ 0x00,0x00,0x00,0x92,0x92,0x92,0x92,0xFE, },{ 0x00,0x00,0x00,0x88,0x50,0x20,0x50,0x88, },{ 0x00,0x00,0x00,0x88,0x88,0xF8,0x08,0xF8, },{ 0x00,0x00,0x00,0xF8,0x10,0x20,0x40,0xF8, },{ 0x00,0x00,0x38,0x20,0x20,0xE0,0x20,0x20, },{ 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20, },{ 0x00,0x00,0xE0,0x20,0x20,0x38,0x20,0x20, },{ 0x00,0x00,0x00,0xE8,0xB8,0x00,0x00,0x00, },{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, },};
|
||||
|
||||
// draw a letter
|
||||
void draw_char(byte ch, byte x, byte y, byte op) {
|
||||
const byte* src = &FONT[(ch-LOCHAR)][0];
|
||||
byte xb = x>>2; // divide x by 4
|
||||
byte* dest = &vmagic[y][xb]; // destination address
|
||||
hw_magic = M_SHIFT(x) | M_XPAND | op;
|
||||
for (byte i=0; i<8; i++) {
|
||||
char b = *src++;
|
||||
EXIT_CLIPDEST(dest);
|
||||
*dest++ = b; // expand lower nibble -> 1st byte
|
||||
*dest++ = b; // expand upper nibble -> 2nd byte
|
||||
*dest++ = 0; // leftover -> 3rd byte
|
||||
*dest = 0; // reset upper/lower flag
|
||||
dest += VBWIDTH-3; // we incremented 3 bytes for this line
|
||||
}
|
||||
}
|
||||
|
||||
void draw_string(const char* str, byte x, byte y) {
|
||||
do {
|
||||
byte ch = *str++;
|
||||
if (!ch) break;
|
||||
draw_char(ch, x, y, M_MOVE);
|
||||
x += 8;
|
||||
} while (1);
|
||||
}
|
||||
|
||||
void draw_bcd_word(word bcd, byte x, byte y, byte op) {
|
||||
byte j;
|
||||
x += 3*8;
|
||||
for (j=0; j<4; j++) {
|
||||
draw_char('0'+(bcd&0xf), x, y, op);
|
||||
x -= 8;
|
||||
bcd >>= 4;
|
||||
}
|
||||
}
|
||||
|
||||
// add two 16-bit BCD values
|
||||
word bcd_add(word a, word b) __naked {
|
||||
a; b; // to avoid warning
|
||||
__asm
|
||||
push ix
|
||||
ld ix,#0
|
||||
add ix,sp
|
||||
ld a,4 (ix)
|
||||
add a, 6 (ix)
|
||||
daa
|
||||
ld c,a
|
||||
ld a,5 (ix)
|
||||
adc a, 7 (ix)
|
||||
daa
|
||||
ld b,a
|
||||
ld l, c
|
||||
ld h, b
|
||||
pop ix
|
||||
ret
|
||||
__endasm;
|
||||
}
|
||||
|
||||
/////
|
||||
|
||||
//
|
||||
// GAME GRAPHICS
|
||||
@ -315,8 +141,8 @@ void xor_player_derez() {
|
||||
byte x = player_x+13;
|
||||
byte y = player_y+PLYRHEIGHT-1;
|
||||
byte* rand = (byte*) &clrscr; // use code as random #'s
|
||||
for (j=1; j<=0x1f; j++) {
|
||||
for (i=0; i<50; i++) {
|
||||
for (j=1; j<=0xf; j++) {
|
||||
for (i=0; i<100; i++) {
|
||||
signed char xx = x + (*rand++ & 0xf) - 15;
|
||||
signed char yy = y - (*rand++ & j);
|
||||
pixel(xx, yy, *rand++, M_XOR);
|
||||
@ -561,13 +387,9 @@ void attract_mode() {
|
||||
|
||||
void setup_registers() {
|
||||
hw_col0r = 0x00;
|
||||
hw_col1r = 0x20;
|
||||
hw_col2r = 0xe0;
|
||||
hw_col3r = 0xa0;
|
||||
hw_col0l = 0x10;
|
||||
hw_col1l = 0x30;
|
||||
hw_col2l = 0xc0;
|
||||
hw_col3l = 0xf0;
|
||||
hw_col1r = 0x2f;
|
||||
hw_col2r = 0xef;
|
||||
hw_col3r = 0xaf;
|
||||
hw_horcb = 0;
|
||||
hw_verbl = VHEIGHT*2;
|
||||
}
|
||||
|
141
src/emu.ts
141
src/emu.ts
@ -31,7 +31,7 @@ export function setNoiseSeed(x : number) {
|
||||
|
||||
type KeyboardCallback = (which:number, charCode:number, flags:number) => void;
|
||||
|
||||
function __createCanvas(mainElement:HTMLElement, width:number, height:number) : HTMLElement {
|
||||
function __createCanvas(mainElement:HTMLElement, width:number, height:number) : HTMLCanvasElement {
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
@ -55,15 +55,33 @@ function _setKeyboardEvents(canvas:HTMLElement, callback:KeyboardCallback) {
|
||||
|
||||
type VideoCanvasOptions = {rotate?:number, overscan?:boolean};
|
||||
|
||||
export var RasterVideo = function(mainElement:HTMLElement, width:number, height:number, options?:VideoCanvasOptions) {
|
||||
var canvas, ctx;
|
||||
var imageData, arraybuf, buf8, datau32;
|
||||
var vcanvas;
|
||||
export class RasterVideo {
|
||||
|
||||
mainElement : HTMLElement;
|
||||
width : number;
|
||||
height : number;
|
||||
options : VideoCanvasOptions;
|
||||
|
||||
constructor(mainElement:HTMLElement, width:number, height:number, options?:VideoCanvasOptions) {
|
||||
this.mainElement = mainElement;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
this.paddle_x = 255;
|
||||
this.paddle_y = 255;
|
||||
canvas : HTMLCanvasElement;
|
||||
ctx;
|
||||
imageData;
|
||||
arraybuf;
|
||||
buf8;
|
||||
datau32;
|
||||
vcanvas;
|
||||
|
||||
this.setRotate = function(rotate) {
|
||||
paddle_x = 255;
|
||||
paddle_y = 255;
|
||||
|
||||
setRotate(rotate:number) {
|
||||
var canvas = this.canvas;
|
||||
if (rotate) {
|
||||
// TODO: aspect ratio?
|
||||
canvas.style.transform = "rotate("+rotate+"deg)";
|
||||
@ -75,79 +93,77 @@ export var RasterVideo = function(mainElement:HTMLElement, width:number, height:
|
||||
}
|
||||
}
|
||||
|
||||
this.create = function() {
|
||||
this.canvas = canvas = __createCanvas(mainElement, width, height);
|
||||
vcanvas = $(canvas);
|
||||
if (options && options.rotate) {
|
||||
this.setRotate(options.rotate);
|
||||
create() {
|
||||
var canvas;
|
||||
this.canvas = canvas = __createCanvas(this.mainElement, this.width, this.height);
|
||||
this.vcanvas = $(canvas);
|
||||
if (this.options && this.options.rotate) {
|
||||
this.setRotate(this.options.rotate);
|
||||
}
|
||||
if (options && options.overscan) {
|
||||
vcanvas.css('padding','0px');
|
||||
if (this.options && this.options.overscan) {
|
||||
this.vcanvas.css('padding','0px');
|
||||
}
|
||||
ctx = canvas.getContext('2d');
|
||||
imageData = ctx.createImageData(width, height);
|
||||
datau32 = new Uint32Array(imageData.data.buffer);
|
||||
this.ctx = canvas.getContext('2d');
|
||||
this.imageData = this.ctx.createImageData(this.width, this.height);
|
||||
this.datau32 = new Uint32Array(this.imageData.data.buffer);
|
||||
}
|
||||
|
||||
this.setKeyboardEvents = function(callback) {
|
||||
_setKeyboardEvents(canvas, callback);
|
||||
setKeyboardEvents(callback) {
|
||||
_setKeyboardEvents(this.canvas, callback);
|
||||
}
|
||||
|
||||
this.getFrameData = function() { return datau32; }
|
||||
getFrameData() { return this.datau32; }
|
||||
|
||||
this.getContext = function() { return ctx; }
|
||||
getContext() { return this.ctx; }
|
||||
|
||||
this.updateFrame = function(sx:number, sy:number, dx:number, dy:number, width?:number, height?:number) {
|
||||
if (width && height)
|
||||
ctx.putImageData(imageData, sx, sy, dx, dy, width, height);
|
||||
updateFrame(sx:number, sy:number, dx:number, dy:number, w?:number, h?:number) {
|
||||
if (w && h)
|
||||
this.ctx.putImageData(this.imageData, sx, sy, dx, dy, w, h);
|
||||
else
|
||||
ctx.putImageData(imageData, 0, 0);
|
||||
if (frameUpdateFunction) frameUpdateFunction(canvas);
|
||||
this.ctx.putImageData(this.imageData, 0, 0);
|
||||
if (frameUpdateFunction) frameUpdateFunction(this.canvas);
|
||||
}
|
||||
|
||||
this.setupMouseEvents = function(el? : HTMLElement) {
|
||||
if (!el) el = canvas;
|
||||
setupMouseEvents(el? : HTMLElement) {
|
||||
if (!el) el = this.canvas;
|
||||
$(el).mousemove( (e) => {
|
||||
// TODO: get coords right
|
||||
var x = e.pageX - vcanvas.offset().left;
|
||||
var y = e.pageY - vcanvas.offset().top;
|
||||
var new_x = Math.floor(x * 255 / vcanvas.width() - 20);
|
||||
var new_y = Math.floor(y * 255 / vcanvas.height() - 20);
|
||||
var x = e.pageX - this.vcanvas.offset().left;
|
||||
var y = e.pageY - this.vcanvas.offset().top;
|
||||
var new_x = Math.floor(x * 255 / this.vcanvas.width() - 20);
|
||||
var new_y = Math.floor(y * 255 / this.vcanvas.height() - 20);
|
||||
this.paddle_x = clamp(0, 255, new_x);
|
||||
this.paddle_y = clamp(0, 255, new_y);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export var VectorVideo = function(mainElement:HTMLElement, width:number, height:number) {
|
||||
var self = this;
|
||||
var canvas, ctx;
|
||||
var persistenceAlpha = 0.5;
|
||||
var jitter = 1.0;
|
||||
var gamma = 0.8;
|
||||
var sx = width/1024.0;
|
||||
var sy = height/1024.0;
|
||||
export class VectorVideo extends RasterVideo {
|
||||
|
||||
this.create = function() {
|
||||
this.canvas = canvas = __createCanvas(mainElement, width, height);
|
||||
ctx = canvas.getContext('2d');
|
||||
persistenceAlpha = 0.5;
|
||||
jitter = 1.0;
|
||||
gamma = 0.8;
|
||||
sx : number;
|
||||
sy : number;
|
||||
|
||||
create() {
|
||||
super.create();
|
||||
this.sx = this.width/1024.0;
|
||||
this.sy = this.height/1024.0;
|
||||
}
|
||||
|
||||
this.setKeyboardEvents = function(callback) {
|
||||
_setKeyboardEvents(canvas, callback);
|
||||
}
|
||||
|
||||
this.clear = function() {
|
||||
clear() {
|
||||
var ctx = this.ctx;
|
||||
ctx.globalCompositeOperation = 'source-over';
|
||||
ctx.globalAlpha = persistenceAlpha;
|
||||
ctx.globalAlpha = this.persistenceAlpha;
|
||||
ctx.fillStyle = '#000000';
|
||||
ctx.fillRect(0, 0, width, height);
|
||||
ctx.fillRect(0, 0, this.width, this.height);
|
||||
ctx.globalAlpha = 1.0;
|
||||
ctx.globalCompositeOperation = 'lighter';
|
||||
if (frameUpdateFunction) frameUpdateFunction(canvas);
|
||||
if (frameUpdateFunction) frameUpdateFunction(this.canvas);
|
||||
}
|
||||
|
||||
var COLORS = [
|
||||
COLORS = [
|
||||
'#111111',
|
||||
'#1111ff',
|
||||
'#11ff11',
|
||||
@ -158,26 +174,29 @@ export var VectorVideo = function(mainElement:HTMLElement, width:number, height:
|
||||
'#ffffff'
|
||||
];
|
||||
|
||||
this.drawLine = function(x1:number, y1:number, x2:number, y2:number, intensity:number, color:number) {
|
||||
drawLine(x1:number, y1:number, x2:number, y2:number, intensity:number, color:number) {
|
||||
var ctx = this.ctx;
|
||||
var sx = this.sx;
|
||||
var sy = this.sy;
|
||||
//console.log(x1,y1,x2,y2,intensity,color);
|
||||
if (intensity > 0) {
|
||||
// TODO: landscape vs portrait
|
||||
var alpha = Math.pow(intensity / 255.0, gamma);
|
||||
var alpha = Math.pow(intensity / 255.0, this.gamma);
|
||||
ctx.globalAlpha = alpha;
|
||||
ctx.beginPath();
|
||||
// TODO: bright dots
|
||||
var jx = jitter * (Math.random() - 0.5);
|
||||
var jy = jitter * (Math.random() - 0.5);
|
||||
var jx = this.jitter * (Math.random() - 0.5);
|
||||
var jy = this.jitter * (Math.random() - 0.5);
|
||||
x1 += jx;
|
||||
x2 += jx;
|
||||
y1 += jy;
|
||||
y2 += jy;
|
||||
ctx.moveTo(x1*sx, height-y1*sy);
|
||||
ctx.moveTo(x1*sx, this.height-y1*sy);
|
||||
if (x1 == x2 && y1 == y2)
|
||||
ctx.lineTo(x2*sx+1, height-y2*sy);
|
||||
ctx.lineTo(x2*sx+1, this.height-y2*sy);
|
||||
else
|
||||
ctx.lineTo(x2*sx, height-y2*sy);
|
||||
ctx.strokeStyle = COLORS[color & 7];
|
||||
ctx.lineTo(x2*sx, this.height-y2*sy);
|
||||
ctx.strokeStyle = this.COLORS[color & 7];
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import { ColecoVision_PRESETS } from "./coleco";
|
||||
// http://www.smspower.org/uploads/Development/sg1000.txt
|
||||
// http://www.smspower.org/uploads/Development/richard.txt
|
||||
// http://www.smspower.org/uploads/Development/msvdp-20021112.txt
|
||||
// http://www.smspower.org/uploads/Development/SN76489-20030421.txt
|
||||
|
||||
// TODO: merge w/ coleco
|
||||
export var SG1000_PRESETS = [
|
||||
|
@ -70,21 +70,26 @@ export class CodeProject {
|
||||
if (dir.length > 0 && dir != 'local') // TODO
|
||||
files.push(dir + '/' + fn);
|
||||
}
|
||||
|
||||
|
||||
parseIncludeDependencies(text:string):string[] {
|
||||
var files = [];
|
||||
var m;
|
||||
if (this.platform_id.startsWith('verilog')) {
|
||||
// include verilog includes
|
||||
var re1 = /^\s*(`include|[.]include)\s+"(.+?)"/gmi;
|
||||
var m;
|
||||
while (m = re1.exec(text)) {
|
||||
this.pushAllFiles(files, m[2]);
|
||||
}
|
||||
// include .arch (json) statements
|
||||
var re2 = /^\s*([.]arch)\s+(\w+)/gmi;
|
||||
var m;
|
||||
while (m = re2.exec(text)) {
|
||||
this.pushAllFiles(files, m[2]+".json");
|
||||
}
|
||||
// include $readmem[bh] (TODO)
|
||||
var re3 = /\b\$readmem[bh]\("(.+?)"/gmi;
|
||||
while (m = re3.exec(text)) {
|
||||
this.pushAllFiles(files, m[2]);
|
||||
}
|
||||
} else {
|
||||
// for .asm -- [.]include "file"
|
||||
// for .c -- #include "file"
|
||||
@ -98,12 +103,12 @@ export class CodeProject {
|
||||
|
||||
parseLinkDependencies(text:string):string[] {
|
||||
var files = [];
|
||||
var m;
|
||||
if (this.platform_id.startsWith('verilog')) {
|
||||
//
|
||||
} else {
|
||||
// for .c -- //#link "file" (or ;link or #link)
|
||||
var re = /^\s*([;#]|[/][/][#])link\s+"(.+?)"/gm;
|
||||
var m;
|
||||
while (m = re.exec(text)) {
|
||||
this.pushAllFiles(files, m[2]);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user