ZXScreen viewer

Previous topic - Next topic

Crivens

What sort of issues did they have?

Cheers
Current fave quote: Cause you like musicians and I like people with boobs.

Kitty Hello

I thought "Public Domain" means: everyone can do whatever they want with it. True shame.

Gary

Not quite sure its classed as "public domain" more a case of "freeware" which means the original owner retains all copyrights over the product. After all Mame is seen as public domain but you try and do something with the source and not follow the GPL and they will come down on you.

Been reading up on how to write a spectrum emulator and it seems once the core and display routines are sorted its pretty much impossible not to load the rom and get a (C) Sinclair Research appear on the screen. After that its just a case of hooking in things like keyboard, sound etc. If you break everything down and have a stable core then emulation is fairly easy if you are emulating a well documented system like the spectrum. Get a memory map and you are sorted

Mikele

Just played more with GLB and ZX things... Now the loading effect has more sense - every "screen" is loaded ZX-like way - that means you can see how the loading is progressing (press SPACE to load quickly, LEFT mouse button to load next ZXscreen, RIGHT to toggle color/b&w mode). The timings aren't correct as in real ZX but it's just for fun (to be honest I learn GLB that way). Thanks to Amon's delta time code it's still working with similar speed on my Galaxy S.  I'm thinking about adding loading sounds.

Code (glbasic) Select

// --------------------------------- //
// Project: ZX Spectrum Screen
// Start: Monday, October 17, 2011
// IDE Version: 10.118


SETCURRENTDIR("Media") // go to media files

GLOBAL VIDRAM = 16384 //videoram
GLOBAL VIDATR = 22528 //attributes

GLOBAL ZXRAMbank[]
DIM ZXRAMbank[65536] //ZX memory image 16KB ROM + 48KB RAM

GLOBAL SCREENbufor[]
DIM SCREENbufor[6912]

GLOBAL colortable[]
DIM colortable[16] //colors FOR WritePixelFast

MakeColors()

GLOBAL flashstate = TRUE
GLOBAL time = 350 // flash frq
GLOBAL oldTime
GLOBAL load = TRUE //loadingFX simulator
GLOBAL BWmode = FALSE
GLOBAL waitkey = 0


//------- demo --------

SETSCREEN 320,256, 0//320,256,0
LIMITFPS 50

STARTDATA screens:
DATA "LuckyLucke.scr", "terrorpolis.scr", "ship.scr", "sen1.11.scr", "sen.scr", "knights.scr", "miasto.scr", "space2.scr"
ENDDATA

GLOBAL scrCounter = 1, scrfile$
RESTORE screens
READ scrfile$

GLOBAL is_loading = FALSE
GLOBAL adres_count = 0
GLOBAL game_delta = 0
GLOBAL ubermultiplyer=0

GLOBAL dt AS DeltaTimer
dt.InitDelta()
dt.SetDeltaFPS(50.0)



//OpenSCR(scrfile$)
PrepareLoad(scrfile$)




WHILE TRUE
ALPHAMODE -1

ZXField()

dt.UpdateDelta()

IF waitkey > 0
waitkey = waitkey-1
ENDIF

MOUSESTATE mx, my, b1, b2

IF is_loading
LoadSCR()
ENDIF

IF (KEY(67) = 1 OR b2 = 1) AND waitkey = 0 //KEY F9 = B/W / color mode

BWmode = NOT BWmode
waitkey = 10

IF BWmode = TRUE
MakeGrey()
ELSE
MakeColors()
ENDIF

ELSEIF (KEY(87) = 1 OR b1 = 1) AND waitkey = 0 AND is_loading=FALSE

INC scrCounter
IF scrCounter > 8
scrCounter = 1
RESTORE screens
ENDIF

READ scrfile$
PrepareLoad(scrfile$)
// OpenSCR(scrfile$)
waitkey = 10

ENDIF

IF (KEY(57)) = 1
ubermultiplyer=1
ELSE
ubermultiplyer=0
ENDIF


SHOWSCREEN

SLEEP 1

WEND

END



//---------------------

FUNCTION ResetZXVideoRAM:
LOCAL count
FOR count=0 TO 6143
ZXRAMbank[16384+count]=0
NEXT
FOR count=6144 TO 6911
ZXRAMbank[16384+count]=56
NEXT
ENDFUNCTION



//.scr, .zx, .$c, .s  6912 AND 6929 are supported
FUNCTION OpenSCR: scrfile$, channel1=1
IF scrfile$<>"" AND (RIGHT$(scrfile$,4)=".scr" OR RIGHT$(scrfile$,3)=".zx" OR RIGHT$(scrfile$,2)=".s" OR RIGHT$(scrfile$,3)=".$c")
LOCAL sizefile=GETFILESIZE(scrfile$)

