This function uses the current back buffer's contents and re-renders it with the C64 color palette. Unfortunately it's too slow for real-time updates :(. I'll try to find a way for that.
// --------------------------------- //
// Project: C64izer
// Start: Tuesday, March 25, 2008
// IDE Version: 5.212
LOADBMP "test.png"
C64ize()
SHOWSCREEN
MOUSEWAIT
FUNCTION C64ize:
// weighting of color components
LOCAL x,y,c, r,g,b, dr,dg,db
LOCAL mindist, dist, ibest, i
LOCAL c64_pal[]
DIMDATA c64_pal[], _
0x00 , 0x00 , 0x00, 0, _
0xff , 0xff , 0xff, 0, _
0x88 , 0x00 , 0x00, 0, _
0xaa , 0xff , 0xee, 0, _
0xcc , 0x44 , 0xcc, 0, _
0x00 , 0xcc , 0x55, 0, _
0x00 , 0x00 , 0xaa, 0, _
0xee , 0xee , 0x77, 0, _
0xdd , 0x88 , 0x55, 0, _
0x66 , 0x44 , 0x00, 0, _
0xff , 0x77 , 0x77, 0, _
0x33 , 0x33 , 0x33, 0, _
0x77 , 0x77 , 0x77, 0, _
0xaa , 0xff , 0x66, 0, _
0x00 , 0x88 , 0xff, 0, _
0xbb , 0xbb , 0xbb, 0
FOR i=0 TO 15
c64_pal[i*4+3] = RGB(c64_pal[i*4], c64_pal[i*4+1], c64_pal[i*4+2])
NEXT
FOR x=0 TO 319 STEP 2
FOR y=0 TO 239
c = GETPIXEL(x,y)
b=bAND(c/0x10000, 0xff)/2
g=bAND(c/0x100 , 0xff)/2
r=bAND(c , 0xff)/2
mindist=0
c = GETPIXEL(x+1,y)
INC b,bAND(c/0x10000, 0xff)/2
INC g,bAND(c/0x100 , 0xff)/2
INC r,bAND(c , 0xff)/2
ibest=0
FOR i=0 TO 15
db=ABS(bAND(c/0x10000, 0xff) - c64_pal[i*4+2])
dg=ABS(bAND(c/0x100 , 0xff) - c64_pal[i*4+1])
dr=ABS(bAND(c , 0xff) - c64_pal[i*4 ])
dist=dr*dr+dg*dg+db*db
IF i=0 OR dist mindist=dist
ibest=i
ENDIF
NEXT
DRAWRECT x,y,2,1,c64_pal[ibest*4+3]
NEXT
NEXT
ENDFUNCTION
Cool, but very slow :(
Wow!
Sweet Gernot ! Nice piece of code ... reminds me to the good old days ... once upon, a long ago :D
CYA !
So, now in realtime:
http://www.glbasic.com/showroom.php?game=C64colorshader
Forgive me, for this is my first fragment shader, ever. It's not very optimized, but it works REALTIME.
Yeah, C64-like graphics REALTIME... but with DX9 capable graphics cards only. That's quite ironic ;)
Anyway, great work!
It doesn't seem to work on my 7900 GS Go.
You're not alone, Andy. All I get is the image displayed as normal, not C64ized. :(
What GFX card, PJ?
On my machine, the image does turn blocky a la C64, but it's still true colour and doesn't use only C64 palette :(
ATI Radeon 9800+ 256Mb (old, but gold).
NVidia GeForce FX 5500 here (old, but, er, crap :D)
Works fine for me. NVidia GeForce 8600M GT here. Sounds like it's more a problem for older cards maybe?
Might be. It needs Shader Language 2.0
Mine has shader 2 and is not that old. I've some shader's (reportedly v2) in MMF that work ok.
Yeah I noticed that when I went and did a bit of research on each of the cards mentioned. Unfortunately in the case of Ian and PJ I'm not surprised theirs are having problems with Open GL Shader 2. BTW Andy, not that it might be the problem, but are you running XP or Vista and are your drivers up to date?
Vista, yes my drivers are the latest. I don't really get any problems here - everything runs great (DirectX and OpenGL).
Updated the file. Working now?
It works now, but it takes an age (it says "LOADING" for a good few seconds) and the square no longer rotates (in fact the program appears to cease after it has displayed the image).
Update. Should work on more cards now.
Nope. It dies now before any image is displayed, after a long "Loading" screen. :(
Working fine on Radeon HD2600 pro
Works great on my dinosaur too! :)
I enjoyed optimizing the no shader version.
On my pc 20 ms with standard programming
SETFONT 0,2
GLOBAL pixels%[],id%=0
IF DOESFILEEXIST("test.png")
LOADSPRITE "test.png",id
ENDIF
SPRITE2MEM (pixels[],id)
GETSPRITESIZE id, sx%, sy%
dtime% = GETTIMERALL()
C64ize()
MEM2SPRITE(pixels[],id,sx,sy)
dtime% = GETTIMERALL()-dtime%
DRAWSPRITE id,0,0
SAVESPRITE "test.bmp", id
PRINT dtime%,10,300
SHOWSCREEN
MOUSEWAIT
END
FUNCTION C64ize:
// weighting of color components
LOCAL x%,y%,c%, r%,g%,b%, dr%,dg%,db%
LOCAL mindist, dist, ibest, i
LOCAL c64_pal[]
DIMDATA c64_pal[], _
0x00 , 0x00 , 0x00, 0, _
0xff , 0xff , 0xff, 0, _
0x88 , 0x00 , 0x00, 0, _
0xaa , 0xff , 0xee, 0, _
0xcc , 0x44 , 0xcc, 0, _
0x00 , 0xcc , 0x55, 0, _
0x00 , 0x00 , 0xaa, 0, _
0xee , 0xee , 0x77, 0, _
0xdd , 0x88 , 0x55, 0, _
0x66 , 0x44 , 0x00, 0, _
0xff , 0x77 , 0x77, 0, _
0x33 , 0x33 , 0x33, 0, _
0x77 , 0x77 , 0x77, 0, _
0xaa , 0xff , 0x66, 0, _
0x00 , 0x88 , 0xff, 0, _
0xbb , 0xbb , 0xbb, 0
FOR i=0 TO 15
c64_pal[i*4+3] = RGB(c64_pal[i*4], c64_pal[i*4+1], c64_pal[i*4+2])
NEXT
FOR x=0 TO 319 STEP 2
FOR y=0 TO 239
ind=x+y*320
c = pixels[ind]
c = bAND(c, 0xffffff)
r=bAND(c, 0xff)/2
g=bAND(ASR(c,8), 0xff)/2
b=bAND(ASR(c,16), 0xff)/2
mindist=0
c = pixels[ind+1]
c = bAND(c, 0xffffff)
INC r,bAND(c, 0xff)/2
INC g,bAND(ASR(c,8), 0xff)/2
INC b,bAND(ASR(c,16), 0xff)/2
ibest=0
FOR i=0 TO 15
db=b - c64_pal[i*4+2]
dg=g - c64_pal[i*4+1]
dr=r - c64_pal[i*4 ]
dist=dr*dr+dg*dg+db*db
IF i=0 OR dist<mindist
mindist=dist
ibest=i
ENDIF
NEXT
fillcolour=bOR(c64_pal[ibest*4+3], ASL(255, 24))
pixels[ind]=fillcolour
pixels[ind+1]=fillcolour
NEXT
NEXT
ENDFUNCTION
Am I missing something? As both pure in-code effects doesn't work for me :/ bitmap remains unchanged (24bit bmp GLB logo). Or maybe there is something more to this code as not all variables were declared, probably I'm blind :D
On other hand, change 'c64_pal' array from floats to integers -> "LOCAL c64_pal%[]" as this should fast it up to 15ms..
Yes the file test.bmp is 24bit but inside there are only 16 colours.
Change the array to integer don't improve on my pc.
I mean input bitmap that I'm using is 24bit bmp GLB logo, and the result/output bitmap 'test.bmp' is also 24bit with full color range, checked with gimp - same as result drawn on screen when running this code. hm.. probably some mismatch from pasting code but can't find it :>
Strange, because changing to integers should give speed up around 25%-30%, double checked on my pc, and btw. didn't noticed that also some other variables are floats, at least in this code on forum..
LOCAL mindist%, dist%, ibest%, i%
LOCAL c64_pal%[]
that gives speed bump from 22ms to 11ms, on my i5.
Try with this file.
Yep this file works, and now I see what was the issue :)
Both FOR loops in main function are fixed to this image dimensions - 320x240px, despite checking sprite size with GETSPRITESIZE. How could I miss that :/
Easy to fix and now works great :-) And now I know where to use this with combination of Your FastMem2Sprite - or that Shader version by Gernot :D Thanks!