1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-05-29 15:41:29 +00:00

removed tools/, moved to new repo sehugg/8bit-tools

This commit is contained in:
Steven Hugg 2020-07-12 10:22:41 -05:00
parent 4480e217f6
commit 5fe9ec29a5
57 changed files with 2 additions and 19070 deletions

View File

@ -34,5 +34,3 @@ tsweb:
astrolibre.b64.txt: astrolibre.rom
lzg -9 $< | base64 -w 0 > $@
astdump:
clang -Xclang -ast-dump -fsyntax-only tools/galois.c

View File

@ -1,53 +0,0 @@
all: binaries
%.lzg: %
lzg -9 $< $@
binaries: scr2floyd scr2floyd_percept galois
%-pf.hex: %-pf.pbm p4_to_pfbytes.py
python p4_to_pfbytes.py $< > $@
%-48.hex: %-48.pbm p4_to_48pix.py
python p4_to_48pix.py $< > $@
%-pf.pbm: %.jpg
convert $< -resize 40x192\! -colorspace Gray -dither FloydSteinberg $@
%-48.pbm: %.jpg
convert $< -resize 48x192\! -colorspace Gray -dither FloydSteinberg $@
%.tga: %.png
convert $< -resize 192 $<.gif
convert $<.gif +dither -type palette -depth 4 -compress RLE -colors 8 -flip $@
convert $@ $@.png
%.pcx: %.png
convert $< -format raw -type palette -compress none -colors 15 +dither $@
%.rle.pcx: %.png
convert $< -format raw -type palette -compress rle -colors 15 +dither $@
%.4.pcx: %.png
convert $< -format raw -type palette -compress none -colors 4 +dither $@
ship1.pbm: ship1.png
convert ship1.png -negate -flop ship1.pbm
%.h:
cat $* | hexdump -v -e '"\n" 128/1 "0x%02x,"'
%.prom:
cat $* | hexdump -v -e '" \n defb " 32/1 "$$%02x,"' | cut -c 2-134
%.s:
cat $* | hexdump -v -e '" \n .byte " 32/1 "$$%02x,"' | cut -c 2-135
%.rot.pbm: %.pbm
convert $< -transpose -bordercolor white -border 4x4 $@
baddies-horiz.rot.pbm: baddies-horiz.png
convert $< +dither -brightness-contrast 50x50 -fill black -transpose -negate $@
convert $@ foo.png
lfsr.out: lfsrcalc.py
pypy lfsrcalc.py | sort -n > lfsr.out

View File

@ -1,24 +1,3 @@
These files have been moved to:
This directory contains 8bitworkshop tools for bitmap and
music conversion.
Requires ImageMagick (convert) and Python 2.x.
MIDI tools require Mido (pip install mido).
On Ubuntu:
$ sudo apt update
$ sudo apt install python python-pip imagemagick curl
$ sudo pip install mido
To use the tools, go to the appropriate directory and
look at the Makefile for each:
vcs/ Atari 2600/VCS
mw8080/ Midway 8080
scramble/ Galaxian/Scramble
vicdual/ VIC Dual
williams/ Williams
fonts/ Example fonts
images/ Example images
https://github.com/sehugg/8bit-tools

View File

@ -1,15 +0,0 @@
#!/usr/bin/python
import sys
out = sys.stdout
chr = open(sys.argv[1],'rb').read()
out.write('const unsigned char ARRAY[%d] = {\n' % len(chr))
for i in range(0,len(chr)):
out.write('0x%02x, ' % ord(chr[i]))
if (i & 7) == 7:
out.write('\n')
out.write('\n};\n')

View File

@ -1,15 +0,0 @@
import sys,re
inf = sys.stdin
outf = open('a.out','wb')
l = inf.readline()
while l:
l = l.strip()
if l[-1] == ',':
l = l[0:-1]
toks = re.split('[,\s]+', l)
toks = list(filter(lambda x: x[0:2]=='0x', toks))
arr = [int(x,0) for x in toks]
outf.write(bytes(arr))
l = inf.readline()

View File

@ -1,16 +0,0 @@
import os,sys,codecs
for root, dirs, files in os.walk("./presets"):
for fn in files:
path = root + '/' + fn
if fn[-1] == '~':
continue
try:
with open(path,'r') as f:
data = f.read()
if data[0] != '\n':
print((path,'no initial newline'))
except:
print((path,sys.exc_info()[0]))

View File