LOCAL screenfile = OPENFILE(channel1, scrfile$, 1)

IF sizefile = 6912
ReadBytes (channel1, 16384,6912)
ELSEIF sizefile = 6929
ReadBytes (channel1, 16384-17,6912)
ENDIF

CLOSEFILE 1
ENDIF
ENDFUNCTION

FUNCTION ReadBytes: chan, adres, lenght
LOCAL count, newDATA%
FOR count=0 TO lenght-1
READBYTE chan, newDATA%
ZXRAMbank[adres+count]=newDATA%
NEXT
ENDFUNCTION

FUNCTION PrepareLoad: scrfile$, channel1=1
IF scrfile$<>"" AND (RIGHT$(scrfile$,4)=".scr" OR RIGHT$(scrfile$,3)=".zx" OR RIGHT$(scrfile$,2)=".s" OR RIGHT$(scrfile$,3)=".$c")
LOCAL sizefile=GETFILESIZE(scrfile$)

LOCAL screenfile = OPENFILE(channel1, scrfile$, 1)

LOCAL count, newDATA%

IF sizefile = 6912
FOR count=0 TO 6911
READBYTE channel1, newDATA%
SCREENbufor[count]=newDATA%
NEXT
ELSEIF sizefile = 6929
FOR count=0 TO 6928
READBYTE channel1, newDATA%
IF count>16
SCREENbufor[count]=newDATA%
ENDIF
NEXT
ENDIF

CLOSEFILE 1

is_loading = TRUE
adres_count = 0
ResetZXVideoRAM()
ENDIF
ENDFUNCTION

//.scr, .zx, .$c, .s  6912 AND 6929 are supported
FUNCTION LoadSCR: channel1=1
LOCAL kMax = 4
LOCAL multiplyer = INTEGER(game_delta)
IF multiplyer>1 THEN kMax=4*multiplyer
IF ubermultiplyer=1 THEN kMax=4*128
FOR k=0 TO kMax-1
IF (adres_count + k) < 6912
ZXRAMbank[16384 + adres_count + k] = SCREENbufor[0+adres_count + k]
ENDIF
NEXT


adres_count = adres_count + kMax


IF adres_count > 6911
is_loading = FALSE
ENDIF
ENDFUNCTION

//render ZX screen
FUNCTION ZXField:
LOCAL argb%

FlashEffect()

FOR y%=0 TO 255 STEP 2

IF is_loading
argb = RND(10)
IF argb>5
IF BWmode=FALSE
argb = RGB(0,50,200)//blue strips
ELSE
argb = 5592405
ENDIF
ELSE
IF BWmode=FALSE
argb = RGB(200,200,40)//yellow strips
ELSE
argb = RGB(200,200,200)
ENDIF
ENDIF
ELSE
argb = 0
ENDIF

DRAWLINE 0,y, 320, y, argb
DRAWLINE 0,y+1, 320, y+1, argb

NEXT

DrawScreen(32, 32)
ENDFUNCTION

//get INK color
FUNCTION AttrInk: byte
RETURN bAND(byte,7)
ENDFUNCTION

//get PAPER color
FUNCTION AttrPaper: byte
RETURN bAND(ASR (byte,3),7)
ENDFUNCTION

//get BRIGHT attribute
FUNCTION AttrBright: byte
RETURN bAND(byte,64)
ENDFUNCTION

//get FLASH attribute
FUNCTION AttrFlash: byte
RETURN bAND(byte,128)
ENDFUNCTION

//video processor ;)
//x,y - screen coordinates (+32 pixels for border)
FUNCTION DrawScreen: X=32, Y=32
LOCAL Xpixel, Ypixel, bblok, bajt, attr, brightcolor, inkcolor, paperColor, flashcolor, temp, video, blok, at, bat, b, l
DIM pix%[256*256]
Ypixel = Y-32

FOR blok = 0 TO 2

bblok = blok * 256

FOR at = 0 TO 7

bat = at*32

  FOR l = 0+at*32+blok*2048 TO 2047+blok*2048 STEP 256

Xpixel = X-32

FOR b = 0 TO 31

bajt = ZXRAMbank[VIDRAM+b+l]
attr = ZXRAMbank[VIDATR+b+bat+bblok]
brightcolor = ASR (AttrBright (attr), 3)
// inkcolor = 7
// paperColor = 0
inkcolor = AttrInk (attr) + brightcolor
paperColor = AttrPaper (attr) + brightcolor

flashcolor = AttrFlash (attr)

IF flashcolor=128 AND flashstate = TRUE

