Jump to content

Recommended Posts

Good idea! I never liked the 'mini' expander because it stuck too far out the back of the computer, and added too little for the price.

 

I am building a 'micro' expander that combines 32k RAM, 128k ROM, an AY-3-8910 and joystick ports in the stock cartridge port area. There will be two boards, one stacked on top of the other. Here's what I have done so far...

That looks good! My "Mini Expander II" will be a drop-in upgrade board designed to fit inside the original Mini Expander shell, so I'm afraid it won't be any smaller than the original, but it will have many more features built in. As you know, the original Mini Expander was nothing but two cartridge ports, the AY-3-8910 PSG, the two hand controller ports, and some glue logic to hold everything together. I haven't nailed down the specs on the "Mini Expander II" yet, but I would like to include: 512K of ROM, banked into the $2000-$2FFF region (it will be seen as an Aquarius II Extended BASIC ROM, but will include hooks for additional BASIC commands and other software features), an extra PSG for three more audio channels, some Atari-compatible joystick and paddle ports, a serial port, and hopefully, an IDE port for a solid-state disk.

 

In the meantime, I've attached a copy of the best Mini Expander schematic that I have, in case it would be helpful for your "Micro Expander" project:

 

MiniExpanderSchematic.jpg

  • Like 2

My list of what features I think the 'SuperFont' upgrade should have:-

 

1. Installs into character ROM socket on the motherboard, with a minimum amount of extra wiring.

2. Provide at least one bank of programmable characters, plus the original set 'hardwired' in.

3. Optional:- extra character banks and 320x200 mode.

4. Compatible with all existing software and does not conflict with popular expansion devices.

5. Able to manipulate character patterns using BASIC commands, preferably without having to load any extra code.

6. Affordable and easy to obtain, with bare pcb and DIY options for people who like building their own stuff!

 

Regarding #5, the stock POKE command can only be used if 'SuperFont' RAM is mapped at $3000 or higher, but this conflicts with other memory devices (RAM, cartridge ROM). Rather than mapping into memory it could be accessed through an I/O port, but Aquarius BASIC has no port commands!

 

My solution was to replace the BASIC ROM with a patched version that allows poking into low memory. This continues Aquarius minimalist programming philosophy, but has the disadvantage of having to replace the ROM (a good idea, but yet another modification to the motherboard). Another option would be to add an 'Extended BASIC' ROM mapped into the unused expansion bus area at $2000~$2FFF. This ROM could be put in the mini-expander so that it is always available to those people who have one (which should be everybody).

Edited by Bruce Abbott
  • Like 3

In the meantime, I've attached a copy of the best Mini Expander schematic that I have, in case it would be helpful for your "Micro Expander" project:

Thank you! That answers several questions. I searched the net for ages, but couldn't find a circuit for the mini-expander. I didn't think one existed...

  • Like 2

There is a very simple solution to that problem. Simply cut the track going from PLA1 pin 44 to U15 (74LS86) and connect U15 pins 5 and 9 to ground, then CP/M mode is disabled and the I/O bit is available for other use. I did this because I wanted to get a control bit without having to add my own I/O port.

 

CP/M mode inverts the memory map for internal RAM and ROM but doesn't change the cartridge address, so yes it would wreak havoc - which is why I figured that it is not worth retaining and re-purposing it would be safe.

 

I suspect that the I/O bit was originally designed for something else. Then somebody (at Mattel?) decided that the Aquarius needed CP/M compatibility, so an external circuit was added to reconfigure the memory map. This would explain why that external circuit was needed to swap A14 and A15, rather than using logic gates inside PLA1.

Good idea about repurposing the CP/M I/O port. I always assumed that it was reserved for the unreleased Macro Expander (the external card cage and floppy drive controller which would have added CP/M compatibility), but I can't see anyone having any need of it today.

 

You're probably right about the clearance for the plug-in board. Some Aquarius computers have socketed RAM, so if there is enough space for that, there should be enough for a small board with surface-mounted components. The original character ROM is pin-compatible with the 2716 EPROM, so unlike the other custom chips, it is replaceable if a user damages it on extraction and decides later that they want to put it back.

 

I find myself turning back to the original idea of making "SuperFont" a plug-in board. I'd hate to ask people to start pulling chips out of their Aquariuses, but having a mess of wires running around inside would just be too fragile and ugly. The main problem with removing the character ROM is that there will be no character set present on startup. I don't want to have to replace the OS ROM as well, and I want to leave the $2000-$2FFF area free for the Mini Expander II, so I won't be able to use your approach of populating the character RAM on startup. So, I'll probably just add a character ROM to the "SuperFont" board alongside the RAM. A 32K ROM makes sense, since that's the size of the RAM, and it will give me lots of room to provide some built-in character sets for programmers to start with.

  • Like 2

Sorry about that. I looked at the text above your avatar and thought it was your username!

 

I replaced the part that creates the character based screen with my own code that generates a character pattern map instead (I thought it would be easy, but I spent most of the day just trying to get your source code to compile in FreeBasic! Then the real fun began...).

 

 

The programmable character RAM is mapped on top of the BASIC ROM, so getting the data into it is simply a matter of loading an 8k binary file at address $0000. Currently I am just using the whole character set in order, repeated 4 times over. Next step is to reuse characters that already have the correct pattern, then for higher compression start choosing those that are 'close enough'. I also want to add color, but I haven't yet figured out a good way to do it (other programs that I have tried seem to make a mess of 'colorizing' high resolution images).

 

I was amazed by your Dallas video. With a well crafted custom character set it could be even better! So many possibilities...

 

But first I have to put more memory and I/O into my Aquarius. Only having the stock 4k of main RAM and tape storage makes for a very slow and frustrating development cycle.

 

 

Want help? I have been playing with image optimization in attribute clash situations. I've found atkinson to work much better than FS. Sorry about the Freebasic code - the program was written in an older version of Freebasic and become non-compliant in new versions. Get an EEPROM burner and Jay's board - makes development much easier. There are pin-compatible EEPROMs that work well so no UV erasing. If you were to tell me what output you needed and in what memory format it would likely be trivial to put together. Could do character/attribute or a character map continuously and then a separate attribute set. Would be happy to help if you wanted it. Seeing a full screen 320x200x16 color Aquarius image would be awesome. If we got you Jay's Supercart board and a burner, we could even flicker between two frames (certainly having 512 characters per screen is plenty) and we would have 4 colors per 8x8 block!!!! Endless possibilities. So much fun.

  • Like 3

Thank you! That answers several questions. I searched the net for ages, but couldn't find a circuit for the mini-expander. I didn't think one existed...

You're very welcome! I'm glad it was helpful.

 

I agree with your list of features for "SuperFont". Here is my thinking about each of them:

 

#1: Making it a plug-in board will greatly reduce the amount of external wiring. I'll still need to tap into the data bus, so that will be eight wires, plus a couple more for extra address lines and other necessary signals. Most of these solder points will be within easy reach of the daughterboard, so I think it will make for an easy installation, once the RF shielding is gone and the ROM is extracted.

 

#2, #3: The character RAM will be 32K, so that will give us enough space for sixteen character sets, or four fullscreen bitmaps of four sets each. I plan to add the ability to switch between banks (or groups of four banks, in the case of fullscreen bitmaps), and the ability to change from "single character set mode" to "fullscreen bitmap mode". This will make it possible to use rapid character set switching for animation, double buffering, and other graphical tricks.

 

