Previous Thread
Next Thread
Print Thread
Page 30 of 51 1 2 28 29 30 31 32 50 51
Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child] #114921 03/24/19 07:26 PM
Joined: Feb 2014
Posts: 355
G
Golden Child Offline
Senior Member
Offline
Senior Member
G
Joined: Feb 2014
Posts: 355
Here's some routines to draw the print shop fonts (on the original disk)

[Linked Image][Linked Image]
[Linked Image][Linked Image]

Code

-- printshop_drawfont7.lua

function applemem() 
  if applememobject == nil then applememobject = manager:machine().devices[":maincpu"].spaces["program"] end
  return applememobject
end

function calc(line,page) if line<0 then line = 0 end if line > 191 then line=191 end page=page or 0 return line % 8 * 1024 + math.floor(line / 64) * 40 + math.floor((line%64) / 8) * 128 + 8192* (page + 1) end

function calcyaddr(line,page) return calc(line,page) end
function readswitch(a)
local cpu = manager:machine().devices[":maincpu"]  local mem = cpu.spaces["program"]
mem:read_u8(a)
end

function hgrfull(page)
page = page or 1
readswitch(0xC050) -- graphics
readswitch(0xC052) -- full screen
readswitch(0xC054+page-1) -- page 1
readswitch(0xC057) -- hi res
end

function hgr(page)
page = page or 1
readswitch(0xC050) -- graphics
readswitch(0xC053) -- full mixed
readswitch(0xC054+page-1) -- page 1
readswitch(0xC057) -- hi res
end

function textmode()
readswitch(0xC051) -- text
readswitch(0xC054) -- page 1
end

function text()
readswitch(0xC051) -- text
readswitch(0xC054) -- page 1
end

function hgrclr(page) 
local cpu = manager:machine().devices[":maincpu"]  local mem = cpu.spaces["program"]
for y=0,191 do for x=0,39 do mem:write_u8(calc(y)+x,0) end end end

function hgrwhite(page) for x=0,39 do for y=0,191 do applemem():write_u8(calcyaddr(y,page)+x,127) end end end

function getbits(a,lobit,hibit) local retval=0 for bit=lobit,hibit do retval=retval|((1<<bit)&a) end return retval end

function getbitsshift(a,lobit,hibit) return getbits(a,lobit,hibit)>>lobit end


function getfilenamepart(s)
local curpos=1
repeat
local newpos=s:find("/",curpos,true)
if newpos then curpos = newpos+1 end  -- if you don't add the +1, keeps getting same match, infinite loop
until newpos == nil
return s:sub(curpos)
end

function trim2(s) return s:match "^%s*(.-)%s*$" end  -- from lua users wiki

-- plot function, haven't got all the operations working yet but or,xor,store,and inverse seem to be ok

function plot(x,y,page,bit,operation) page=page or 0 x = math.max(0,x) x = math.min(x,279) y = math.max(0,y) y = math.min(y,191) mem=applemem() 
local memloc=calcyaddr(y,page)+math.floor(x/7)
local readval=mem:read_u8(memloc) local bitpos=x%7
local mask=~(1<<bitpos)
local invertmask=(1<<bitpos)
local bitshifted = bit<<bitpos 
local notbitshifted=(iif(bit==0,1,0) << bitpos)
if operation == nil or operation == "or" then mem:write_u8(memloc,readval | (bit<<bitpos)) 
elseif operation == "erase"     then mem:write_u8(memloc,readval & (bit<<bitpos)) 
elseif operation == "color"     then mem:write_u8(memloc,readval & (bit<<bitpos))  -- erase = color black
elseif operation == "xor"     then mem:write_u8(memloc,readval ~ (bit<<bitpos)) 
elseif operation == "store"   then mem:write_u8(memloc,(readval & mask) | bitshifted)
elseif operation == "inverse" then mem:write_u8(memloc,(readval & mask) | notbitshifted)
else error("PLOT OPERATION "..operation.." not recognized") end
end



function revbits(a) if a==nil then print("REV NIL") return nil end local r=0 for i=0,7 do r=(r<<1)+a%2 a=a>>1 end return r end