temp=inkcolor
inkcolor=paperColor
paperColor=temp

ENDIF


video = bAND(bajt,128) //;1
SELECT video
CASE 128
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1

video = bAND(bajt,64) //;2
SELECT video
CASE 64
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1

video = bAND(bajt,32) //;3
SELECT video
CASE 32
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1

video = bAND(bajt,16) //;4
SELECT video
CASE 16
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1

video = bAND(bajt,8) //;5
SELECT video
CASE 8
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1

video = bAND(bajt,4) //;6
SELECT video
CASE 4
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1

video = bAND(bajt,2) //;7
SELECT video
CASE 2
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1

video = bAND(bajt,1) //;8
SELECT video
CASE 1
//SETPIXEL Xpixel,Ypixel, colortable[inkcolor]
pix[Xpixel + Ypixel*256] = bOR(colortable[inkcolor], ASL(0x00ffffff,24))//colortable[inkcolor]+ 0xff000000
CASE 0
//SETPIXEL Xpixel,Ypixel, colortable[paperColor]
pix[Xpixel + Ypixel*256] = bOR(colortable[paperColor], ASL(0x00ffffff, 24))//colortable[paperColor]+ 0xff000000
ENDSELECT
Xpixel = Xpixel + 1
NEXT

     Ypixel = Ypixel + 1

NEXT

   NEXT

  NEXT


MEM2SPRITE(pix[], 1, 256, 256)
DRAWSPRITE 1, 32, 32

ENDFUNCTION

//FLASH timing
FUNCTION FlashEffect:
IF GETTIMERALL() > oldTime + time

IF flashstate = TRUE
flashstate = FALSE
oldTime=GETTIMERALL()
ELSE
flashstate = TRUE
oldTime=GETTIMERALL()
ENDIF
ENDIF
ENDFUNCTION

//ZXGreyscale
FUNCTION MakeGrey:
FOR k=0 TO 15
colortable[k] = Grey(colortable[k])
NEXT
ENDFUNCTION

//ZXSpectrum colors
FUNCTION MakeColors:
colortable[0] = RGB(0,0,0) //;BLACK
colortable[1] = RGB(0,10,120) //;BLUE
colortable[2] = RGB(200,20,20) //;RED
colortable[3] = RGB(200,40,200) //;MAGENTA
colortable[4] = RGB(20,200,20) //;GREEN
colortable[5] = RGB(40,200,200) //;CYAN
colortable[6] = RGB(200,200,40) //;YELLOW
colortable[7] = RGB(200,200,200) //;WHITE
colortable[8] = RGB(1,1,1) //;BLACK + BRIGHT
colortable[9] = RGB(0,20,200) //;BLUE + BRIGHT
colortable[10] = RGB(255,40,40) //;RED + BRIGHT
colortable[11] = RGB(255,80,255) //;MAGENTA + BRIGHT
colortable[12] = RGB(40,255,40) //;GREEN + BRIGHT
colortable[13] = RGB(80,255,255) //;CYAN + BRIGHT
colortable[14] = RGB(255,255,80) //;YELLOW + BRIGHT
colortable[15] = RGB(255,255,255) //;WHITE + BRIGHT
ENDFUNCTION

FUNCTION Grey: rgb1
red1=bAND(ASR(rgb1,16), 255)
green1=bAND(ASR(rgb1,8),255)
blue1=bAND(rgb1,255)

//simple grayscale
gray=(red1+green1+blue1)/3

//greyscale by Peter Scheutz
//gray=red1*0.3 + green1*.059 + blue1*0.11

red1=gray
green1=gray
blue1=gray
RETURN RGB(red1, green1, blue1)
ENDFUNCTION


// DELTA TIME CLASS by AMON ---------------------------------
TYPE DeltaTimer
targetfps#
currentticks#
lastticks#
frametime#
delta#

FUNCTION InitDelta :
self.targetfps = 0.0
self.currentticks = 0.0
self.lastticks = 0.0
self.frametime = 0.0
self.delta = 0.0
RETURN TRUE
ENDFUNCTION

FUNCTION SetDeltaFPS : fps#
self.targetfps = fps
self.lastticks = GETTIMERALL()
RETURN fps
ENDFUNCTION

FUNCTION UpdateDelta :
self.currentticks = GETTIMERALL()
self.frametime = self.currentticks - self.lastticks
self.delta = self.frametime / (1000.0 / self.targetfps)
self.lastticks = self.currentticks
game_delta = self.delta
// Logic()
RETURN TRUE
ENDFUNCTION

ENDTYPE





Regards,

M.



[attachment deleted by admin]

fuzzy70

Nice one, reminds me of my old routine   8)
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)