To control these functions, I could use an I/O port, but that would mean running yet more wires (the /IORQ signal and more address lines for decoding). So to avoid that and to keep the logic simple, I'm thinking of dividing the top half of the 8K OS ROM space into two 2K windows: the $1800-$1FFF window will allow writes into the currently enabled 2K character RAM bank, and writes into the $1000-$17FF window will control the bankswitching and other functions.

 

#4: Since the original character ROM will be removed, I'll have to add a ROM to the "SuperFont" board. This ROM will be enabled by default, so the Aquarius will always start with its original character set. This should preserve compatibility with existing software. I'm also going to avoid using the ROM space from $0000-$0FFF for anything related to "SuperFont", because some ill-behaved Aquarius software will sometimes write into this space (certain cartridge titles don't use proper bounds checking when searching for system RAM, for instance).

 

#5: I'm going to be leaving the original OS ROM intact, but there are other alternatives for adding "SuperFont" functionality to BASIC. I could provide some inline assembly routines that the users can add to their programs (along with plenty of documentation!), or for those who would prefer to have additional BASIC statements to use, I could provide a modified Extended BASIC cartridge with the extra commands built in. Using inline assembly in BASIC will bypass the POKE restrictions, and will also be a lot faster than using POKE. Eventually, the new statements will be a part of the "Mini Expander II" Extended BASIC ROM, and since this will be field upgradeable, we'll have the option of adding more statements (for software sprites, etc) later.

 

#6: I anticipate that "SuperFont" will be very inexpensive, and I'll limit myself to off-the-shelf logic and memory chips. I'd really love to find a way to socket the character ROM, so that if someone wants to store their own characters in the ROM permanently, they can simply burn their own EPROM and plug it in.

 

Let me know what you think!

  • Like 1

 

 

If you were to tell me what output you needed and in what memory format it would likely be trivial to put together. Could do character/attribute or a character map continuously and then a separate attribute set

The bitmap format is the same as a character ROM. Starting from the top left of the screen, the 1st byte (MSB to LSB) is pixels 1~8 of scan line 1, 2nd byte is pixels 1~8 of scan line 2 etc. down to scan line 8, to create character #0. Then back up and across to scan line 1 pixels 9~16, and go down getting another 8 bytes for character #2. This continues until 1000 characters have been created (8000 bytes). Color attributes can be added after that, each byte representing the foreground (bits 7~4) and background (bits 3~0) color of each character position.

 

A more advanced format might have a variable number of character patterns, with a character map to determine their positions (possibly multiple positions per pattern) on screen. It would then need a header word to tell the loader how many character patterns to expect. Two bytes are required to store the number of characters, but since the maximum is 1000 that leaves 6 bits that could be used other purposes.

 