-- 0x3b = 59 so we can have 59 characters per font
-- 
-- byte offset  0x3b * 0 + c = width of character
-- byte offset  0x3b * 1 + c = height of character
-- byte offset  0x3b * 2 + c = offset of character data low byte
-- byte offset  0x3b * 3 + c = offset of character data high byte as well as some flags so AND it with 0x1f

-- fonts on the Print Shop disk are named F0 through F9, in a "hidden" directory (start at t,s=17,2)
-- fonts on Print Shop Companion have additional 12 bytes at the beginning, we're just interested
--   in drawing the bitmap so we can just "ignore" these 12 bytes by using a:sub(13) which means take
--    all the bytes to the end of the string starting at character position 13 (numbered from 1).

function getcharwidth(a,c)  return a:byte((0x3b*0)+c+1) end
function getcharheight(a,c) return a:byte((0x3b*1)+c+1) end
function getcharoffset(a,c) return a:byte((0x3b*2)+c+1)+(a:byte((0x3b*3)+c+1)&0x1f)*256 end

--if we draw as bytes then we lose the high bit of the byte and we are on byte boundaries so it looks strange
-- drawing as pixels the fonts look much better

function drawpsfont(a,c0,c1,offset,doprint,xpos,ypos,lineheight,bytesorpixels,drawmode)
-- draw font characters from c0 to c1
c0 = c0 or 0
c1 = c1 or 58
offset=offset or 0
xpos,ypos=xpos or 0,ypos or 0
for c=c0,c1 do 
if getcharwidth(a,c) < 128 then 
local charwidth=getcharwidth(a,c)
local charheight=getcharheight(a,c)
local charoffset=getcharoffset(a,c)
local charbytewidth=math.floor((charwidth-1)/8)+1
drawmode = drawmode or "or"
if doprint then print("char="..c,"width="..getcharwidth(a,c),"height="..getcharheight(a,c),"offset="..hex(getcharoffset(a,c)))  end
if charoffset>#a then print("INVALID CHAR OFFSET") 
else
if charheight~=0 then 
if c~=32 then
--drawblock loop by bytes
if bytesorpixels=="bytes" then
  drawblockloop({"y",charheight,"x",charbytewidth},function(x,y,index) applemem():write_u8(calc(y+ypos)+x+xpos,revbits(a:sub(getcharoffset(a,c)+1):byte(index+offset+1))) end,32)
--drawblock loop by pixels
else
  drawblockloop({"y",charheight,"x",charbytewidth},function(x,y,index) local bytetoplot=revbits((a:sub(charoffset+1):byte(index+offset+1))) local numpixels=math.min(8,charwidth-8*x) x=xpos+x*8 for i=0,numpixels-1 do plot(x+i,y+ypos,0,getbitsshift(bytetoplot,i,i),drawmode) end end,32)
end
else  -- draw the space
      -- leave space blank for now
end
-- draw the gap between characters
  if bytesorpixels~="bytes" then for y=0,charheight-1 do plot(xpos+charwidth,y+ypos,0,0,drawmode) end end
end
if bytesorpixels=="bytes" then xpos = xpos+charbytewidth  -- by bytes
                          else xpos = xpos+charwidth+1    -- by pixels
end
end
if bytesorpixels=="bytes" then if xpos>36  then xpos=0 ypos=ypos+lineheight end -- by bytes
                          else if xpos>240 then xpos=0 ypos=ypos+lineheight end -- by pixels
end
end
end
print("returning xpos="..xpos.." ypos="..ypos)
return xpos,ypos
end

function writepsfonttext(a,s,x,y,offset,charoffset,lineheight,drawmode) charoffset=charoffset or (65-33) for i=1,#s do x,y=drawpsfont(a,s:byte(i)-charoffset,s:byte(i)-charoffset,offset,false,x,y,lineheight,nil,drawmode) print(x) if x>255 then x=0 y=y+16 end end end

-- translate function for combo lower case/uppercase fonts

function translateps(c) -- c passed as a char number
local replacedchars=""
local translate0=             "!\"#$%&'()*+,-./0123456789:;<=>?"
local translate1=string.upper("!wmnop`rsqt,k.zjabcdefghivuxly?")
for i=1,#translate0 do
  if translate0:sub(i,i)~= translate1:sub(i,i) then replacedchars=replacedchars..translate0:sub(i,i)