@ -1,14 +0,0 @@
#!/bin/sh
./scr2floyd_percept $1.tga
lzg -9 $1.CHR > $1.CHR.lzg
lzg -9 $1.CLR > $1.CLR.lzg
rm -f $1.s
echo "\t.area _CODE" >> $1.s
echo "\t.globl _msx_mode2_pattern_lzg" >> $1.s
echo "\t.globl _msx_mode2_color_lzg" >> $1.s
echo "\n_msx_mode2_pattern_lzg:" >> $1.s
cat $1.CHR.lzg | hexdump -v -e '"\n.db " 16/1 ",0x%02x"' | sed "s/n.db,/ .db /" | tail -n +3 >> $1.s
echo "\n_msx_mode2_color_lzg:" >> $1.s
cat $1.CLR.lzg | hexdump -v -e '"\n.db " 16/1 ",0x%02x"' | sed "s/n.db,/ .db /" | tail -n +3 >> $1.s

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,23 +0,0 @@
/* test of 16-bit Galois LFSR */
#include "stdio.h"
int main()
{
int n = 100;
unsigned short x = 1;
for (int i=0; i<n; i++) {
int c = x&1;
x >>= 1;
if (c) x ^= 0xd400; // 0b1101010000000000
printf("%4x\n", x);
}
for (int i=0; i<n; i++) {
int c = x&0x8000;
x <<= 1;
if (c) x ^= 0xa801;
printf("%4x\n", x);
}
return 0;
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,30 +0,0 @@
#!/usr/bin/python
MAXBITS=16
print("Period,nbits,feedback,mask")
for n in range(1,MAXBITS):
mask = (1<<n)-1
hibit = (1<<(n-1))
for i in range(0,1<<n):
for invert in [0,1]:
x = 1
seq = []
seen = set()
while x and not x in seen:
seq.append(x)
seen.add(x)
feedback = x & hibit
x = ((x << 1) & mask)
if invert:
if not feedback:
x ^= i
else:
if feedback:
x ^= i
if x:
seqindex = seq.index(x)
seqlen = len(seq) - seqindex
if seqlen>1:
print((seqlen, "#(%d,%d'%s,%d)" % (n,n,bin(i)[1:],invert), seqindex))

View File

@ -1,42 +0,0 @@
"use strict";
var BEST={}
var MAXBITS=17
//MAXBITS=12
for (var n=1; n<MAXBITS; n++) {
var mask = (1<<n)-1;
var hibit = (1<<(n-1));
for (var i=0; i < (1<<n); i++) {
for (var invert=0; invert<2; invert++) {
var x = 1;
var seq = [];
var seen = new Map();
while (x && !seen.get(x)) {
seq.push(x);
seen.set(x, true);
var feedback = (x & hibit) != 0;
x = ((x << 1) & mask);
if (invert && !feedback) x ^= i;
if (!invert && feedback) x ^= i;
}
if (x) {
var seqindex = seq.indexOf(x);
var seqlen = seq.length - seqindex;
if (seqlen > 1 && x == 1) {
if (!BEST[seqlen] || n < BEST[seqlen].n) {
BEST[seqlen] = {n:n, i:i, invert:invert};
//console.log(seqlen + "\t" + n + "\t" + i.toString(2) + "\t" + x.toString(2));
}
}
}
}
}
}
for (var seqlen in BEST) {
var b = BEST[seqlen];
console.log(seqlen+" &\t@"+b.n+"'b"+b.i.toString(2)+","+b.invert+"@ \\\\");
}

View File

@ -1,182 +0,0 @@
#!/usr/bin/python
import sys, string, math, argparse
import mido
parser = argparse.ArgumentParser()
parser.add_argument('-s', '--start', type=int, default=21, help="first MIDI note")
parser.add_argument('-n', '--num', type=int, default=21+63, help="number of notes")
parser.add_argument('-v', '--voices', type=int, default=3, help="number of voices")
parser.add_argument('-T', '--transpose', type=int, default=0, help="transpose by half-steps")
parser.add_argument('-t', '--tempo', type=int, default=48, help="tempo")
parser.add_argument('-o', '--one', action="store_true", help="one voice per channel")
parser.add_argument('-z', '--compress', action="store_true", help="compress song (experimental)")
parser.add_argument('-H', '--hex', action="store_true", help="hex output")
parser.add_argument('midifile', help="MIDI file")
parser.add_argument('midichannels', nargs='?', help="comma-separated list of MIDI channels, or -")
args = parser.parse_args()
min_note = args.start
max_note = min_note + args.num
max_voices = args.voices
one_voice_per_channel = args.one
tempo = args.tempo
compress = args.compress
transpose = args.transpose
coutput = not args.hex
# for 2600
#max_voices = 2
#coutput = 0
# for 2600 wavetable
#max_voices = 4
#one_voice_per_channel = 0
fn = args.midifile
mid = mido.MidiFile(fn)
def hex1(n):
return '%02x'%n
def hex2(n):
return '0x%02x'%n
def only_notes(s):
for ch in s:
if ord(ch) == 0xff:
return False
return True
def find_common_substrings(s):
results = {}
for l in range(64, 6, -1):
for i in range(0,len(s)-l*2):
match = s[i:i+l]
if not only_notes(match):
continue
count = 0
j = i+l
while j < len(s):
p = s.find(match, j)
if p > 0:
count += 1
j = p+l
else:
break
if count:
n = count*(l-1)-1
if not results.get(i) or n > results[i][0]:
results[i] = (n,l)
return results
def get_best_substring(ss):
best = (0,0,0)
for k,v in list(ss.items()):
if v[0] > best[2]:
best = (k,v[1],v[0])
return best
def offset2str(ofs):
return chr(ofs & 0xff) + chr((ofs >> 8) & 0xff)
#return chr(0xc0 | (ofs & 0x3f)) + chr(0xc0 | ((ofs >> 6) & 0x3f))
g_code = 0xc1
g_subs = []
def replace_substrings(s, bss):
global g_code
i,l,n = bss
count = (n+1)/(l-1)
match = s[i:i+l]
print((i,l,n,count,repr(match)))
r = s[0:i]
while i<len(s):
r += chr(g_code)
p = s.find(match,i+l)
if p < 0:
p = len(s)
r += s[i+l:p]
i = p
g_subs.append(match + chr(0xff))
g_code += 1
print((len(s), len(r)+n+l))
assert len(s) == len(r)+n+l
return r
def channels_for_track(track):
channels = set()
for msg in track:
if msg.type == 'note_on':
channels.add(msg.channel)
return list(channels)
if not args.midichannels:
print(mid)
print((mid.length, 'seconds'))
for i, track in enumerate(mid.tracks):
print(('Track {}: {} ({}) {}'.format(i, track.name, len(track), channels_for_track(track))))
#for msg in track:
# print(msg)
else:
gtime = 0
curtime = 0
nnotes = 0
nvoices = 0
curchans = 0
channels = [int(x) for x in args.midichannels.split(',')]
print ('')
print(("// %s %s" % (mid, channels)))
output = []
for msg in mid:
gtime += msg.time * tempo
if msg.type == 'note_on' and msg.channel in channels:
note = msg.note + transpose
vel = msg.velocity
t = int(math.ceil(gtime))
if vel > 0:
while curtime < t:
dt = min(63, t-curtime)
curtime += dt
if nnotes > 0:
nvoices = 0
curchans = 0
output.append(dt+128)
if note >= min_note and note <= max_note and nvoices < max_voices:
if not (one_voice_per_channel and (curchans & (1<<msg.channel))):
n = note - min_note
output.append(n)
nnotes += 1
nvoices += 1
curchans |= 1<<msg.channel
output.append(0xff)
if coutput:
print((','.join([hex2(x) for x in output])))
else:
bighex = ''.join([hex1(x) for x in output])
for i in range(0,len(bighex)+32,32):
print(('\thex', bighex[i:i+32]))
if compress:
# replace common substrings
bout = ''.join(chr(i) for i in output)
for iter in range(0,32):
ss = find_common_substrings(bout)
bss = get_best_substring(ss)
print(bss)
if bss[1] == 0:
break
bout = replace_substrings(bout, bss)
print((repr(bout)))
# build substring table
ofs = (len(g_subs)+1)*2
zout = offset2str(ofs)
ofs += len(bout)
for ss in g_subs:
ofs += len(ss)
zout += offset2str(ofs)
# output strings
zout += bout
for ss in g_subs:
zout += ss
# print output
print((','.join([hex2(ord(x)) for x in zout])))
print(("// compressed %d -> %d bytes" % (len(output), len(zout))))

View File

@ -1,48 +0,0 @@
#!/usr/bin/python
import sys, string, math, argparse
parser = argparse.ArgumentParser()
parser.add_argument('-l', '--length', type=int, default=64, help="length of note table")
parser.add_argument('-u', '--upper', type=int, default=49, help="upper note # to test")
parser.add_argument('-f', '--freq', type=float, default=3579545/32.0, help="base frequency (Hz)")
parser.add_argument('-b', '--bias', type=float, default=0, help="divisor bias")
parser.add_argument('-m', '--maxbits', type=float, default=12, help="max. # of bits")
args = parser.parse_args()
test_notes = args.upper
final_notes = args.length
basehz = args.freq
bias = args.bias
maxval = (1<<int(args.maxbits))-1
results = []
for a440 in range(4300,4500):
error = 0
for note in range(1,test_notes):
notehz = a440 / 10.0 * math.pow(2.0, (note - 49) / 12.0);
period = int(round(basehz / notehz))
while period > maxval:
period /= 2
tonehz = basehz / period
error += abs(notehz-tonehz)
#print a440,note,notehz,notehz-tonehz,period
#if a440 == 4405:
# print '%d,%f,%d' % (note,tonehz-notehz,period)
results.append((error, a440))
results.sort()
best_error, best_a440 = results[0]
best_a440 /= 10.0
print('//', args)
print('//', best_a440, best_error, test_notes)
print("const int note_table[%d] = {" % final_notes)
for note in range(0,final_notes):
notehz = best_a440 * math.pow(2.0, (note - 49) / 12.0);
period = int(round(basehz / notehz)) - bias
while period > maxval:
period /= 2
print('%d,' % period, end='')
print("};")

View File

@ -1,91 +0,0 @@
#!/usr/bin/python
import sys, string, math, argparse
parser = argparse.ArgumentParser()
parser.add_argument('-l', '--length', type=int, default=64, help="length of note table")
parser.add_argument('-u', '--upper', type=int, default=49, help="upper note # to test")
args = parser.parse_args()
test_notes = args.upper
final_notes = args.length
basehz = 15720.0 #4
basehz2 = 5240.0 #12
basehz3 = 1014.2 #6
s = 8
bittable = [
0b00000000,
0b00000001,
0b00010001,
0b01001001,
0b01010101,
0b10110101,
0b11011011,
0b11101111,
]
results = []
for a440 in range(4200,4600):
error = 0
for note in range(4,test_notes):
notehz = a440 / 10.0 * math.pow(2.0, (note - 49) / 12.0);
period = round(basehz * s / notehz) / s
tonehz = basehz / period
if period < s or period > 32*s:
tonehz = -10000
period2 = round(basehz2 * s / notehz) / s
tonehz2 = basehz2 / period
if period2 < s or period2 > 32*s:
tonehz2 = -10000
period3 = round(basehz3 * s / notehz) / s
tonehz3 = basehz3 / period
if period3 < s or period3 > 32*s:
tonehz3 = -10000
error += min(abs(notehz-tonehz), abs(notehz-tonehz2), abs(notehz-tonehz3))
results.append((error, a440))
results.sort()
best_error, best_a440 = results[0]
best_a440 /= 10.0
print('//', best_a440, best_error, test_notes)
periods = []
tones = []
bits = []
print("const int note_table[%d] = {" % final_notes)
for note in range(0,final_notes):
notehz = best_a440 * math.pow(2.0, (note - 49) / 12.0);
bestperiod = 255
bestscore = 999999
besthz = -1
for hz in [basehz, basehz2, basehz3]:
period = int(round(hz * s / notehz))
if period >= s and period <= 32*s:
tonehz = hz / period
error = notehz - hz
if error < bestscore:
bestscore = error
bestperiod = period
besthz = hz
#print(note, besthz, bestperiod, notehz)
print('%d,' % period, end='')
periods.append(bestperiod / s - 1)
bits.append(bittable[bestperiod & (s-1)])
if besthz==basehz:
tones.append(4)
elif besthz==basehz2:
tones.append(12)
elif besthz==basehz3:
tones.append(6)
else:
tones.append(0)
print("};")
print(periods)
print(bits)
print(tones)

View File

@ -1,9 +0,0 @@
d = 16
s = 800
for n in range(0,128):
z = n/2+d
y = s/z
print("%d," % y, end='')
print()

View File

@ -1,2 +0,0 @@
*.c
*.pbm

View File

@ -1,29 +0,0 @@
all: cp437.mw8080.c c64.mw8080.c baddies-horiz.rot.c scrappy.rot.c
# convert DOS CP437 font (256 chars)
cp437.mw8080.c: ../fonts/cp437-8x8.bdf
python ../parsebdf8.py $< -f -r -C > $@
# convert C64 font (63 chars)
c64.mw8080.c: ../fonts/c64.bdf
python ../parsebdf8.py $< -f -r -C -s 32 -e 94 > $@
%.h:
cat $* | hexdump -v -e '"\n" 128/1 "0x%02x,"'
# convert PBM bitmap to C array
%.c: %.pbm
python ../pbm_to_c.py $< > $@
#%.rot.pbm: %.pbm
# convert $< -transpose -bordercolor white -border 4x4 $@
# rotate and dither example bitmaps
baddies-horiz.rot.pbm: ../images/baddies-horiz.png
convert $< +dither -brightness-contrast 50x50 -fill black -transpose -negate $@
scrappy.rot.pbm: ../images/scrappy48x64.pbm
convert $< -transpose -bordercolor white -border 4x4 $@

View File

@ -1,11 +0,0 @@
all: nametable.dat
clean:
rm -f *.dat road.png
nametable.dat: road.png
makechr -e error.png $< #-b 0000ff
road.png: road.py
python road.py

View File

@ -1,102 +0,0 @@
#!/usr/bin/python
# Import a library of functions called 'pygame'
import pygame
import random
from math import pi
# Initialize the game engine
pygame.init()
# Define the colors we will use in RGB format
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
BLUE = ( 0, 0, 255)
GREEN = ( 0, 184, 0)
CURBING = [
(136,20,0),
(168,16,0),
]
CENLINE = [
(124,124,124),
(188,188,188),
]
MOUNTAINS = [
(80,48,0),
(172,124,0)
]
# Set the height and width of the screen
size = [512, 240]
y0 = 112
x0 = 256
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Example code for the draw module")
#Loop until the user clicks the close button.
done = False
clock = pygame.time.Clock()
while not done:
# This limits the while loop to a max of 10 times per second.
# Leave this out and we will use all CPU we can.
clock.tick(10)
for event in pygame.event.get(): # User did something
if event.type == pygame.QUIT: # If user clicked close
done=True # Flag that we are done so we exit this loop
# All drawing code happens after the for loop and but
# inside the main while done==False loop.
# Clear the screen and set the screen background
screen.fill(BLUE)
pygame.draw.rect(screen, GREEN, [0, y0, 512, 240-y0])
# draw the road
for y in range(y0,240):
i = y-y0
rw = i*2
cw = rw/4
lw = rw/32
z = 500.0/(i+1)
curbcol = CURBING[int(z) % 2]
cencol = CENLINE[int(z) % 2]
if i < 16:
cencol = BLACK #CENLINE[0]
if i < 0:
curbcol = BLACK #CURBING[0]
pygame.draw.line(screen, BLACK, [x0-rw, y], [x0+rw, y], 1)
pygame.draw.line(screen, curbcol, [x0-rw-cw, y], [x0-rw, y], 1)
pygame.draw.line(screen, curbcol, [x0+rw, y], [x0+rw+cw, y], 1)
pygame.draw.line(screen, cencol, [x0-rw/3-lw, y], [x0-rw/3+lw, y], 1)
pygame.draw.line(screen, cencol, [x0+rw/3-lw, y], [x0+rw/3+lw, y], 1)
# draw mountains
h1 = 1
h2 = 2
for x in range(0,512):
pygame.draw.line(screen, MOUNTAINS[0], [x, y0-1], [x, y0-h1], 1)
pygame.draw.line(screen, MOUNTAINS[1], [x, y0-1], [x, y0-h2], 1)
if random.randint(0,8) > h1:
h1 += 1
elif h1 > 1:
h1 -= 1
if random.randint(0,6) > h2:
h2 += 1
elif h2 > 1:
h2 -= 1
# Go ahead and update the screen with what we've drawn.
# This MUST happen after all the other drawing commands.
pygame.display.flip()
pygame.image.save(screen, 'road.png')
# Be IDLE friendly
pygame.quit()

View File

@ -1,11 +0,0 @@
import sys
chr = open(sys.argv[1],'rb').read()
out = open('outsms.bin','wb')
for i in range(0,len(chr),16):
for y in range(0,8):
arr = [ ord(chr[i+y]), ord(chr[i+8+y]), 0, 0 ]
out.write(bytearray(arr))
out.close()

View File

@ -1,58 +0,0 @@
#!/usr/bin/python
import sys, struct
# playfield bytes, one array for each of 6 columns
output = [[],[],[],[],[],[]]
# reverse byte
def rev(n):
return int('{:08b}'.format(n)[::-1], 2)
# output bits in given range
def out(i, pix, lb, hb, reverse=0, shift=0):
x = (pix >> lb) & ((1<<(hb-lb))-1)
if reverse:
x = rev(x)
if shift:
x = x << shift
assert(x>=0 and x<=255)
output[i].append(x)
# read PBM (binary P4 format) file
with open(sys.argv[1],'rb') as f:
# read PBM header
header = f.readline().strip()
assert(header == b'P4')
dims = f.readline().strip()
if dims[0:1] == b'#':
dims = f.readline().strip()
width,height = list(map(int, dims.split()))
assert(width==48)
# read bitmap rows
for y in range(0,height):
row = bytes(f.read(6) + b'\0\0') # pad to 8 bytes
# convert to 64-bit integer
pix = struct.unpack('<q',row)[0]
#print '%010lx' % pix
# generate playfield bytes
out(0, pix, 0, 8, 0)
out(1, pix, 8, 16, 0)
out(2, pix, 16, 24, 0)
out(3, pix, 24, 32, 0)
out(4, pix, 32, 40, 0)
out(5, pix, 40, 48, 0)
# output bitmap tables
for c in range(0,6):
print("\talign $100")
print(("Bitmap%d" % c))
print("\thex 00")
s = '\thex '
for i in range(0,height):
s += '%02x' % output[c][height-i-1]
if i % 16 == 15:
print(s)
s = '\thex '
if len(s)>5:
print(s)

View File

@ -1,60 +0,0 @@
#!/usr/bin/python
import sys, struct
# playfield bytes, one array for each of 6 columns
output = [[],[],[],[],[],[]]
# reverse byte
def rev(n):
return int('{:08b}'.format(n)[::-1], 2)
# output bits in given range
def out(i, pix, lb, hb, reverse=0, shift=0):
x = (pix >> lb) & ((1<<(hb-lb))-1)
if reverse:
x = rev(x)
if shift:
x = x << shift
assert(x>=0 and x<=255)
output[i].append(x)
# read PBM (binary P4 format) file
with open(sys.argv[1],'rb') as f:
# read PBM header
header = f.readline().strip()
assert(header == b'P4')
dims = f.readline().strip()
if dims[0:1] == b'#':
dims = f.readline().strip()
print(dims)
width,height = list(map(int, dims.split()))
assert(width==40)
# read bitmap rows
for y in range(0,height):
row = bytes(f.read(5) + b'\0\0\0') # pad to 8 bytes
# convert bytes from MSB first to LSB first
row2 = []
for i in range(0,8):
row2.append(rev(row[i]))
# convert to 64-bit integer
pix = struct.unpack('<q',bytes(row2))[0]
# generate playfield bytes
out(0, pix, 0, 4, 0, 4)
out(1, pix, 4, 12, 1)
out(2, pix, 12, 20, 0)
out(3, pix, 20, 24, 0, 4)
out(4, pix, 24, 32, 1)
out(5, pix, 32, 40, 0)
# output bitmap tables
for c in range(0,6):
print(("PFBitmap%d" % c))
s = '\thex '
for i in range(0,height):
s += '%02x' % output[c][height-i-1]
if i % 16 == 15:
print(s)
s = '\thex '
if len(s)>5:
print(s)

View File

@ -1,71 +0,0 @@
#!/usr/bin/python
import sys,string
height = 5
lochar = 41
hichar = 90
chars = {}
inbitmap = 0
with open(sys.argv[1],'r') as f:
lines = f.readlines()
for l in lines:
l = l.strip()
toks = l.split()
if toks[0] == 'ENCODING':
chord = int(toks[1])
elif toks[0] == 'BITMAP':
inbitmap = True
bytes = []
elif toks[0] == 'ENDCHAR':
inbitmap = False
if chord >= lochar and chord <= hichar:
while len(bytes) < height:
bytes.insert(0,0)
assert(len(bytes) == height)
bytes.reverse()
print((chord,bytes))
chars[chord] = bytes
elif inbitmap and len(toks) == 1:
byte = int(toks[0],16)
assert((byte&15)==0)
assert((byte&1)==0)
byte = byte / 32
bytes.append(byte)
# output font table
x = 0
output = []
outputlo = []
outputhi = []
for ch in range(lochar,hichar+1):
x = 0
bytes = chars.get(ch)
#bytes = bytes + [0]
if not bytes:
bytes = [0] * height
for b in bytes:
if not x:
v = b
else:
v = v | (b<<4)
output.append(v)
x ^= 1
outputlo.append(b)
outputhi.append(b<<4)
def tohex(v):
return '%02x'%v
def tohex2(v):
return '0x%02x'%v
def tobin(v):
return "bitarray[0][0]=3'b{0:3b};\n".format(v)
print(('\thex ' + ''.join(map(tohex,output))))
print((''.join(map(tohex2,output))))
print(('\thex ' + ''.join(map(tohex,outputlo))))
print(('\thex ' + ''.join(map(tohex,outputhi))))
print((''.join(map(tobin,output))))
print((len(output),len(outputlo),len(outputhi)))

View File

@ -1,65 +0,0 @@
#!/usr/bin/python
import sys,string,argparse
#lochar = 0x20 #48
#hichar = 0x5e #57
parser = argparse.ArgumentParser()
parser.add_argument('-s', '--start', type=int, default=0, help="index of first character")
parser.add_argument('-e', '--end', type=int, default=255, help="index of last character")
parser.add_argument('bdffile', help="BDF bitmap file")
args = parser.parse_args()
lochar = args.start
hichar = args.end
def tohex(v):
return '%02x'%v
def tohex2(v):
return '0x%02x'%v
chars = {}
inbitmap = 0
with open(args.bdffile,'r') as f:
lines = f.readlines()
for l in lines:
l = l.strip()
toks = l.split()
#print l,toks
if toks[0] == 'ENCODING':
chord = int(toks[1])
elif toks[0] == 'BITMAP':
inbitmap = True
bytes = []
elif toks[0] == 'BBX':
bbx = [int(x) for x in toks[1:]]
elif toks[0] == 'ENDCHAR':
inbitmap = False
if chord >= lochar and chord <= hichar:
#bytes.reverse()
#print chord,bytes,bbx
width = bbx[0]+1
height = bbx[1]
output = [(width+1)//2 + (width)*16, height + (height+bbx[3])*16]
for y in range(0,height):
for x in range(0,width,2):
b = 0
if bytes[y] & (0x80 >> x):
b |= 0xf0
if bytes[y] & (0x40 >> x):
b |= 0x0f
output.append(b)
print('const char CH_%d[] = { %s };' % ( chord, ','.join([tohex2(x) for x in output]) ))
chars[chord] = 'CH_%d' % chord
elif inbitmap and len(toks) == 1:
byte = int(toks[0],16)
bytes.append(byte)
print('const char* const FONT_TABLE[%d] = {' % (hichar-lochar+1), end=' ')
for ch in range(lochar, hichar+1):
if chars.get(ch):
print('%s,' % chars[ch], end=' ')
else:
print('0,', end=' ')
print("};")

View File

@ -1,120 +0,0 @@
#!/usr/bin/python
import sys,string,argparse
#lochar = 0x20 #48
#hichar = 0x5e #57
parser = argparse.ArgumentParser()
parser.add_argument('-s', '--start', type=int, default=0, help="index of first character")
parser.add_argument('-e', '--end', type=int, default=255, help="index of last character")
parser.add_argument('-H', '--height', type=int, default=8, help="character height")
parser.add_argument('-i', '--invert', action="store_true", help="invert bits")
parser.add_argument('-r', '--rotate', action="store_true", help="rotate bits")
parser.add_argument('-f', '--flip', action="store_true", help="flip bits (vertically)")
parser.add_argument('-m', '--mirror', action="store_true", help="mirror bits (horizontally)")
outfmtgroup = parser.add_mutually_exclusive_group()
outfmtgroup.add_argument("-A", "--asmhex", action="store_true", help="DASM-compatible hex")
outfmtgroup.add_argument("-B", "--asmdb", action="store_true", help="Z80ASM-compatible hex")
outfmtgroup.add_argument("-C", "--carray", action="store_true", help="Nested C array")
outfmtgroup.add_argument("-F", "--flatcarray", action="store_true", help="Flat C array")
outfmtgroup.add_argument("-V", "--verilog", action="store_true", help="Verilog-compatible hex")
parser.add_argument('bdffile', help="BDF bitmap file")
args = parser.parse_args()
height = args.height
lochar = args.start
hichar = args.end
invert = args.invert
flip = args.flip
rotate = args.rotate
mirror = args.mirror
chars = {}
inbitmap = 0
with open(args.bdffile,'r') as f:
lines = f.readlines()
for l in lines:
l = l.strip()
toks = l.split()
#print l,toks
if toks[0] == 'ENCODING':
chord = int(toks[1])
elif toks[0] == 'BITMAP':
inbitmap = True
bytes = []
elif toks[0] == 'ENDCHAR':
inbitmap = False
if chord >= lochar and chord <= hichar:
while len(bytes) < height:
bytes.insert(0,0)
assert(len(bytes) == height)
bytes.reverse()
#print chord,bytes
chars[chord] = bytes
elif inbitmap and len(toks) == 1:
byte = int(toks[0],16)
bytes.append(byte)
def revbits(n):
r = 0
for i in range(0,8):
if (n & (1<<i)):
r |= (1<<(7-i))
return r
# output font table
x = 0
output = []
revoutput = []
rotoutput = []
rot2output = []
for ch in range(lochar,hichar+1):
bytes = chars.get(ch)
if not bytes:
bytes = [0] * height
if flip:
bytes.reverse()
if mirror:
for i in range(0,height):
bytes[i] = revbits(bytes[i])
if rotate:
rotbytes = [0] * height
for x in range(0,height):
for y in range(0,height):
rotbytes[-1-x] |= (((bytes[-1-y]>>x)&1)<<y)
bytes = rotbytes
#rotoutput[-7+x] |= (((output[-1-y]>>x)&1)<<y)
#rotoutput[-1-x] |= (((output[-1-y]>>x)&1)<<y)
#rot2output[-1-x] |= (((output[-7+y]>>x)&1)<<y)
for b in bytes:
output.append(b)
def tohex(v):
return '%02x'%v
def tohex2(v):
return '0x%02x'%v
def tohexv(v):
return "8'h%02x"%v
for arr in [output]:
if args.asmhex:
print('\thex ' + ''.join(list(map(tohex,arr))))
if args.asmdb:
for i in range(0,len(output),height):
print('.DB', ','.join(list(map(tohex2,arr[i:i+height]))), ';%d'%(i/height+lochar))
if args.carray:
print("static char FONT[%d][%d] = {" % (hichar-lochar+1, height))
for i in range(0,len(output),height):
print('{', ','.join(list(map(tohex2,arr[i:i+height]))), '},', end=' ')
print()
print("};")
if args.flatcarray:
print("static char FONT[%d] = {" % ((hichar-lochar+1) * height))
print(','.join(list(map(tohex2,arr))))
print("}");
if args.verilog:
j = 0
for i in range(0,len(output),height):
print(','.join(list(map(tohexv,arr[i:i+height]))) + ", //%d" % (i/height))
j += 1

View File

@ -1,37 +0,0 @@
#!/usr/bin/python
import sys
# reverse byte
def rev(n):
return int('{:08b}'.format(n)[::-1], 2)
# output bits in given range
def out(i, pix, lb, hb, reverse=0, shift=0):
x = (pix >> lb) & ((1<<(hb-lb))-1)
if reverse:
x = rev(x)
if shift:
x = x << shift
assert(x>=0 and x<=255)
output[i].append(x)
# read PBM (binary P4 format) file
with open(sys.argv[1],'rb') as f:
# read PBM header
header = f.readline().strip()
assert(header == 'P4')
dims = f.readline().strip()
while dims[0] == '#':
dims = f.readline().strip()
width,height = map(int, dims.split())
wbytes = (width+7)/8
data = f.read()
print("{%d,%d," % (wbytes,height), end='')
for i in range(0,len(data)):
if i>0:
sys.stdout.write(",")
ofs = i+wbytes-(i%wbytes)*2-1
sys.stdout.write( "0x%02x" % ord(data[ofs]) )
print("}")

View File

@ -1,46 +0,0 @@
#!/usr/bin/python
import sys, array, string
col0 = 0
def tocolor(x):
if x == 0:
return 0
else:
return x + col0
def tohex2(v):
return '0x%02x'%v
with open(sys.argv[1],'rb') as f:
data = array.array('B', f.read())
assert data[0] == 0xa
assert data[3] == 8
# palette
print("byte palette[16] = {", end='')
for i in range(0,16):
r = data[16+i*3]
g = data[17+i*3]
b = data[18+i*3]
entry = (r>>5) | ((g>>2)&0x38) | (b&0xc0)
print('%s,' % (tohex2(entry)), end='')
print("}")
# image data
width = (data[9] << 8) + data[8] + 1
height = (data[11] << 8) + data[10] + 1
rowlen = (data[0x43] << 8) + data[0x42]
print("const byte sprite[] = {")
print("%d,%d," % ((width+1)/2,height))
for y in range(0,height):
ofs = 0x80 + y*rowlen
output = []
for x in range(0,width,2):
b = (tocolor(data[ofs]) << 4) + tocolor(data[ofs+1])
output.append(b)
ofs += 2
print(','.join(map(tohex2,output)) + ',')
print("}")

View File

@ -1,83 +0,0 @@
#!/usr/bin/env node
var fs = require('fs'),
PNG = require('pngjs').PNG,
RgbQuant = require('rgbquant');
var data = fs.readFileSync(process.argv[2]);
var png = PNG.sync.read(data);
q = new RgbQuant();
q.colors = 4;
q.sample(png.data);
pal = q.palette(false, true);
//console.log(q);
function readfonttxt(s) {
var lines = s.split(/\r?\n/);// TODO
}
function remapBits(x, arr) {
if (!arr) return x;
var y = 0;
for (var i=0; i<arr.length; i++) {
var s = arr[i];
if (s < 0) {
s = -s-1;
y ^= 1 << s;
}
if (x & (1 << i)) {
y ^= 1 << s;
}
}
return y;
}
function reorder(arrin, remap) {
var out = [];
for (var i=0; i<arrin.length; i++) {
var j = remapBits(i, remap);
//console.log(i,j);