There is a slight problem with the first character (char #0) which the Aquarius hardware repeats in the border area. There are two ways around this:-

 

1. Skip the first character, or skip the whole line (40 bytes) and start at line 2 (giving an effective resolution of 320x192).

 

2. Just make sure that character #0 is blank and/or has the same foreground and background colors. You could have an option to not adjust character #0 and just leave it with whatever is in the image, then you would still have the option of a patterned border if you want one.

Edited by Bruce Abbott
  • Like 3

A DIP EPROM will fit if you use socket strips like this, that allow the pins to go through the pcb. Alternatively you could use a PLCC chip and smd socket (about 3.5mm height). Most smd EPROMs are OTP only, but equivalent flash chips such as the AT28C64 are not much more expensive.

 

And then there's the lazy option - don't use a socket at all, just program the chip and solder it in! I would put up with this if the other alternatives were too difficult or expensive.

 

 

jaybird3rd, on 31 Dec 2014 - 09:49 AM, said:

 

#6: I anticipate that "SuperFont" will be very inexpensive, and I'll limit myself to off-the-shelf logic and memory chips. I'd really love to find a way to socket the character ROM, so that if someone wants to store their own characters in the ROM permanently, they can simply burn their own EPROM and plug it in.

 

Let me know what you think!

 

 

 

Edited by Bruce Abbott
  • Like 2

The bitmap format is the same as a character ROM. Starting from the top left of the screen, the 1st byte (MSB to LSB) is pixels 1~8 of scan line 1, 2nd byte is pixels 1~8 of scan line 2 etc. down to scan line 8, to create character #0. Then back up and across to scan line 1 pixels 9~16, and go down getting another 8 bytes for character #2. This continues until 1000 characters have been created (8000 bytes). Color attributes can be added after that, each byte representing the foreground (bits 7~4) and background (bits 3~0) color of each character position.

 

A more advanced format might have a variable number of character patterns, with a character map to determine their positions (possibly multiple positions per pattern) on screen. It would then need a header word to tell the loader how many character patterns to expect. Two bytes are required to store the number of characters, but since the maximum is 1000 that leaves 6 bits that could be used other purposes.

 

There is a slight problem with the first character (char #0) which the Aquarius hardware repeats in the border area. There are two ways around this:-

 

1. Skip the first character, or skip the whole line (40 bytes) and start at line 2 (giving an effective resolution of 320x192).

 

2. Just make sure that character #0 is blank and/or has theme foreground and background colors. You could have an option to not adjust character #0 and just leave it with whatever is in the image, then you would still have the option of a patterned border if you want one.

 

Awesome. I am in Cartegena Columbia at the moment, so no access to my rig to get this done, but I will put time into it when I get back this coming weekend. Should be straightforward to make you a converter that outputs what you describe above. No worries on the first character. All of my work had been done at 320x192 to avoid that challenge, so, we'll go ahead and do that again this time. The input will be any 320x192 BMP image. I'll add selection options for no dither, bayer dither, floyd stein and atkinson. You should still be able to load all of that from tape. If/when you get the Supercart I we can play with flickering if you'd like. Should be able to get it done this weekend! Woot. Fun times. (Nice distraction from a CGA demo that I am a bit stalled/stuck on.)

  • Like 2

A DIP EPROM will fit if you use socket strips like this, that allow the pins to go through the pcb. Alternatively you could use a PLCC chip and smd socket (about 3.5mm height). Most smd EPROMs are OTP only, but equivalent flash chips such as the AT28C64 are not much more expensive.

 

And then there's the lazy option - don't use a socket at all, just program the chip and solder it in! I would put up with this if the other alternatives were too difficult or expensive.

Thanks! That socket strip looks like a workable solution, but it is a bit on the expensive side. It's tempting to use an EEPROM for in-place reprogramming, which would be even better than a removable ROM, so I'll certainly investigate the 28C64.

 

Now to finish my prototype ... and to decide what to put inside those "extra" fifteen character sets in the ROM ...

  • Like 1

Now to finish my prototype ... and to decide what to put inside those "extra" fifteen character sets in the ROM ...

If possible it would be nice to also have some character sets which would make converting certain games from other machines a lot easier. For example I am thinking about the Odyssey2, the ZX-Spectrum or even the Intellivision!

  • Like 2

If possible it would be nice to also have some character sets which would make converting certain games from other machines a lot easier. For example I am thinking about the Odyssey2, the ZX-Spectrum or even the Intellivision!

Definitely. We can have character sets "borrowed" from other machines, multilingual character sets, or sets devoted to specific games (I'm going to borrow an idea from the Cromemco C10 and create a dedicated set of Chess graphics). Lots of possibilities.

  • Like 2

Definitely. We can have character sets "borrowed" from other machines, multilingual character sets, or sets devoted to specific games (I'm going to borrow an idea from the Cromemco C10 and create a dedicated set of Chess graphics). Lots of possibilities.

There were quite a few ZX-81 kits that had multiple character sets some of them used to enhance games

 

 

http://www.zx81stuff.org.uk/zx81/generated/hardwareinfo/0/4KRom.html

 

Note: Out of interest have any noticeable artifacting colours been seen on NTSC TV output, similar to how some old Atari and coco games produced colours?

Edited by barnieg
  • Like 1

There were quite a few ZX-81 kits that had multiple character sets some of them used to enhance games

 

http://www.zx81stuff.org.uk/zx81/generated/hardwareinfo/0/4KRom.html

Thanks! Very interesting collection of character graphics. I was thinking of something along similar lines: different sets for different kinds of games, such as space shapes, map shapes, box and line shapes, double-sized numbers, etc. I'll be sure to post the characters that I come up with for everyone's feedback, and of course, suggestions are welcome, too!

  • Like 1

Thanks! Very interesting collection of character graphics. I was thinking of something along similar lines: different sets for different kinds of games, such as space shapes, map shapes, box and line shapes, double-sized numbers, etc. I'll be sure to post the characters that I come up with for everyone's feedback, and of course, suggestions are welcome, too!

I came across this yesterday

 

http://www.fruitcake.plus.com/Sinclair/ZX81/Chroma/ChromaInterface_GraphicsSupport.htm

 

The features include additional character sets, ram and hi res

Edited by barnieg
  • Like 1

The bitmap format is the same as a character ROM. Starting from the top left of the screen, the 1st byte (MSB to LSB) is pixels 1~8 of scan line 1, 2nd byte is pixels 1~8 of scan line 2 etc. down to scan line 8, to create character #0. Then back up and across to scan line 1 pixels 9~16, and go down getting another 8 bytes for character #2. This continues until 1000 characters have been created (8000 bytes). Color attributes can be added after that, each byte representing the foreground (bits 7~4) and background (bits 3~0) color of each character position.

 

A more advanced format might have a variable number of character patterns, with a character map to determine their positions (possibly multiple positions per pattern) on screen. It would then need a header word to tell the loader how many character patterns to expect. Two bytes are required to store the number of characters, but since the maximum is 1000 that leaves 6 bits that could be used other purposes.

 

There is a slight problem with the first character (char #0) which the Aquarius hardware repeats in the border area. There are two ways around this:-

 

1. Skip the first character, or skip the whole line (40 bytes) and start at line 2 (giving an effective resolution of 320x192).

 

2. Just make sure that character #0 is blank and/or has the same foreground and background colors. You could have an option to not adjust character #0 and just leave it with whatever is in the image, then you would still have the option of a patterned border if you want one.

 

 

convrun.bmp

lweap.bmp

lweapatk.bmp

cheetara.bmp

dcoke.bmp

fred.bmp

 

This is examples of what is possible. I got the converter to put out the right image. Now I just have to capture the character set and output it properly. It'll be full-featured soon enough. I figure I can output a character set that can get loaded into Virtual Aquarius and then some kind of loader and everyone can enjoy images. Bruce - is the Virtual Aquarius character set image the same format you need?

 

EDIT: I just realized that I will only have 256 characters and since the screen size is 40x24 that it needs 960 characters (or 1024) so... I could optimize it to only 256 characters, but that doesn't max out Bruce's mod. We'll start with getting Bruce what he needs.

Edited by chjmartin2
  • Like 2

Bruce - you should be able to add your code to make the character map file to the below. The file below will output the attribute bytes. This upgraded code lets you adjust gamma, brightness, contrast, and dither attributes with preview. Small adjustments in brightness or contrast can have a dramatic output. I tend to prefer the Atkinson dithering (press D) without gamma correction. I wasn't sure if you just wanted me to go ahead and code the character output, I got lazy and then realized you had already done it. I can come back to it if you want...

 

 

 

#lang "fblite"
#define WIN_INCLUDEALL
 
#include once "windows.bi"
#include "fbgfx.bi"
 
 
function file_getname( byval hWnd as HWND ) as string
 
        dim ofn as OPENFILENAME
        dim filen as zstring * MAX_PATH+1
        dim filemask as string
        
        filemask = "BMP Files, (*.BMP)"+chr$(0)+"*.BMP"+chr$(0)+chr$(0)
        with ofn
                .lStructSize           = sizeof( OPENFILENAME )
                .hwndOwner             = hWnd
                .hInstance             = GetModuleHandle( NULL )
                .lpstrFilter           = strptr( filemask )
                .lpstrCustomFilter     = NULL
                .nMaxCustFilter        = 0
                .nFilterIndex          = 1
                .lpstrFile             = @filen
                .nMaxFile              = sizeof( filen )
                .lpstrFileTitle        = NULL
                .nMaxFileTitle         = 0
                .lpstrInitialDir       = NULL
                .lpstrTitle            = @"Select BMP File to Process..."
                .Flags                 = OFN_EXPLORER or OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST
                .nFileOffset           = 0
                .nFileExtension        = 0
                .lpstrDefExt           = NULL
                .lCustData             = 0
                .lpfnHook              = NULL
                .lpTemplateName        = NULL
        end with
        
        if( GetOpenFileName( @ofn ) = FALSE ) then
                return ""
        else
                return filen
        end if
 
end Function 
 
DIM shared image(320, 200) as Integer, apal(15,3), imz(320,200,3), charo(8, 8,3), COLL(16), codis(16, 16), outbmp(320, 200), outcol(40, 25, 2), collok(16), FOUTCHAR(960), FOUTFORE(960), FOUTBACK(960)
DIM shared imgload(320*200) AS Integer, charmap(511,7,7), matches(255,255), imagein(320,200,3) as Integer, imout(639,199), imageinbak(320,200,3) as Integer
Dim shared ret As String, graphchar(255),gpal(3,3), mixcharo(8,8,3) as integer, outchars(40, 25,2) as integer, outchar(40,25), mixpals(15,15,15,15,4,3) as Integer,charoout(8,8,3)
Dim Shared ImageOut(320,200,3),mixedpal(15,15,3),palcount(40,50,15),palout(40,50,4),colorcombos(136,2) As Integer, diffsq(255,255) As Integer, sqrt(195075), FrFinalOne(4006) As UByte, FrFinalTwo(4006) As UByte
DIM Shared bloxin(40,25,3) as Integer, palavg(15,15,15,15,3), lumen(15) as Integer, imageintwobak(320,200,3) as Integer, imgtwo(320*200) AS Integer
DIM Shared rgbtolin(255) as Integer, lintorgb(255) as Integer, ddpal(15,3) as Integer, rgbdist(3) as Integer
DIM Shared initpal(40,50,4) as Integer, outpal(4,3) as Integer
Dim Shared Lummix(511,15,15) as integer, imagelum(40,25) as integer, fild as integer
Dim Shared totaldist as Integer, mindist as Integer, rdist as Integer, gdist as Integer, bdist as Integer
dim Shared abst(256,256) as Integer
Dim Shared newoutpal(40,25,4,7) As Integer,FrOutOne(1000) As UByte
Dim Shared mixchars(511,511,7,7) as Integer
Dim Shared coldist(15,15) As Integer
Dim Shared imagework(320,200,4) as Integer
Dim Shared Bayer(7,7) as Single
dim Shared colmat(15,15,15,15) as Integer
Dim Shared CharSet(511) as Integer
Dim Shared CharCounts(511,4) As Integer
Dim Shared OutCounts(40,25,4) as Integer
Dim Shared CDist(511,40,25) As Integer
Dim Shared CharOneF(7,7) as Integer, CharTwoF(7,7) as Integer
Dim Shared ImageFrOne(320,200,3) As Integer, ImageFrTwo(320,200,3) As Integer
Dim Shared alpha As Single, ra As Single, rg As Single, rb As Single, gamma As Single
Dim Shared AltMatrix(20,7,7) As Single
Dim Shared MName(20) As String 
Dim Shared BigCharMap(1024, 8, As Integer
Dim Shared BigCharMapOut(1024* As UByte
 
dither=1
alpha=1
beta=0
atk=8
lumdiff=255
DTH=.5
limit=0
bayeralpha=32
bayerbeta=-32
cartoonmode=0
distmastlimit=6
ra=1
rg=1
rb=1
altmat=1
gamma=2.2
gammacont=1
 
Screenres 960,800,32: Cls
'LOCATE 1, 1
FILENAME$ = "-"
TOGGLE = 0
 
filename$=file_getname(NULL)
 
FOR i = 1 TO 16
  FOR j = 1 TO 16
     READ codis(i, j)
     'LOCATE 2, 1: PRINT "Index "; i; j
  NEXT j
NEXT i
 
 
 
for t=0 to 255
    'rgbtolin(t)=Int(255*((t/255)^2.2))
    'lintorgb(t)=Int(255*((t/255)^(1/2.2)))
    rgbtolin(t)=t
    lintorgb(t)=t
    
    
    'print t;"  ";rgbtolin(t);"  ";lintorgb(t);"   "
next t
 
FOR i = 0 TO 15
 
  READ collok(i)
  'LOCATE 4, 1: PRINT "Color "; i; collok(i)
NEXT i
 
for j=0 to 15
   read ddpal(j,1)
   read ddpal(j,2)
   read ddpal(j,3)
   
   apal(j,1)=rgbtolin(ddpal(j,1))
   apal(j,2)=rgbtolin(ddpal(j,2))
   apal(j,3)=rgbtolin(ddpal(j,3))
   'lumen(j)=sqr(0.241*apal(j,1)^2 + 0.691*apal(j,2)^2 + 0.068*apal(j,3)^2)
   'lumen(j)=(apal(j,1)+apal(j,2)+apal(j,3))/3
   lumen(j)=0.2126*apal(j,1)+0.7152*apal(j,2)+0.0722*apal(j,3)
next j
 
for c=1 to 3
    gpal(1,c)=0
    gpal(2,c)=128
    gpal(3,c)=255
next c
 
 
 
bstart=15
astart=15
 
for a=0 to 15
    for b=0 to 15
        for c=1 to 3
            mixedpal(a,b,c)=(int(((apal(a,c))+(apal(b,c)))/2))
        next c
    next b
next a
 
 
                
 
 
'locate 5,1:print "Mixing Palettes..."
 
for a=0 to 15
    for b=0 to 15
        for c=0 to 15
            for d=0 to 15
                for i=1 to 3
                    mixpals(a,b,c,d,1,i)=int((apal(a,i)+apal(c,i))/2)
                    mixpals(a,b,c,d,2,i)=int((apal(a,i)+apal(d,i))/2)
                    mixpals(a,b,c,d,3,i)=int((apal(b,i)+apal(c,i))/2)
                    mixpals(a,b,c,d,4,i)=int((apal(b,i)+apal(d,i))/2)
                
                    palavg(a,b,c,d,i)=255*(((((mixpals(a,b,c,d,1,i)/255)^2.2)+((mixpals(a,b,c,d,2,i)/255)^2.2)+((mixpals(a,b,c,d,3,i)/255)^2.2)+((mixpals(a,b,c,d,4,i)/255)^2.2))/4)^(1/2.2))
                
                    'palavg(a,b,c,d,i)=int((mixpals(a,b,c,d,1,i)+mixpals(a,b,c,d,2,i)+mixpals(a,b,c,d,3,i)+mixpals(a,b,c,d,4,i))/4)
                
                    if palavg(a,b,c,d,i)<0 then palavg(a,b,c,d,i)=0
                    if palavg(a,b,c,d,i)>255 then palavg(a,b,c,d,i)=255
                    
                next i
            next d
        next c
    next b
next a
 
 
countme=0
while yostop<>999
    countme=countme+1
    read lbj
    if lbj<>999 then graphchar(lbj)=lbj
    if lbj=999 then yostop=999
wend
 
'Read Alternate Matrices
For bv=1 To 13
    For y=0 To 7
        For x=0 To 7
           Read v
           AltMatrix(bv,x,y)=v/64
        Next x
    Next y
Next bv
 
For bv=1 To 13
    Read MName(bv)
Next bv
 
 
 
'print "combos: ";combos;"          "
'input gh$
 
for t=0 to 255
    For y=0 To 255
        diffsq(t,y)=(t-y)^2
    next y
next t
 
For t=0 To 195075
    sqrt(t)=sqr(t)
next t
 
 
for t=0 to 511
 
        for h=0 to 7
            for g=0 to 7
                mixchars(t,d,g,h)=charmap(t,g,h)*2+charmap(d,g,h)*1+1
                
                CharCounts(t,charmap(t,g,h)+1)=CharCounts(t,charmap(t,g,h)+1)+1
                'locate 1,1:print "mixchars(t,d,h,g):";mixchars(t,d,h,g)
                'locate 2,1:print "charmap(t,h,g):";charmap(t,h,g)
                'locate 3,1:print "charmap(d,h,g):";charmap(d,h,g)*1
                'locate 4,1:print "t,d,h,g: ";t,d,h,g
                'locate 5,1:print "charmap(t,h,g)*2:";charmap(t,h,g)*2
                
                
                'if mixchars(t,d,g,h)=0 then print "HEY HEY HEY": input gh$
                
            next g
        Next h
 
next t
 
 
For t=0 To 255
    for y=0 to 255
        abst(t,y)=abs(t-y)
    next y
next t
 
for a=0 to 15
    for b=0 to 15
 
      
                'coldist(a,b,c,d)=sqrt(diffsq(mixedpal(a,b,1),mixedpal(c,d,1))+diffsq(mixedpal(a,b,2),mixedpal(c,d,2))+diffsq(mixedpal(a,b,3),mixedpal(c,d,3)))
                'coldist(a,b)=sqrt(.2126*diffsq(apal(a,1),apal(b,1))+.7152*diffsq(apal(a,2),apal(b,2))+.0722*diffsq(apal(a,3),apal(b,3)))
                coldist(a,b)=sqrt(diffsq(apal(a,1),apal(b,1))+diffsq(apal(a,2),apal(b,2))+diffsq(apal(a,3),apal(b,3)))
                'if a=c and b=d then colmat(a,b,c,d)=colmat(a,b,c,d)+1
                'if a=b then colmat(a,b,c,d)=colmat(a,b,c,d)+.25
                'if c=d then colmat(a,b,c,d)=colmat(a,b,c,d)+.25
                'locate 1,1:print "a,b,c,d: ";a;b;c;d;"           "
                'locate 2,1:print "coldist(a,b,c,d): ";coldist(a,b,c,d);"        "
                'input ghb$
               
 
    Next b
next a
 
for t=1 to len(filename$)
    if mid(filename$,t,1)="\" then positionslash=t
next t
 
SAVENAME$=Left$(Right$(filename$,Len(filename$)-positionslash),Len(Right$(filename$,Len(filename$)-positionslash))-4)
 
'basename$=Left$(savename$,Len(savename$)-7)
 
'Locate 1,1:Input "Enter Number of Frames: ",frames
 
'Locate 1,1:Print "savename: ";savename$ 
'Input gh$
 
Hardreset:
 
START:
 
begintimer=Timer
 
 
frameone=0
 
 
Locate 78,10:Print "[1/2,3/4,5/6] R, G, B: ";Int(ra)*100;Int(rg)*100;Int(rb)*100;"         "
Locate 80,10:Print "[D,F,A] Dith, Full, Atk:";dither;"     "
Locate 82,10:Print "[O,P] Contrast:        ";alpha;"     "        
Locate 84,10:Print "[K,L] Brightness:      ";beta;"     "
Locate 86,10:Print "[Q] Dither Select:     ";Mname(altmat);"                                             "
Locate 87,10:Print "[G] Gamma On/Off:      ";gammacont;"                         " 
Locate 88,10:Print "[T,Y} Gamma:           ";gamma;"                                 "       
Locate 78,60:Print "[N,M] Bayer Strength:  ";bayeralpha;"     "
Locate 80,60:Print "[U,I] Bayer Offset:    ";bayerbeta;"     "
Locate 82,60:Print "[H,J] Focus / Blur:    ";distmastlimit;"     "
 
Locate 88,60:Print "(X) to Finish:          ";paused;"        "
Locate 90,10:Print "(R) to Redraw"
 
 
  
'For fard=0 To frames 'step 120
 
cycleloop:
 
mb$=Ucase$(Inkey$)
 
If mb$="D" Then dither = 1:Goto donekey
If mb$="F" Then dither = 0:Goto DONEKEY 
If mb$="A" Then dither = 3:Goto DONEKEY
If mb$="P" Then alpha=alpha+.1:Goto donekey
If mb$="O" Then alpha=alpha-.1:Goto donekey
If mb$="L" Then beta=beta+1:Goto donekey
If mb$="K" Then beta=beta-1:Goto donekey
If mb$="M" Then bayeralpha=bayeralpha+1:Goto donekey
If mb$="N" Then bayeralpha=bayeralpha-1:Goto donekey
If mb$="I" Then bayerbeta=bayerbeta+1:Goto donekey
If mb$="U" Then bayerbeta=bayerbeta-1:Goto donekey
If mb$="J" Then distmastlimit=distmastlimit+1:Goto donekey
If mb$="H" Then distmastlimit=distmastlimit-1:Goto donekey
If mb$="X" Then paused=1:Goto donekey
If mb$="1" Then ra=ra-1:Goto donekey
If mb$="2" Then ra=ra+1:Goto donekey
If mb$="3" Then rg=rg-1:Goto donekey
If mb$="4" Then rg=rg+1:Goto donekey
If mb$="5" Then rb=rb-1:Goto donekey
If mb$="6" Then rb=rb+1:Goto donekey
If mb$="T" Then gamma=gamma-.01:Goto donekey
If mb$="Y" Then gamma=gamma+.01:Goto donekey
 
If mb$="G" Then
 
        If gammacont=0 Then
 
            gammacont=1
            Goto donekey
        End If
        
        
        If gammacont=1 Then
 
 
            gammacont=0
            Goto donekey
        End If
End If    
 
 
If gammacont = 0 Then
            For t=0 To 255
                rgbtolin(t)=t
                lintorgb(t)=t
            Next t
End If
              
If gammacont = 1 Then
            For t=0 To 255
                rgbtolin(t)=Int(255*((t/255)^gamma))
                lintorgb(t)=Int(255*((t/255)^(1/gamma)))
            Next t
End If
 
For j=0 To 15
 
   apal(j,1)=rgbtolin(ddpal(j,1))
   apal(j,2)=rgbtolin(ddpal(j,2))
   apal(j,3)=rgbtolin(ddpal(j,3))
   lumen(j)=0.2126*apal(j,1)+0.7152*apal(j,2)+0.0722*apal(j,3)
Next j 
         
If mb$="Q" Then 
    altmat=altmat+1
    If altmat=14 Then altmat=1
    Goto donekey    
End If
 
If mb$="R" Then Goto hardreset
 
Goto skipkey
 
donekey:
           
mb$=""                                    
 
Locate 78,10:Print "[1/2,3/4,5/6] R, G, B: ";Int(ra/255*100);Int(rg/255*100);Int(rb/255*100);"         "
Locate 80,10:Print "[D,F,A] Dith, Full, Atk:";dither;"     "
Locate 82,10:Print "[O,P] Contrast:        ";alpha;"     "        
Locate 84,10:Print "[K,L] Brightness:      ";beta;"     "
Locate 86,10:Print "[Q] Dither Select:     ";Mname(altmat);"                                         "
Locate 87,10:Print "[G] Gamma On/Off:      ";gammacont;"                         " 
Locate 88,10:Print "[T,Y} Gamma:           ";gamma;"                                 "                                                 
Locate 78,60:Print "[N,M] Bayer Strength:  ";bayeralpha;"     "
Locate 80,60:Print "[U,I] Bayer Offset:    ";bayerbeta;"     "
Locate 82,60:Print "[H,J] Focus / Blur:    ";distmastlimit;"     "
Locate 88,60:Print "(X) to Exit:          "
Locate 90,10:Print "(R) to Redraw"
 
pauseman:
If paused = 1 Then
    
    Locate 88,60: Print "Exiting..."
    Goto SAVEITGEORGE
    paused=0
End If
       
skipkey:
 
opfile$=filename$
svfile$="OUT.IMG"
svfile2$="OUT.CHR"
 
'print "opfile: ";opfile$;"        "
'print "svfile: ";svfile$;"        "
 
'input gh$
 
Line(0,0)-(320,200),Rgb(0,0,0),bf
 
BLoad opfile$,@imgload(0)
put (0,1),imgload(0)
 
for y=1 to 200
    for x=1 to 320
      imagein(x,y,3)=imgload((y-1)*320+x) And 255
      imagein(x,y,2)=(imgload((y-1)*320+x) and 65280)\256
      imagein(x,y,1)=(imgload((y-1)*320+x) and 16711680)\65536
      
      for c=1 to 3
          imagein(x,y,c)=rgbtolin(imagein(x,y,c))
      Next c
 
      If dither = 1 Then   
            For c=1 To 3
                imagein(x,y,c) = imagein(x,y,c)+(altmatrix(altmat,(x-1) Mod 8,(y-1) Mod *bayeralpha)+bayerbeta
            Next c
      End If 
 
      imagein(x,y,1)=ra+imagein(x,y,1)
      imagein(x,y,2)=rg+imagein(x,y,2)
      imagein(x,y,3)=rb+imagein(x,y,3)
 
      for c=1 to 3
          imagein(x,y,c)=alpha*imagein(x,y,c)+beta
          If imagein(x,y,c)>255 Then imagein(x,y,c)=255
          If imagein(x,y,c)<0 Then imagein(x,y,c)=0
      next c
 
 
      for c=1 to 3
          imageinbak(x,y,c)=imagein(x,y,c)
      next c
 
    next x
next y
 
For x=1 To 320
    for y=1 to 200
        
 
        
        'for c=1 to 3
          'if imagein(x,y,c)>=255 then imagein(x,y,c)=255
          'If imagein(x,y,c)<=0 Then imagein(x,y,c)=0
        'next c   
        
        'For c=1 To 3
            'imageinbak(x,y,c)=imagein(x,y,c)
        'Next c
        
        Pset(x+320,y),Rgb(lintorgb(imagein(x,y,1)),lintorgb(imagein(x,y,2)),lintorgb(imagein(x,y,3)))
        
        
    
    next y
next x
 
'locate 1,80:print"Post Dither Image..."
'input gh$
 
erase palcount
 
for y=1 to 200
    for x=1 to 320
    
      for c=1 to 3
          if imagein(x,y,c)>=255 then imagein(x,y,c)=255
          if imagein(x,y,c)<=0 then imagein(x,y,c)=0
      next c      
 
      mindist=50000:mina=16
            For a=0 To 15
                colordist=Sqr(diffsq(imagein(x,y,1),apal(a,1))+diffsq(imagein(x,y,2),apal(a,2))+diffsq(imagein(x,y,3),apal(a,3)))
                        'locate 13,42:print "colordist:";colordist
                        if colordist<=mindist then 
                        mindist=colordist:mina=a
                        end if
 
stopcalc:                
            Next a
 
            rgbdist(1)=imagein(x,y,1)-apal(mina,1)  ' calculate error in R dimension
            rgbdist(2)=imagein(x,y,2)-apal(mina,2)  ' calculate error in G dimension
            rgbdist(3)=imagein(x,y,3)-apal(mina,3)  ' calculate error in B dimension
 
            For c=1 To 3
                imagein(x,y,c)=apal(mina,c)
            next c
 
            Pset(x+640,y),Rgb(ddpal(mina,1),ddpal(mina,2),ddpal(mina,3))
 
            palcount(Int((x-1)/8)+1,Int((y-1)/8)+1,mina)=palcount(Int((x-1)/8)+1,Int((y-1)/8)+1,mina)+1
            
            If dither=3 Then  
             
                For c=1 To 3
                    
                    'imagein(x+1,y,c)=imagein(x+1,y,c)+(7/16)*rgbdist(c)
 
 
                    'imagein(x+1,y+1,c)=imagein(x+1,y+1,c)+(1/16)*rgbdist(c)
 
                    
                    'imagein(x,y+1,c)=imagein(x,y+1,c)+(5/16)*rgbdist(c)
 
                    'imagein(x-1,y+1,c)=imagein(x-1,y+1,c)+(3/16)*rgbdist(c)
 
                    
                    
                    imagein(x+1,y,c)=imagein(x+1,y,c)+(1/atk)*rgbdist(c)
                    imagein(x+2,y,c)=imagein(x+2,y,c)+(1/atk)*rgbdist(c)
                    imagein(x-1,y+1,c)=imagein(x-1,y+1,c)+(1/atk)*rgbdist(c)
                    imagein(x,y+1,c)=imagein(x,y+1,c)+(1/atk)*rgbdist(c)
                    imagein(x+1,y+1,c)=imagein(x+1,y+1,c)+(1/atk)*rgbdist(c)
                    imagein(x,y+2,c)=imagein(x,y+2,c)+(1/atk)*rgbdist(c)
                    
                    
                    
                    'imagein(x+1,y+1,c)=imagein(x,y,c)
                    'imagein(x,y+1,c)=imagein(x,y+1,c)+(1/2)*rgbdist(c)
                    'imagein(x+1,y,c)=imagein(x+1,y,c)+(1/2)*rgbdist(c)
 
                    
                              
                Next c 
            End If
            
            
            
            
            
            
            
            
            
            
            
    Next x
next y
 
for ychar=1 to 25
    For xchar=1 To 40
            
            maxa=-1:maxval=0
            For a=0 To 15
                If palcount(xchar,ychar,a)>maxval And palcount(xchar,ychar,a)>0 Then 
                     maxval=palcount(xchar,ychar,a):maxa=a
                End If  
                
                'If palcount(xchar,ychar,a)<minval And palcount(xchar,ychar,a)>0 Then 
                     'minval=palcount(xchar,ychar,a):minb=a
                'End If 
                
                
babycalc:
            Next a
 
            minpaltotaldist=9999999:mina=16:minb=16:minc=16:mind=16
 
            a=maxa
 
                For b=0 To 15
 
                   For k=1 To 3
                        outpal(1,k)=apal(a,k)
                        outpal(2,k)=apal(b,k)
                    Next k
                    
                   paltotaldist=0
                    
                    
                    For v=0 To 15
 
                            If palcount(xchar,ychar,v)=0 Then Goto skiptomylou
                            minm=5:mindist=50000
                            For m=1 To 2
 
                                colordist=Sqr(diffsq(outpal(m,1),apal(v,1))+diffsq(outpal(m,2),apal(v,2))+diffsq(outpal(m,3),apal(v,3)))
                                If colordist<mindist Then minm=m:mindist=colordist:minv=v
                           Next m
                            
                            paltotaldist=paltotaldist+mindist*palcount(xchar,ychar,v)
skiptomylou:                            
 
                    Next v
                    
                    If paltotaldist<minpaltotaldist Then minpaltotaldist=paltotaldist:mina=a:minb=b
                    
nocalc:
 
 
               Next b
                    
            palout(xchar,ychar,1)=mina
            palout(xchar,ychar,2)=minb
 
    next xchar
next ychar
 
for y=1 to 200
    for x=1 to 320
        For c=1 To 3
            imagein(x,y,c)=imageinbak(x,y,c)
            'imagefrone(x,y,c)=imageinbak(x,y,c)
            'imagefrtwo(x,y,c)=imageinbak(x,y,c)
        next c
        
        pset(x,y+200),rgb(lintorgb(imagein(x,y,1)),lintorgb(imagein(x,y,2)),lintorgb(imagein(x,y,3)))
        
        
    next x
next y
 
erase outcounts
 
for y=1 to 200
    for x=1 to 320
        xchar=int((x-1)/8)+1
        ychar=int((y-1)/8)+1
        
      for c=1 to 3
          if imagein(x,y,c)>=255 then imagein(x,y,c)=255
          if imagein(x,y,c)<=0 then imagein(x,y,c)=0
      next c
      
      premindist=50000:minn=5
      For n=1 To 2
 
                    'precolordist=sqrt(.2126*diffsq(imagein(x,y,1),apal(palout(xchar,ychar,n),1))+.7152*diffsq(imagein(x,y,2),apal(palout(xchar,ychar,n),2))+.0722*diffsq(imagein(x,y,3),apal(palout(xchar,ychar,n),3)))
                    precolordist=sqrt(diffsq(imagein(x,y,1),apal(palout(xchar,ychar,n),1))+diffsq(imagein(x,y,2),apal(palout(xchar,ychar,n),2))+diffsq(imagein(x,y,3),apal(palout(xchar,ychar,n),3)))
                    
                    if precolordist<premindist then 
                      premindist=precolordist:minn=n
                    end if
      next n
            
            rgbdist(1)=imagein(x,y,1)-apal(palout(xchar,ychar,minn),1)  ' calculate error in R dimension
            rgbdist(2)=imagein(x,y,2)-apal(palout(xchar,ychar,minn),2)  ' calculate error in G dimension
            rgbdist(3)=imagein(x,y,3)-apal(palout(xchar,ychar,minn),3)  ' calculate error in B dimension
            
            For c=1 To 3
                imagein(x,y,c)=apal(palout(xchar,ychar,minn),c)
            next c
                    
                    
            imagework(x,y,1)=palout(xchar,ychar,minn) 
            outcounts(xchar,ychar,minn)=outcounts(xchar,ychar,minn)+1
         
            Pset(x+320,y+200),Rgb(lintorgb(imagein(x,y,1)),lintorgb(imagein(x,y,2)),lintorgb(imagein(x,y,3)))
            'pset(x+700,y),rgb(lintorgb(mixedpal(imagework(x,y,1),imagework(x,y,2),1)),lintorgb(mixedpal(imagework(x,y,1),imagework(x,y,2),2)),lintorgb(mixedpal(imagework(x,y,1),imagework(x,y,2),3)))
            Pset(x+640,y+200),Rgb(ddpal(imagework(x,y,1),1),ddpal(imagework(x,y,1),2),ddpal(imagework(x,y,1),3))
            
            If dither=3 Then  
             
                For c=1 To 3
 
                    imagein(x+1,y,c)=imagein(x+1,y,c)+(1/atk)*rgbdist(c)
                    imagein(x+2,y,c)=imagein(x+2,y,c)+(1/atk)*rgbdist(c)
                    imagein(x-1,y+1,c)=imagein(x-1,y+1,c)+(1/atk)*rgbdist(c)
                    imagein(x,y+1,c)=imagein(x,y+1,c)+(1/atk)*rgbdist(c)
                    imagein(x+1,y+1,c)=imagein(x+1,y+1,c)+(1/atk)*rgbdist(c)
                    imagein(x,y+2,c)=imagein(x,y+2,c)+(1/atk)*rgbdist(c)
 
                              
                Next c 
           End If    
            
    next x
next y
 
CLOSE #1
 
Goto cycleloop
 
SAVEITGEORGE: 
 
posit=-1
 
frameoneout$=svfileone$+str$(frameone)+".DMP"
 
for row=1 to 25
    for col=1 to 40
        
        posit=posit+1
    
        froutone(posit)=palout(col,row,1)*16+palout(col,row,2)
        'fore is first 4 bits, back is second 4 bits
 
    posit=posit+1
        
    next col
next row
 
open frameoneout$ for binary as #2
 
put #2,,froutone()
 
close #2
 
Input gh$
 
'next fard
 
totaltime=Timer-begintimer
 
End
 
REM Color Distance Lookup Table:  16x16 Array
 
Data 0,138,203,227,163,263,351,320,68,215,239,265,239,337,330,442
Data 138,0,199,153,146,144,293,226,93,92,258,184,217,215,308,341
DATA 203,199,0,111,218,267,223,207,156,231,63,132,284,336,220,311
DATA 227,153,111,0,228,205,228,157,170,144,169,37,294,266,263,261
Data 163,146,218,228,0,162,240,228,122,230,260,256,81,228,219,339
DATA 263,144,267,205,162,0,235,160,207,162,325,217,182,76,273,250
DATA 351,293,223,228,240,235,0,113,288,321,244,222,244,265,90,156
DATA 320,226,207,157,228,160,113,0,253,228,252,146,252,189,187,121
DATA 68,93,156,170,122,207,288,253,0,174,203,206,203,283,277,374
DATA 215,92,231,144,230,162,321,228,174,0,293,163,293,215,357,328
DATA 239,258,63,169,260,325,244,252,203,293,0,184,321,393,227,345
DATA 265,184,132,37,256,217,222,146,206,163,184,0,316,270,268,238
DATA 239,217,284,294,81,182,244,252,203,293,321,316,0,227,218,345
DATA 337,215,336,266,228,76,265,189,283,215,393,270,227,0,315,245
DATA 330,308,220,263,219,273,90,187,277,357,227,268,218,315,0,246
DATA 442,341,311,261,339,250,156,121,374,328,345,238,345,245,246,0
 
DATA 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
 
Data 0,0,0
Data 54,11,126
Data 25,194,54
Data 32,159,159
Data 159,25,25
Data 185,25,185
Data 238,238,101
Data 185,185,185
Data 39,39,39
Data 25,25,212
Data 11,238,11
Data 39,185,185
Data 238,11,11
Data 238,11,238
Data 238,229,11
Data 255,255,255
 
Data 15,133,163,183,203,226,246
Data 16,134,164,184,204,227,247
Data 17,135,165,185,205,228,248
Data 18,136,166,186,206,229,249
Data 26,137,167,187,207,230,250
Data 27,142,168,188,208,231,251
Data 28,143,169,189,209,232,252
Data 29,144,170,190,210,233,253
Data 30,145,171,191,214,234,254
Data 31,148,172,192,215,235
Data 46,149,173,193,216,236
Data 58,150,174,194,217,237
Data 61,151,175,195,218,238
Data 92,152,176,196,219,239
Data 95,153,177,197,220,240
Data 124,158,178,198,221,241
Data 127,159,179,199,222,242
Data 128,160,180,200,223,243
Data 129,161,181,201,224,244
Data 132,162,182,202,225,245,999
 
'Dither Matrix
'DATA 1,9,3,11
'DATA 13,5,15,7
'DATA 4,12,2,10
'DATA 16,8,14,6
 
'DATA 1,1,11,11
'DATA 1,1,11,11
'DATA 16,16,6,6
'DATA 16,16,6,6
 
'DATA 1,11,1,11
'DATA 16,6,16,6
'DATA 1,11,1,11
'DATA 16,6,16,6
 
'DATA 16,16,16,11
'DATA 16,16,11,6
'DATA 16,11,6,6
'DATA 11,6,6,6
 
'data 3,7,4
'data 6,1,9
'data 2,8,5
 
'DATA 1,3
'DATA 4,2
 
Data 1,49,13,61,4,52,16,64
Data 33,17,45,29,36,20,48,32
Data 9,57,5,53,12,60,8,56
Data 41,25,37,21,44,28,40,24
Data 3,51,15,63,2,50,14,62
Data 35,19,47,31,34,18,46,30
Data 11,59,7,55,10,58,6,54
Data 43,27,39,23,42,26,38,22
 
Data 3,33,11,41,3,33,11,41
Data 48,18,56,26,48,18,56,26
Data 15,45,7,37,15,45,7,37
Data 60,30,52,22,60,30,52,22
Data 3,33,11,41,3,33,11,41
Data 48,18,56,26,48,18,56,26
Data 15,45,7,37,15,45,7,37
Data 60,30,52,22,60,30,52,22
 
DATA 12,38,12,38,12,38,12,38
Data 51,25,51,25,51,25,51,25
Data 12,38,12,38,12,38,12,38
Data 51,25,51,25,51,25,51,25
Data 12,38,12,38,12,38,12,38
Data 51,25,51,25,51,25,51,25
Data 12,38,12,38,12,38,12,38
Data 51,25,51,25,51,25,51,25
 
Data 64,1,64,1,64,1,64,1
Data 1,64,1,64,1,64,1,64
Data 64,1,64,1,64,1,64,1
Data 1,64,1,64,1,64,1,64
Data 64,1,64,1,64,1,64,1
Data 1,64,1,64,1,64,1,64
Data 64,1,64,1,64,1,64,1
Data 1,64,1,64,1,64,1,64
 
Data 01,01,64,64,01,01,64,64
Data 01,01,64,64,01,01,64,64
Data 64,64,01,01,64,64,01,01
Data 64,64,01,01,64,64,01,01
Data 01,01,64,64,01,01,64,64
Data 01,01,64,64,01,01,64,64
Data 64,64,01,01,64,64,01,01
Data 64,64,01,01,64,64,01,01
 
Data 0,0,0,0,64,64,64,64
Data 0,0,0,0,64,64,64,64
Data 0,0,0,0,64,64,64,64
Data 0,0,0,0,64,64,64,64
Data 64,64,64,64,0,0,0,0
Data 64,64,64,64,0,0,0,0
Data 64,64,64,64,0,0,0,0
Data 64,64,64,64,0,0,0,0
 
Data 12,12,38,38,12,12,38,38
Data 12,12,38,38,12,12,38,38
Data 51,51,25,25,51,51,25,25
Data 51,51,25,25,51,51,25,25
Data 12,12,38,38,12,12,38,38
Data 12,12,38,38,12,12,38,38
Data 51,51,25,25,51,51,25,25
Data 51,51,25,25,51,51,25,25
 
Data 12,12,12,12,38,38,38,38
Data 12,12,12,12,38,38,38,38
Data 12,12,12,12,38,38,38,38
Data 12,12,12,12,38,38,38,38
Data 51,51,51,51,25,25,25,25
Data 51,51,51,51,25,25,25,25
Data 51,51,51,51,25,25,25,25
Data 51,51,51,51,25,25,25,25
 
Data 1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1
Data 1,1,1,64,64,1,1,1
Data 1,1,64,64,64,64,1,1
Data 1,1,64,64,64,64,1,1
Data 1,1,1,64,64,1,1,1
Data 1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1
 
Data 64,64,64,64,64,64,64,64
Data 64,64,1,1,1,1,64,64
Data 64,1,1,64,64,1,1,64
Data 64,1,64,64,64,64,1,64
Data 64,1,64,64,64,64,1,64
Data 64,1,1,64,64,1,1,64
Data 64,64,1,1,1,1,64,64
Data 64,64,64,64,64,64,64,64
 
Data 1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1
Data 1,1,1,1,1,1,1,1
Data 64,64,64,64,64,64,64,64
Data 64,64,64,64,64,64,64,64
Data 64,64,64,64,64,64,64,64
Data 64,64,64,64,64,64,64,64
 
Data 64,64,64,64,1,1,1,1
Data 64,64,64,64,1,1,1,1
Data 64,64,64,64,1,1,1,1
Data 64,64,64,64,1,1,1,1
Data 64,64,64,64,1,1,1,1
Data 64,64,64,64,1,1,1,1
Data 64,64,64,64,1,1,1,1
Data 64,64,64,64,1,1,1,1
 
Data 1,3,6,10,15,21,28,36
Data 2,5,9,14,20,27,35,43
Data 4,8,13,19,26,34,42,49
Data 7,12,18,25,33,41,48,54
Data 11,17,24,32,40,47,53,58
Data 16,23,31,39,46,52,57,61
Data 22,30,38,45,51,56,60,63
Data 29,37,44,50,55,59,62,64
 
Data "Bayer 8x8", "Bayer 4x4", "Bayer 2x2"
Data "Checkerboard 8x8", "Checkerboard 4x4", "Checkerboard 2x2"
Data "Bayer 2x2 2X", "Bayer 2x2 4X", "Dot", "Ring"
Data "Rows", "Columns", "Gradient"

Well done! Being able to tweak all the parameters in real time is excellent

 

I removed the intermediate screens to make the window more compact, tidied the text layout, and fixed the color attributes file (the values were being saved as 16 bit integers instead of bytes).

 

Now I want to add the character map, but I can't figure out how to generate the character patterns from the image array. Can you give me a clue?

post-40459-0-83171500-1420621981_thumb.png

Edited by Bruce Abbott
  • Like 1

Well done! Being able to tweak all the parameters in real time is excellent

 

I removed the intermediate screens to make the window more compact, tidied the text layout, and fixed the color attributes file (the values were being saved as 16 bit integers instead of bytes).

 

Now I want to add the character map, but I can't figure out how to generate the character patterns from the image array. Can you give me a clue?

 

 

VERY NICE!!!

 

The way I would do it is like this - certainly not the most efficient...

 

Create an array called BigCharMap(1024,8, 8) to capture the bit values.

Use a loop: (not real code, have to check all of the math):

 

for x=1 to 320

for y=1 to 200

xchar = int((x-1)/8)

ychar = int((y-1)/8)

charpos = xchar+ychar*40

BigCharpMap(charpos, ((x-1) mod 8)+1,((y-1) mod 8)+1)= imagework(x,y,1)-1 'there is an array that has a 1 or 2 in it called Imagework.

 

next y

next x

 

Now you have an array that has the data in it, so now just loop and write it out in order. Does that help?

Edited by chjmartin2

 

 

'there is an array that has a 1 or 2 in it called Imagework.

 

Unfortunately each element had either 0, 1 or 8 in it - and even that wasn't enough to reproduce all the detail.

 

Eventually I figured out that I could create the character patterns by comparing the color of each pixel in the character to the foreground color for that character, then setting the pattern bit to 1 if it is foreground color or 0 if it isn't. Then I drew the picture again using the bits in the character patterns to select foreground/background color for each pixel. It looks identical to the original so I think I got it right...

 

Here's the relevant code:-

' color map (foreground)
for row=1 to 25
    for col=1 to 40
        attr = palout(col,row,1)
        Line(col*8+40,row*8+422)-(col*8+46,row*8+428),rgb(ddpal(attr,1),ddpal(attr,2),ddpal(attr,3)),bf
    next col
next row

' color map (background)
for row=1 to 25
    for col=1 to 40
        attr = palout(col,row,2)
        Line(col*8+386,row*8+422)-(col*8+392,row*8+428),rgb(ddpal(attr,1),ddpal(attr,2),ddpal(attr,3)),bf
    next col
next row

' display Aquarius pixels and create array of character patterns
for row=0 to 24
   for col=0 to 39
      for crow = 0 to 7
          byt = 0
          for cbit = 0 to 7
            byt = byt*2       ' shift bits left in character pattern byte
            x = col*8+cbit+1
            y = row*8+crow+1
            if ddpal(imagework(x,y,1),1) = ddpal(palout(col+1,row+1,1),1) AND ddpal(imagework(x,y,1),2) = ddpal(palout(col+1,row+1,1),2) AND ddpal(imagework(x,y,1),3) = ddpal(palout(col+1,row+1,1),3) then
              byt = byt + 1                     ' set bit in character pattern byte
              Pset(x+740,y+430),rgb(255,255,255)' white pixel = pattern bit set (foreground)  
            else
              Pset(x+740,y+430),rgb(0,0,0)      ' black pixel = pattern bit clear (background)
            end if
          next cbit
          patterns((col+row*40)*8+crow)=byt     ' 8000 pattern bytes = 1000 characters
      next crow
   next col  
next row

' Display final Aquarius screen 
for row=0 to 24
   for col=0 to 39
      for crow = 0 to 7
         byt = patterns((col+row*40)*8+crow)
         for cbit = 0 to 7
           if (byt and (2^(7-cbit))) then
             attr = palout(col+1,row+1,1) ' bit = 1 so display foreground color
           else
             attr = palout(col+1,row+1,2) ' bit = 0 so display background color
           end if
           x = col*8+cbit
           y = row*8+crow
           Pset(x+740,y+20),rgb(ddpal(attr,1),ddpal(attr,2),ddpal(attr,3))
         next cbit
      next crow
   next col  
next row


The screenshot below shows (bottom row, left to right) foreground colors, background colors, B&W pixels, and (top right) the final image. Next step - write the file out and load it into my Aquarius!

 

post-40459-0-10547400-1420676038_thumb.png

  • Like 2

Amazing work!! Anyone know how easy it would be to add this to an emulator? Would it be possible to patch Virtual Aquarius or request the authour release the source. I know Mess is available but it's quite clunky and I don't like its license (It's not open source)

 

Barnie

Sorry about that - really thought it would work the other way.

 

Regardless you got to the end! Woot. Fun stuff. It makes me want to turn it into a better version of the Aquarius image converter, the real time adjustments really let you dial in the final result.

 

Anyway - can't wait to see the Aquarius screen shots!

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...