end
end
print("REPLACED="..replacedchars)
if c>=string.byte("A") and c<=string.byte("Z") then  
  local cpos=string.find(translate1,string.char(c),1,true)
  if cpos==nil then c=string.byte(c) end
  c=string.byte(translate0:sub(cpos,cpos))
elseif c>=string.byte("a") and c<=string.byte("z") then c=c-32
elseif string.find(replacedchars,string.char(c),1,true)  then c=string.byte("!")
elseif c>128 or c<32 then c=string.byte(".")
elseif c>90 or c<32 then c=string.byte(".")
end
return c
end

--for i=string.byte("a"),string.byte("z") do c=string.char(i) print(c,translateps(c)) end

--[[

loaddisk("../../PrintShop.dsk")
catalog()
getcatalog(17,2,nil,true)

-- snippet to render font f1

hgrclr() filename="F1" filelist,t,s=getcatalog(17,2,filename,nil) a=getfilefromtslist(gettslist(t,s)) print(#a.." bytes") a=stripfileheaderandextra(a) hgrclr() drawpsfont(a,32,58,0,false,0,0,38,"pixels","xor") writepsfonttext(a,filename.." 32-58",0,160)

--]]


--[[
-- snippet will loop through the namelist and render each one, but not taking any snaps

namelist={"SYSTEM","RSVP","ALEXIA","NEWS","TECH","PARTY","BLOCK","TYPEWRITER","STENCIL"}
filelist={"F0","F1","F2","F3","F4","F5","F6","F7","F8"}loaddisk("../../Print_Shop_The_1984_Broderbund_a.dsk")hgr() hgrfull() hgrclr() for i=1,#filelist do filename=filelist[i] aafilelist,t,s=getcatalog(17,2,filename,nil) a=getfilefromtslist(gettslist(t,s)) print(#a.." bytes") a=stripfileheaderandextra(a) hgrclr() drawpsfont(a,1,58,0,false,0,0,38,"pixels","xor") writepsfonttext(a,filename.." "..namelist[i],0,160) 
end


-- this snippet will create snaps of all the fonts on the print shop disk


co1=coroutine.create( function()
namelist={"SYSTEM","RSVP","ALEXIA","NEWS","TECH","PARTY","BLOCK","TYPEWRITER","STENCIL"}
filelist={"F0","F1","F2","F3","F4","F5","F6","F7","F8"}
diskname="../../Print_Shop_The_1984_Broderbund_a.dsk"  -- has good f5 block font, bad  f1 rsvp
diskname="../../PrintShop.dsk"                         -- has bad  f5 block font, good f1 rsvp
loaddisk(diskname)hgr() hgrfull() hgrclr() for i=1,#filelist do filename=filelist[i] aafilelist,t,s=getcatalog(17,2,filename,nil) a=getfilefromtslist(gettslist(t,s)) print(#a.." bytes") a=stripfileheaderandextra(a) hgrclr() drawpsfont(a,iif(filename=="F1",32,1),58,0,false,0,0,iif(filename=="F1",38,32),"pixels","xor") writepsfonttext(a,filename.." "..namelist[i],0,160) 
emu.wait(2/60)
manager:machine():debugger():command("snap \"" .. sanefilename(getfilenamepart(diskname).."_"..trim2(filelist[i]).."_"..namelist[i])..".png\"")
end
end)
ok,error=coroutine.resume(co1)
print(ok,error)

--]]


A couple of things to note about the print shop disk, the catalog is truncated, so if you start at track 17, sector 2 you can see the rest of the files. Also font F1 or F5 is corrupted depending on the disk you use.

Now the PS Companion fonts seem to have 12 extra bytes at the beginning, so if you pass them as a:sub(13) instead of a those 12 bytes will be ignored.



Code
-- just a quick test on the PS Companion disk.
loaddisk("../../PrintShop.Companion.dsk") catalog()
filename="FONT.BALLOON" hgr() hgrclr() hgrwhite() a=getfile(filename) drawpsfont(a:sub(13),iif(filename=="BALLOON",32,1),58,0,false,0,0,32,"pixels","xor") writepsfonttext(a:sub(13),filename,0,140,0,nil,20,"xor")


[Linked Image]

Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01] #114922 03/24/19 07:52 PM
Joined: Mar 2006
Posts: 1,035
L
Lord Nightmare Offline
Very Senior Member
Offline
Very Senior Member
L
Joined: Mar 2006
Posts: 1,035
Golden Child: speaking of AppleII font stuff, is the "candy apple" Hershey font editor/renderer apple2 disk preserved anywhere?
The Applesoft basic listing and some of the binary and text contents are listed at https://www.govinfo.gov/content/pkg...C13-f5df264c560c0810c872edea211033cc.pdf which might be enough to re-create the disk from scratch, but I don't know of any surviving copies. Both authors of that paper have sadly passed away, so its unlikely I can get any information from that angle.

