Assuming that the problem is emulators working on the RGB model which is problematic for TV effects,
I coded the linemixer algo in RGB.
I checked on real machine, same thing, too makes a solid plane of new mixcolor, it is great!
The tool shows images like on TV, load an image and see.
The linemix() function is easily done to C.
to get it running type
javac linemix.java java linemix
it will load the image "test.png".
the source
import java.io.*; import java.util.*; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import javax.imageio.*; import javax.swing.*; import javax.swing.event.*; public class linemix { BufferedImage loadimage(File f) { try { return ImageIO.read(f); } catch (Exception e) { System.err.println("IMAGEIO.read: " + e); } return null; } void saveimage(BufferedImage img, File f, String type) { try { ImageIO.write(img, type, f); } catch (Exception e) { System.err.println("IMAGEIO.write: " + e); } } public static void main(String args[]) { new linemix().main2(args); } class framelauncher implements Runnable { int w,h; frame f; public void run() { cimg ci = new cimg(w, h); JScrollPane scroll = new JScrollPane(); scroll.setVerticalScrollBarPolicy(scroll.VERTICAL_SCROLLBAR_ALWAYS); scroll.setHorizontalScrollBarPolicy(scroll.HORIZONTAL_SCROLLBAR_ALWAYS); scroll.getViewport().add(ci); scroll.getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE); f = new frame(); f.framescr = ci; f.addKeyListener(ci); f.add(scroll); //f.add(ci); f.resize(800,600); //f.pack(); f.show(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } public class frame extends JFrame { public cimg framescr; } public class cimg extends JPanel implements KeyListener { public void keyPressed(KeyEvent e) { }// Invoked when a key has been pressed. public void keyReleased(KeyEvent e) { /*showbitmap = false; repaint();*/ }// Invoked when a key has been released. public void keyTyped(KeyEvent e) {}// Invoked when a key has been typed. BufferedImage img; int w() { return destimg.getWidth(); } int h() { return destimg.getHeight(); } int zw() { return destimg.getWidth() * zoom; } int zh() { return destimg.getHeight() * zoom; } int zoom = 3; public cimg(int w, int h) { img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); } int forcebar = 800; //force scrollbar public Dimension getMinimumSize() { return new Dimension(zw() + forcebar, zh() + forcebar); } public Dimension getPreferredSize() { return new Dimension(zw() + forcebar, zh() + forcebar); } public Dimension getMaximumSize() { return new Dimension(zw() + forcebar, zh() + forcebar); } //need .getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE); public void paint(Graphics g) { super.paint(g); Container c = getParent(); JViewport v = (JViewport)c; JScrollPane s = (JScrollPane)v.getParent(); int barx = s.getHorizontalScrollBar().getValue(); int x = barx / zoom; //g.drawImage(img, 0,0,zw(),zh(), null); synchronized (destimg) { g.drawImage(destimg, 0,0,zw(),zh(), null); } } } public void linemix() { int w = srcimg.getWidth(), h = srcimg.getHeight(); for (int y = 1 ;y < h; y++) { for (int x = 0; x < w; x++) { int rgb = srcimg.getRGB(x,y); double r = (rgb >> 16) & 0xff; double g = (rgb >> 8) & 0xff; double b = (rgb >> 0) & 0xff; double brightness = r * 0.299 + g * 0.587 + b * 0.114; if (r < 0.1) r = 0.1; //to get no div by 0 with black if (g < 0.1) g = 0.1; //to get no div by 0 with black if (b < 0.1) b = 0.1; //to get no div by 0 with black //get color part, crank up to full saturation double max = 0; if (r > max) max = r; if (g > max) max = g; if (b > max) max = b; double scale = 255.0 / max; double satr = r*scale; double satg = g*scale; double satb = b*scale; //data of previous line like on TV. I think taking next line would be wrong. int rgb2 = srcimg.getRGB(x,y - 1); double r2 = (rgb2 >> 16) & 0xff; double g2 = (rgb2 >> 8) & 0xff; double b2 = (rgb2 >> 0) & 0xff; if (r2 < 0.1) r2 = 0.1; //to get no div by 0 with black if (g2 < 0.1) g2 = 0.1; //to get no div by 0 with black if (b2 < 0.1) b2 = 0.1; //to get no div by 0 with black //get color part, crank up to full saturation double max2 = 0; if (r2 > max2) max2 = r2; if (g2 > max2) max2 = g2; if (b2 > max2) max2 = b2; double scale2 = 255.0 / max2; double satr2 = r2*scale2; double satg2 = g2*scale2; double satb2 = b2*scale2; //mix the two colors double r3 = (satr + satr2)/2.0; double g3 = (satg + satg2)/2.0; double b3 = (satb + satb2)/2.0; double brightness3 = r3 * 0.299 + g3 * 0.587 + b3 * 0.114; //take mixcolor and tweak to original brightness r = r3*brightness/brightness3; g = g3*brightness/brightness3; b = b3*brightness/brightness3; //prevent overshooting beyond 255 if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; synchronized(destimg) { destimg.setRGB(x,y,((int)r*65536)+((int)g*256)+(int)b); } } } } BufferedImage destimg; BufferedImage srcimg; public void main2(String args[]) { srcimg = loadimage(new File("test.png")); destimg = loadimage(new File("test.png")); //for same dimension in that pic framelauncher f = new framelauncher(); f.w = 640; f.h = 400; f.run(); linemix(); f.f.repaint(); } }
@sd_snatcher,
the deal is that certain colors of the palette got same brightness,
and that is the basis for getting a solid mix.
i.e. the TV can be 10% off in tone and thing still work.
I just saw brown and dark gray on real MSX1!
p.s and no it is not dithering! I saw a solid plane of new color!
p.p.s. the png must be saved in RGB, in paletted mode the tool fails.
here's a test i did in the past, PAL TMS chip
http://imgur.com/XMlCZky
@hap, I found that image some time ago, that was inspiration for my BASIC program
I am just looking at a plain monochrome shape on a color 7 sky on PAL.
The left side gets highlight, the right side gets shadow, it is unbelievable!
just make color 2,7 and look at the cursor - that is not a monochrome sprite
I feel like finding another 9918 feature, the cinch = gamer port
Well aside it is the only port on my real machine.
Why does cinch not have this reputation.
Because for example in penguin a red sprite with transparent holes having blue sky pixels shine thru makes a mess.
While the way things recently been going with twocolor sprites and scollable gfx, things are different.
This is so intriguing. I gotta try out more emulation algorithm.
@Hit9918,
Wait, what's this you're saying about 2-color sprites?
Is that ALSO an MSX1-thing?
Got a piece of code you'd perhaps like to share?
Greetings,
Ron.
some MSX1 colors have exactly same brightness. recent openmsx palette change has this fixed, however still missing is the line mixing of the TV.
openMSX always emulates RGB output. Is that what you're saying? (Note that several MSX1 machines have RGB output...)
If that's what you mean, then your tricks won't work on MSX1 machines with RGB output, right? So it's not an MSX1 feature then.
The MSX has this ability like no other homecomputer, pick a new color every line.
Did I already mention how openmsx misses a major thing hint hint
Honestly, I don't know what you mean here.
I remember there was some painting program already in the eighties for MSX1 that had the possibility to draw boxes with non-standard colors like brown using this technique. I don't remember the name of the program anymore but I recall it had a short opening music when it was started, a piece of "in the hall of the mountain king" from Peer Gynt.
SVI-728 also had this weird feature that enabled brown color instead of green in palette. It was possible to enable it by typing VDP(0)=VDP(0)OR1