izapple2/characterGenerator.go

125 lines
2.7 KiB
Go
Raw Normal View History

2019-04-21 16:18:43 +00:00
package apple2
import (
2019-10-05 23:26:00 +00:00
"errors"
2019-04-21 16:18:43 +00:00
"fmt"
)
/*
See:
hhttps://mirrors.apple2.org.za/Apple%20II%20Documentation%20Project/Companies/Apple/Documentation/Apple%20Technical%20Information%20Library/a2til041.txt
*/
// CharacterGenerator represents the ROM wth the characters bitmaps
type CharacterGenerator struct {
data []uint8
customRom bool
columnMap charColumnMap
page int
2019-04-21 16:18:43 +00:00
}
type charColumnMap func(column int) int
2019-04-21 16:18:43 +00:00
const (
rev7CharGenSize = 2048
defaultCharGenROM = "<internal>/Apple2rev7CharGen.rom"
2019-04-21 16:18:43 +00:00
)
// NewCharacterGenerator instantiates a new Character Generator with the rom on the file given
2019-10-05 23:26:00 +00:00
func NewCharacterGenerator(filename string) (*CharacterGenerator, error) {
2019-04-21 16:18:43 +00:00
var cg CharacterGenerator
2019-10-05 23:26:00 +00:00
err := cg.load(filename)
if err != nil {
return nil, err
}
return &cg, nil
2019-04-21 16:18:43 +00:00
}
2019-10-05 23:26:00 +00:00
func (cg *CharacterGenerator) load(filename string) error {
cg.customRom = !isInternalResource(filename)
2019-10-05 23:26:00 +00:00
bytes, err := loadResource(filename)
if err != nil {
return err
}
2019-05-15 14:01:04 +00:00
size := len(bytes)
if size < rev7CharGenSize {
2019-10-05 23:26:00 +00:00
return errors.New("Character ROM size not supported")
2019-04-21 16:18:43 +00:00
}
2019-05-15 14:01:04 +00:00
cg.data = bytes
2019-10-05 23:26:00 +00:00
return nil
2019-04-21 16:18:43 +00:00
}
func (cg *CharacterGenerator) setColumnMap(columnMap charColumnMap) {
// Regular Apple II uses bits 6 to 0 but some clones have other mappings
cg.columnMap = columnMap
}
func (cg *CharacterGenerator) setPage(page int) {
// Some clones had a switch to change codepage with extra characters
pages := len(cg.data) / rev7CharGenSize
cg.page = page % pages
}
func (cg *CharacterGenerator) nextPage() {
cg.setPage(cg.page + 1)
}
2019-04-21 19:04:02 +00:00
func (cg *CharacterGenerator) getPixel(char uint8, row int, column int) bool {
bits := cg.data[int(char)*8+row+cg.page*rev7CharGenSize]
var bit int
if cg.columnMap != nil {
bit = cg.columnMap(column)
} else {
// Standard Apple 2 mapping
bit = 6 - column
}
value := bits >> uint(bit) & 1
return value == 1
2019-04-21 19:04:02 +00:00
}
func (cg *CharacterGenerator) dumpCharRaw(char int) {
2019-04-21 16:18:43 +00:00
base := int(char) * 8
fmt.Printf("Char: %v\n---------\n", char)
for i := 0; i < 8; i++ {
fmt.Print("|")
b := cg.data[base+i]
for j := 0; j < 8; j++ {
2019-04-21 16:18:43 +00:00
if (b>>uint(j))&1 == 1 {
fmt.Print("#")
} else {
fmt.Print(" ")
}
}
fmt.Println("|")
}
fmt.Println("---------")
}
2019-04-21 19:04:02 +00:00
func (cg *CharacterGenerator) dumpChar(char uint8) {
fmt.Printf("Char: %v\n---------\n", char)
for row := 0; row < 8; row++ {
fmt.Print("|")
for col := 0; col < 7; col++ {
if cg.getPixel(char, row, col) {
fmt.Print("#")
} else {
fmt.Print(" ")
}
}
fmt.Println("|")
}
fmt.Println("---------")
}
// Dump to sdtout all the character maps
2019-04-21 16:18:43 +00:00
func (cg *CharacterGenerator) Dump() {
pages := len(cg.data) / rev7CharGenSize
for p := 0; p < pages; p++ {
cg.setPage(p)
for i := 0; i < 256; i++ {
cg.dumpChar(uint8(i))
//cg.dumpCharRaw(int(i))
}
2019-04-21 16:18:43 +00:00
}
}