EDIT: some of the fonts on the Fontrix user group disks are traced by hand from some glyphs of the herhsey fonts with some manual adjustment, but none seem to be a direct 1:1 copy.

LN

Last edited by Lord Nightmare; 03/24/19 08:12 PM.

"When life gives you zombies... *CHA-CHIK!* ...you make zombie-ade!"
Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Lord Nightmare] #114924 03/25/19 11:42 AM
Joined: Feb 2014
Posts: 355
G
Golden Child Offline
Senior Member
Offline
Senior Member
G
Joined: Feb 2014
Posts: 355
Hi LN, looking around at the "regular" places, I don't see any Hershey fonts. They're kind of interesting vector fonts, the only mention I could find was a company named Tangent 270 which sold a Hershey font product (google for "tangent 270 hershey fonts apple").

Code
SOFTWARE/ GRAPHICS TANGENT 270 P.O. Box 38587. DspL 9281 Denver, CO ... High quality characters based on Hershey's character repertory. 14 fonts including Roman Bold, English Gothic, Greek. 7 special ... 48K Apple II+. DOS 3.3.

Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child] #114925 03/25/19 11:56 AM
Joined: Feb 2014
Posts: 355
G
Golden Child Offline
Senior Member
Offline
Senior Member
G
Joined: Feb 2014
Posts: 355
Now to draw some Fontrix fonts:

[Linked Image][Linked Image]
[Linked Image][Linked Image]

I was able to get some files from Printrix to draw also, which has Times 25,30,40,50,70 and Helvetica 25,30,40,50,70.

Since the printrix disk was Prodos, I created a dos3.3 image in the file manager (I called it created_image.dsk and you can see the SET.HELVET25) and used COPY II+ to copy the files over so I could access them. (I haven't written routines to access Prodos disks yet -- coming soon after I can decipher Beyond Apple Prodos).



Code
function calc(line,page) if line<0 then line = 0 end if line > 191 then line=191 end page=page or 0 return line % 8 * 1024 + math.floor(line / 64) * 40 + math.floor((line%64) / 8) * 128 + 8192* (page + 1) end

function calcyaddr(line,page) return calc(line,page) end

function plot(x,y,page,bit,operation) page=page or 0 x = math.max(0,x) x = math.min(x,279) y = math.max(0,y) y = math.min(y,191) mem=applemem() 
local memloc=calcyaddr(y,page)+math.floor(x/7)
local readval=mem:read_u8(memloc) local bitpos=x%7
local mask=~(1<<bitpos)
local invertmask=(1<<bitpos)
local bitshifted = bit<<bitpos 
local notbitshifted=(iif(bit==0,1,0) << bitpos)
if operation == nil or operation == "or" then mem:write_u8(memloc,readval | (bit<<bitpos)) 
elseif operation == "erase"     then mem:write_u8(memloc,readval & (bit<<bitpos)) 
elseif operation == "color"     then mem:write_u8(memloc,readval & (bit<<bitpos))  -- erase = color black
elseif operation == "xor"     then mem:write_u8(memloc,readval ~ (bit<<bitpos)) 
elseif operation == "store"   then mem:write_u8(memloc,(readval & mask) | bitshifted)
elseif operation == "inverse" then mem:write_u8(memloc,(readval & mask) | notbitshifted)
else error("PLOT OPERATION "..operation.." not recognized") end
end

function applemem() return manager:machine().devices[":maincpu"].spaces["program"] end

function hgrwhite(page) for x=0,39 do for y=0,191 do applemem():write_u8(calcyaddr(y,page)+x,127) end end end

function getbits(a,lobit,hibit) if a==nil then print("getbits:NIL!") return 0 end local retval=0 for bit=lobit,hibit do retval=retval|((1<<bit)&a) end return retval end

function getbitsshift(a,lobit,hibit) if a==nil then print("getbitsshift:NIL!") return 0 end return getbits(a,lobit,hibit)>>lobit end



function getcharheightfontrix(a,c) return a:byte(0x14+1) end
function getcharwidthfontrix(a,c)  return a:byte((0xe2)+(c-1)+1) end

function getcharwidthfontrix(a,c)  if a:byte(0x12+1)==0 then return a:byte(0x13+1) else return a:byte((0xe2)+(c-1)+1) end end

function getcharoffsetfontrix(a,c) return a:byte((0x20)+(c-1)*2+1)+a:byte((0x21)+(c-1)*2+1)*256 end

function applemem() 
  if applememobject == nil then applememobject = manager:machine().devices[":maincpu"].spaces["program"] end
  return applememobject
end


-- subtle difference, between just catalog() and return catalog()
function cat(...) return catalog(...) end
function CAT(...) return catalog(...) end


--new version of drawfontrix font, with xpos coordinate is pixel, not byte
function drawfontrixfont2(a,c0,c1,offset,doprint,xpos,ypos,lineheight,drawmode)
-- draw font characters from c0 to c1
c0 = c0 or 0
c1 = c1 or 58
offset=offset or 0
--hgrclr() 
xpos,ypos=xpos or 0,ypos or 0
for c=c0,c1 do 
local charwidth=getcharwidthfontrix(a,c)
local charheight=getcharheightfontrix(a,c)
local charoffset=getcharoffsetfontrix(a,c)
local charbytewidth=math.floor((charwidth-1)/8)+1
if doprint then print("char="..c.."  "..string.char(c+31),"width="..charwidth,"height="..charheight,"offset="..hex(charoffset).." vpos="..getcharvposfontrix(a,c))
  end
if charoffset>#a then print("INVALID CHAR OFFSET") 
else
drawblockloop({"y",charheight,"x",charbytewidth},function(x,y,index) local bytetoplot=(a:sub(charoffset+1):byte(index+offset+1)) local numpixels=math.min(8,charwidth-8*x) x=xpos+x*8 for i=0,numpixels-1 do plot(x+i,y+ypos+getcharvposfontrix(a,c),0,getbitsshift(bytetoplot,i,i),drawmode) end end,32)
xpos=xpos+charwidth+2 -- pixels now
if xpos>250 then xpos=0 ypos=ypos+lineheight end  -- ypos=ypos+charheight+1 
end
end
print("returning xpos="..xpos.." ypos="..ypos)
return xpos,ypos
end

function writetextfontrix2(a,s,x,y,lineheight,drawmode) for i=1,#s do c=s:byte(i) c=c-32+1 x,y=drawfontrixfont2(a,c,c,0,nil,x,y,lineheight,drawmode) if x>250 then x=0 y=y+lineheight print(y) end end end


-- for the bigger fonts
function getcharheightfontrix(a,c) return a:byte(0x200+(c-2)+1) end

function getcharheightfontrix(a,c) if a:byte(1)==0x14 then return a:byte(0x200+(c-2)+1) else return a:byte(0x14+1) end end
function getcharvposfontrix(a,c) if a:byte(1)==0x14 then return a:byte(0x200+96*1-1+(c-2)+1) else return 0 end end

--[[


function getfilenamepart(s)
local curpos=1
repeat
local newpos=s:find("/",curpos,true)
if newpos then curpos = newpos+1 end  -- if you don't add the +1, keeps getting same match, infinite loop
until newpos == nil
return s:sub(curpos)
end

function trim2(s) return s:match "^%s*(.-)%s*$" end  -- from lua users wiki


loaddisk("../../fontrix.dsk") setascii=getfile("SET.ASCII BOLD")

co1=coroutine.create( function()
disknamelist={"../../fontrix.dsk","../../Font Paks 1 and 2.dsk","../../fontrixfontpak14.dsk","../../created_image.dsk"}
for d=1,#disknamelist do diskname=disknamelist[d] 
loaddisk(diskname)
filelist=cat()
for i=1,#filelist do print(filelist[i]) 
if filelist[i]:find("SET.",1,true) then 
print("IT'S A FONT so let's render a sample!") 
filename=filelist[i]
a=getfile(filelist[i])
 hgr() hgrfull() hgrclr() xpos=0 ypos=10
drawfontrixfont2(a,1,96,0,true,0,0,30) 
writetextfontrix2(setascii,diskname,0,170,20,"store")
writetextfontrix2(setascii,filename,0,180,20,"store")
emu.wait(1/60+.01) 
manager:machine():debugger():command("snap \"" .. sanefilename(getfilenamepart(diskname).."_"..trim2(filelist[i]))..".png\"")
end end
end
end) 
ok,error=coroutine.resume(co1)
print(ok,error)


--]]



I think the screen's too small for 50 point type.

[Linked Image][Linked Image]

Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child] #114942 03/27/19 02:49 PM
Joined: Feb 2014
Posts: 355
G
Golden Child Offline
Senior Member
Offline
Senior Member
G
Joined: Feb 2014
Posts: 355
I was creating some blank apple 2 disk images to copy some Prodos files to Dos 3.3 with Copy II+ using mame's built in file manager and was getting some strange results, primarily because I was asking for filenames with .DSK in capitals as opposed to a lowercase .dsk extension.

What threw me off was that it would happily create the file and give it a zero size so I could see it in Ubuntu's file manager but it contained no data.

Only after a few tries did I see that there was a popup message at the bottom of the screen that said "Error: Unable to identify the image format".

So be careful when you leave your caps lock on, because it doesn't like .DSK, only .dsk.

[Linked Image]

Notice that the menu here doesn't have a default option:

[Linked Image]

and we get a popup error message: (which I didn't see the first couple of times I did this)

[Linked Image]


and when using lowercase .dsk extension the menu is slightly different with a bar separating the first option from the rest.

[Linked Image]

Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01] #114958 03/29/19 03:28 AM
Joined: Mar 2001
Posts: 16,390
R
R. Belmont Offline
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,390
With the Apple II SCSI card solidified, the next step was getting the CD-ROM drive to work. Didn't take much work, and here you see the IIgs Finder browsing a PlayStation game disc.

[Linked Image]

Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01] #114959 03/29/19 03:42 AM
Joined: Mar 2001
Posts: 16,390
R
R. Belmont Offline
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,390
MAME is now the first and only Apple IIgs emulator able to use the Golden Orchard CD-ROM .iso.

[Linked Image]

And, it can even boot from the CD-ROM:
[Linked Image]

Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: rfka01] #114960 03/29/19 08:22 AM
Joined: May 2004
Posts: 890
D
Duke Offline
Senior Member
Offline
Senior Member
D
Joined: May 2004
Posts: 890
That's awesome smile

Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Duke] #114972 04/02/19 01:59 PM
Joined: Feb 2014
Posts: 355
G
Golden Child Offline
Senior Member
Offline
Senior Member
G
Joined: Feb 2014
Posts: 355
Something I've been fiddling with (and the emulation is probably horribly incorrect since I have no idea what I'm doing)

Bonus points if you know what this is:

[Linked Image]

Re: 8bit Apples - Apple I, II, /// and the 16 bit GS [Re: Golden Child] #114982 04/04/19 12:06 PM
Joined: Feb 2014
Posts: 355
G
Golden Child Offline
Senior Member
Offline
Senior Member
G
Joined: Feb 2014
Posts: 355
Getting closer...

[Linked Image] [Linked Image] [Linked Image]

Page 30 of 51 1 2 28 29 30 31 32 50 51

Who's Online Now
1 registered members (Pernod), 179 guests, and 2 spiders.
Key: Admin, Global Mod, Mod
ShoutChat Box
Comment Guidelines: Do post respectful and insightful comments. Don't flame, hate, spam.
Forum Statistics
Forums9
Topics8,722
Posts114,633
Members4,873
Most Online510
Aug 26th, 2019
Powered by UBB.threads™ PHP Forum Software 7.7.3