Recent Posts

Pages: 1 ... 8 9 [10]
91
Code snippets / Swirl
« Last post by Rick3137 on March 01, 2017 »
    Just a little computer art experiment.

    I was going to try an animation, but my circle command is too slow. Some day I hope to figure out another way to draw circles.

Code: [Select]
     visible:
  sw = 1200 ;
  sh = 700 ;
  sw2# = float(sw)
  sh2# = float(sh)
  x# = 1.0 ;   
  y# = 1.0 ;
  PI# = 3.14159265 ;
  pi2# = PI * 2.0 ;
  r2# = 0.0 ;
  r3# = 0.0 ;
hidden:
set redraw off
set window 0, 0, sw, sh
   proc Bang ;
   wait keydown
end
 
   procedure Bang()
radius# ;  cnt = 0
     angle# = 0.0
     StartAngle# = 0.0 
     size# = 0.1
    radius# = 0.1
    ds# = 0.1
    clr = 2
 
       while radius < 700.0 
                         x = cos( angle ) * radius
                       y = sin( angle ) * radius
                       
                       proc Circle sw2/2.0 + x, sh2/2.0 + y, size  , clr
                         proc Circle  sw2/2.0 + x, sh2/2.0 + y, size / 1.5, clr + 1
                         proc Circle  sw2/2.0 + x, sh2/2.0 + y, size / 2.0, clr + 2
                         proc Circle  sw2/2.0 + x, sh2/2.0 + y, size / 2.5, clr + 3
                     
                             angle = angle + 42.0
                             radius = radius + 1.0
                             clr = clr + 1
                             size = size + ds
                             ds = ds + 0.0001
                             if clr > 9 then clr = 2
                             redraw
          wend
          redraw
    endproc

procedure Circle(x1#,y1#,radius#,clr)
  dx# ; dy# ; angle# = 0.0
     proc MakeColor clr
     while angle < 360.1
        dy = sin(angle) * radius
        dx = cos(angle) * radius
       
        draw pixel int(x1) + int(dx),int(y1) + int(dy)
        angle = angle + 2.0
     wend
   set color 255,255,255 ;
endproc

procedure MakeColor(clr)
   
    if clr = 0 then set color 0,0,0 ;
    if clr = 1 then set color 200,100,100 ;
    if clr = 2 then set color 255,0,0 ;
    if clr = 3 then set color 150,255,0 ;
    if clr = 4 then set color 255,255,0 ;
    if clr = 5 then set color 0,255,0 ;
    if clr = 6 then set color 0,0,255 ;
    if clr = 7 then set color 255,0,255 ;
    if clr = 8 then set color 200,200,200 ;
    if clr = 9 then set color 255,255,255 ;


endproc
 

   
       
 

92
Code snippets / Some basic p2p stuff
« Last post by Marcus on February 26, 2017 »
I started to write on a 2d multiplayer shooter thingy, might be interesting if you're experimenting with the p2p library but don't find the tick-tack-toe example funny enough :)

The "game" is pointless. Start the first instance and choose to create a lobby (Y), then start up to 3 other instances where you chose not to create a lobby (N). Each player can shoot bullets (left mouse button) and throw grenades (right mouse button). Move around with AWSD or arrow keys and aim with the mouse cursor. Everything one player does is transmitted to the others.

Code: [Select]
' ------------------------------------------------------------------------------
' 1234.
'
' chose to create a lobby (Y) for the first running instance, then start up to
' three more instances that connect to the first (N).
' ------------------------------------------------------------------------------

import "Keycodes.lib"
import "Speed.lib"
import "p2p.lib"

constant:
' transmit player position four (60/15) times every second.
TSMT_PLY_POS_TICKS 15

' players.
PLY_MAX_BULLETS 8
PLY_MAX_GRENADES 2

' p2p messages.
MSG_PLAYER_POS   16
MSG_PLAYER_SHOOT 17
MSG_PLAYER_BULLET_DIED 18
MSG_PLAYER_GRENADE 19

' player types. PLY_BOT only exists for server, will be PLY_REMOTE
' for client.
PLY_NONE   0
PLY_THIS   1
PLY_REMOTE 2
PLY_BOT    3

' player status.
PLY_STATE_NONE       0
PLY_STATE_CONNECTING 1
PLY_STATE_INGAME     2

' log.
MAX_LOG_MESSAGES 6
LOG_CHAT 1
LOG_INFO 2
LOG_GOOD 3
LOG_BAD  4

visible:
' server or client.
isServer = false

' players, bullets and grenades.
players?[4]
playerBullets?[4][PLY_MAX_BULLETS]
playerGrenades?[4][PLY_MAX_GRENADES]

' log.
vLog?[MAX_LOG_MESSAGES]

hidden:

set window 16, 16, 480, 270

if not P2P_Init() then _Error "Could not initialize the p2p library"

_ClearLog
_ClearPlayers

' setup this player.
randomize time()
players[0].type = PLY_THIS
players[0].state = PLY_STATE_INGAME
players[0].x# = float(rnd(width(primary)))
players[0].y# = float(rnd(height(primary)))
players[0].dx# = 0.0
players[0].dy# = 0.0
players[0].spd# = 2.0
players[0].aimX# = 0.0
players[0].aimY# = 1.0
players[0].a# = atan2(1.0, 0.0)
players[0].ticks = 0
players[0].id = -1

' create lobby or connect to localhost.
write "Create lobby? (Y/N) "
result$ = upper(rln$(1))
if result = "Y"
isServer = true
players[0].name$ = "Serverman"
if not P2P_CreateLobby("1234", players[0].name$, 0, false)
_Error "Could not create lobby"
endif
if not P2P_SearchClient()
_Error "Could not search for client"
endif
_Log "Lobby created", LOG_INFO
else
isServer = false
players[0].name$ = "Clientman"
if not P2P_Connect("localhost", players[0].name$)
_Error "Could not connect to lobby"
endif
_Log "Joined lobby", LOG_INFO
endif

set redraw off

do
_P2P_Update
_HandleMessages

for i = 0 to 3
_UpdatePlayer players[i]
next
_UpdatePlayerBullets
_UpdatePlayerGrenades
_UpdateLog

' draw.
set color 0, 0, 0
cls
for i = 0 to 3
if players[i].type and players[i].state = PLY_STATE_INGAME then _DrawPlayer players[i]
next
for i = 0 to 3
' bullets.
for j = 0 to PLY_MAX_BULLETS - 1
if playerBullets[i][j].type
draw rect int(playerBullets[i][j].x#) - 1, int(playerBullets[i][j].y#) - 1, 2, 2, true
endif
next
' grenades.
for j = 0 to PLY_MAX_GRENADES - 1
if playerGrenades[i][j].type
s = 4 + int(sin(playerGrenades[i][j].p#*180.0)*8.0)
x# = playerGrenades[i][j].sx#*(1.0 - playerGrenades[i][j].p#) + playerGrenades[i][j].dx#*playerGrenades[i][j].p#
y# = playerGrenades[i][j].sy#*(1.0 - playerGrenades[i][j].p#) + playerGrenades[i][j].dy#*playerGrenades[i][j].p#
draw rect int(x) - s/2, int(y) - s/2, s, s, true
endif
next
next

_DrawLog

redraw
_SPD_HoldFrame 60
until keydown(VK_ESC, true)

' ------------------------------------------------------------------------------
' handle p2p messages.
' ------------------------------------------------------------------------------
procedure HandleMessages()
pkg?
while P2P_Receive(pkg)
' connections.
if pkg.id = P2P_USER_CONNECTED
_AddPlayer pkg.usr, pkg.msg$
_Log pkg.msg$ + " joined the lobby", LOG_INFO
if isServer
if ServerFull()
_Log "Server is now full", LOG_INFO
elseif not P2P_SearchClient()
_Error "Could not search for another client"
endif
endif
elseif pkg.id = P2P_USER_DISCONNECTED
index = PlayerIndex(pkg.usr)
players[index].type = PLY_NONE
_Log pkg.msg$ + " left the lobby", LOG_INFO
elseif pkg.id = P2P_CONNECTION_LOST
_Error "Lost connection to lobby"
' player status.
elseif pkg.id = MSG_PLAYER_POS
index = PlayerIndex(pkg.usr)
_P2P_Decompose pkg.msg$
x = P2P_GetInt()
y = P2P_GetInt()
a = P2P_GetInt()
moving = P2P_GetInt()
players[index].wx# = float(x)
players[index].wy# = float(y)
players[index].a# = float(a)
players[index].aimX# = cos(float(a))
players[index].aimY# = sin(float(a))
players[index].mov = moving
' first update?
if players[index].state = PLY_STATE_CONNECTING
players[index].state = PLY_STATE_INGAME
players[index].x# = players[index].wx#
players[index].y# = players[index].wy#
endif
dx# = players[index].wx# - players[index].x#
dy# = players[index].wy# - players[index].y#
d# = sqr(dx*dx + dy*dy)
if d >= 32.0
players[index].x# = 0.5*(players[index].x# + players[index].wx#)
players[index].y# = 0.5*(players[index].y# + players[index].wy#)
endif
elseif pkg.id = MSG_PLAYER_SHOOT
' index, type, angle
index = PlayerIndex(pkg.usr)
_P2P_Decompose pkg.msg$
bulletIndex = P2P_GetInt()
playerBullets[index][bulletIndex].type = P2P_GetInt()
a = P2P_GetInt()
dx# = cos(float(a))
dy# = sin(float(a))
playerBullets[index][bulletIndex].x# = players[index].wx# + dx*16.0
playerBullets[index][bulletIndex].y# = players[index].wy# + dy*16.0
playerBullets[index][bulletIndex].dx# = dx
playerBullets[index][bulletIndex].dy# = dy
elseif pkg.id = MSG_PLAYER_BULLET_DIED
index = PlayerIndex(pkg.usr)
_P2P_Decompose pkg.msg$
bulletIndex = P2P_GetInt()
playerBullets[index][bulletIndex].type = 0
elseif pkg.id = MSG_PLAYER_GRENADE
index = PlayerIndex(pkg.usr)
_P2P_Decompose pkg.msg$
grenadeIndex = P2P_GetInt()
playerGrenades[index][grenadeIndex].type = P2P_GetInt()
dstX# = P2P_GetFloat()
dstY# = P2P_GetFloat()
playerGrenades[index][grenadeIndex].sx# = players[index].x#
playerGrenades[index][grenadeIndex].sy# = players[index].y#
playerGrenades[index][grenadeIndex].dx# = dstX
playerGrenades[index][grenadeIndex].dy# = dstY
playerGrenades[index][grenadeIndex].p# = 0.0
dx# = playerGrenades[index][grenadeIndex].dx# - playerGrenades[index][grenadeIndex].sx#
dy# = playerGrenades[index][grenadeIndex].dy# - playerGrenades[index][grenadeIndex].sy#
d# = sqr(dx*dx + dy*dy)
playerGrenades[index][grenadeIndex].spd# = 4.0/d
endif
wend
endproc

' ------------------------------------------------------------------------------
' clear players.
' ------------------------------------------------------------------------------
procedure ClearPlayers()
for i = 0 to 3
players[i].type = PLY_NONE
for j = 0 to PLY_MAX_BULLETS - 1
playerBullets[i][j].type = 0
next
for j = 0 to PLY_MAX_GRENADES - 1
playerGrenades[i][j].type = 0
next
next
endproc

' ------------------------------------------------------------------------------
' add player.
' ------------------------------------------------------------------------------
procedure AddPlayer(id, name$)
for i = 0 to 3
if players[i].type = PLY_NONE then break
next
if i > 3
_Error "No player slot available"
endif
players[i].type = PLY_REMOTE
players[i].state = PLY_STATE_CONNECTING
players[i].id = id
players[i].name$ = name
endproc

' ------------------------------------------------------------------------------
' server full.
' ------------------------------------------------------------------------------
function ServerFull()
for i = 0 to 3
if players[i].type = PLY_NONE then return false
next
return true
endfunc

' ------------------------------------------------------------------------------
' get index in 'players' array for player id.
' ------------------------------------------------------------------------------
function PlayerIndex(id)
for i = 0 to 3
if players[i].type and players[i].id = id then return i
next
_Error "Player not found"
endfunc

' ------------------------------------------------------------------------------
' update player.
' ------------------------------------------------------------------------------
procedure UpdatePlayer(&ply?)
if ply.type = PLY_THIS
_UpdateThisPlayer ply
elseif ply.type = PLY_REMOTE
_UpdateRemotePlayer ply
elseif ply.type = PLY_BOT
_UpdateBotPlayer ply
endif
endproc

' ------------------------------------------------------------------------------
' update this player.
' ------------------------------------------------------------------------------
procedure UpdateThisPlayer(&ply?)
' aim.
mx# = float(mousex())
my# = float(mousey())
dx# = mx - ply.x#
dy# = my - ply.y#
k# = 1.0/sqr(dx*dx + dy*dy)
ply.aimX# = k*dx
ply.aimY# = k*dy
ply.a# = atan2(ply.aimY#, ply.aimX#)

' movement.
dxi = 0
dyi = 0
moving = false
if keydown(VK_LEFT) or keydown("A") then dxi = dxi - 1
if keydown(VK_RIGHT) or keydown("D") then dxi = dxi + 1
if keydown(VK_UP) or keydown("W") then dyi = dyi - 1
if keydown(VK_DOWN) or keydown("S") then dyi = dyi + 1
if dxi or dyi
dx# = float(dxi)
dy# = float(dyi)
k# = 1.0/sqr(dx*dx + dy*dy)
ply.dx# = k*dx
ply.dy# = k*dy
moving = true
else
ply.dx# = 0.0
ply.dy# = 0.0
endif
ply.x# = ply.x# + ply.dx#*ply.spd#
ply.y# = ply.y# + ply.dy#*ply.spd#

' environment collision (will use Tilemap lib later on).
if ply.x# < 0.0 then ply.x# = 0.0
if ply.x# > float(width(primary)) then ply.x# = float(width(primary))
if ply.y# < 0.0 then ply.y# = 0.0
if ply.y# > float(height(primary)) then ply.y# = float(height(primary))

if ply.ticks = 0
_TransmitPlayerPosition ply, moving
endif
ply.ticks = (ply.ticks + 1)%TSMT_PLY_POS_TICKS

' shooting.
if mousebutton(0, true)
for i = 0 to PLY_MAX_BULLETS - 1
if playerBullets[0][i].type = 0 then break
next
if i < PLY_MAX_BULLETS
playerBullets[0][i].type = 1
playerBullets[0][i].x# = ply.x# + ply.aimX#*16.0
playerBullets[0][i].y# = ply.y# + ply.aimY#*16.0
playerBullets[0][i].dx# = ply.aimX#
playerBullets[0][i].dy# = ply.aimY#

_P2P_ComposePackage MSG_PLAYER_SHOOT
_P2P_AddInt i
_P2P_AddInt playerBullets[0][i].type
_P2P_AddInt int(players[0].a#)
_P2P_SendComposed
endif
endif
' throw grenade.
if mousebutton(1, true)
for i = 0 to PLY_MAX_GRENADES - 1
if playerGrenades[0][i].type = 0 then break
next
if i < PLY_MAX_GRENADES
playerGrenades[0][i].type = 1
playerGrenades[0][i].sx# = ply.x#
playerGrenades[0][i].sy# = ply.y#
playerGrenades[0][i].dx# = float(mousex())
playerGrenades[0][i].dy# = float(mousey())
playerGrenades[0][i].p# = 0.0

dx# = playerGrenades[0][i].dx# - playerGrenades[0][i].sx#
dy# = playerGrenades[0][i].dy# - playerGrenades[0][i].sy#
d# = sqr(dx*dx + dy*dy)
playerGrenades[0][i].spd# = 4.0/d

_P2P_ComposePackage MSG_PLAYER_GRENADE
_P2P_AddInt i
_P2P_AddInt playerGrenades[0][i].type
_P2P_AddInt int(playerGrenades[0][i].dx#)
_P2P_AddInt int(playerGrenades[0][i].dy#)
_P2P_SendComposed
endif
endif
endproc

' ------------------------------------------------------------------------------
' update remote player.
' ------------------------------------------------------------------------------
procedure UpdateRemotePlayer(&ply?)
' must be ingame for updating.
if ply.state <> PLY_STATE_INGAME then return

dx# = ply.wx# - ply.x#
dy# = ply.wy# - ply.y#
d# = sqr(dx*dx + dy*dy)
if d > 0.0
k# = 1.0/d
ply.x# = ply.x# + dx*k*min#(d, 2.0)
ply.y# = ply.y# + dy*k*min#(d, 2.0)
if ply.mov
ply.wx# = ply.wx# + dx*k*2.0
ply.wy# = ply.wy# + dy*k*2.0
endif
endif

' environment collision (will use Tilemap lib later on).
if ply.x# < 0.0 then ply.x# = 0.0
if ply.x# > float(width(primary)) then ply.x# = float(width(primary))
if ply.y# < 0.0 then ply.y# = 0.0
if ply.y# > float(height(primary)) then ply.y# = float(height(primary))
endproc

' ------------------------------------------------------------------------------
' update bot player.
' ------------------------------------------------------------------------------
procedure UpdateBotPlayer(&ply?)
endproc

' ------------------------------------------------------------------------------
' transmit player position.
' ------------------------------------------------------------------------------
procedure TransmitPlayerPosition(&ply?, moving)
_P2P_ComposePackage MSG_PLAYER_POS
_P2P_AddInt int(ply.x#)
_P2P_AddInt int(ply.y#)
_P2P_AddInt int(ply.a#)
_P2P_AddInt moving
_P2P_SendComposed
endproc

' ------------------------------------------------------------------------------
' update player bullets.
' ------------------------------------------------------------------------------
procedure UpdatePlayerBullets()
for i = 0 to 3
' this player's bullets.
if i = 0
for j = 0 to PLY_MAX_BULLETS - 1
_UpdatePlayerBullet playerBullets[i][j], j
next
' remote bullets.
else
for j = 0 to PLY_MAX_BULLETS - 1
_UpdateRemotePlayerBullet playerBullets[i][j]
next
endif
next
endproc

' ------------------------------------------------------------------------------
' update grenades.
' ------------------------------------------------------------------------------
procedure UpdatePlayerGrenades()
for i = 0 to 3
for j = 0 to PLY_MAX_GRENADES - 1
if playerGrenades[i][j].type
_UpdateGrenade playerGrenades[i][j]
if i = 0 and playerGrenades[i][j].type = 0
' handle enemy collisions.
endif
endif
next
next
endproc

' ------------------------------------------------------------------------------
' update grenade.
' ------------------------------------------------------------------------------
procedure UpdateGrenade(&g?)
g.p# = g.p# + g.spd#
if g.p# >= 1.0
g.type = 0
endif
endproc

' ------------------------------------------------------------------------------
' update player bullet.
' ------------------------------------------------------------------------------
procedure UpdatePlayerBullet(&b?, index)
if b.type = 0 then return

b.x# = b.x# + b.dx#*8.0
b.y# = b.y# + b.dy#*8.0
if b.x# < 0.0 or b.x# >= float(width(primary)) or b.y# < 0.0 or b.y# >= float(height(primary))
b.type = 0
_P2P_ComposePackage MSG_PLAYER_BULLET_DIED
_P2P_AddInt index
_P2P_SendComposed
endif
endproc

' ------------------------------------------------------------------------------
' update remote player bullet.
' ------------------------------------------------------------------------------
procedure UpdateRemotePlayerBullet(&b?)
if b.type = 0 then return

b.x# = b.x# + b.dx#*8.0
b.y# = b.y# + b.dy#*8.0
endproc

' ------------------------------------------------------------------------------
' draw player.
' ------------------------------------------------------------------------------
procedure DrawPlayer(&ply?)
set color 255, 255, 255
x = int(ply.x#)
y = int(ply.y#)
draw rect x - 8, y - 8, 16, 16, true
draw line x, y, x + int(32.0*ply.aimX#), y + int(32.0*ply.aimY#)

set caret x, y - 32
center ply.name$
endproc

' ------------------------------------------------------------------------------
' clear log.
' ------------------------------------------------------------------------------
procedure ClearLog()
for i = 0 to MAX_LOG_MESSAGES - 1
vLog[i].type = 0
next
endproc

' ------------------------------------------------------------------------------
' add log message.
' ------------------------------------------------------------------------------
procedure Log(msg$, type)
for i = 0 to MAX_LOG_MESSAGES - 2
vLog[i] = vLog[i + 1]
next
vLog[MAX_LOG_MESSAGES - 1].txt$ = msg
vLog[MAX_LOG_MESSAGES - 1].type = type
vLog[MAX_LOG_MESSAGES - 1].a = 1024
endproc

' ------------------------------------------------------------------------------
' update log.
' ------------------------------------------------------------------------------
procedure UpdateLog()
for i = 0 to MAX_LOG_MESSAGES - 1
if vLog[i].type
vLog[i].a = vLog[i].a - 4
if vLog[i].a <= 0 then vLog[i].type = 0
endif
next

endproc

' ------------------------------------------------------------------------------
' draw log.
' ------------------------------------------------------------------------------
procedure DrawLog()
set caret 4, height(primary) - 4 - fheight(0)*MAX_LOG_MESSAGES
for i = 0 to MAX_LOG_MESSAGES - 1
if vLog[i].type
if vLog[i].type = LOG_CHAT;     set color 255, 255, 255, vLog[i].a
elseif vLog[i].type = LOG_INFO; set color 200, 200, 200, vLog[i].a
elseif vLog[i].type = LOG_GOOD; set color 0, 255, 0, vLog[i].a
elseif vLog[i].type = LOG_BAD;  set color 255, 0, 0, vLog[i].a
endif
wln vLog[i].txt$
else
wln
endif
next
endproc

' ------------------------------------------------------------------------------
' show error message and quit.
' ------------------------------------------------------------------------------
procedure Error(msg$)
set font 0
set color 0, 0, 0
cls
set color 255, 255, 255
set caret 0, 0
wln "ERROR: ", msg
redraw
wait 500
wait keydown
end
endproc
93
Announcements / Re: I'm not dead
« Last post by Mr Nutz on February 21, 2017 »
A lot of time since my last visit and I see this bad news :-[ My condolences...
NaaLaa is a very good program, you are a very good programmer, your Mother must be proud of you in paradise.
94
Announcements / Re: I'm not dead
« Last post by rickclark58 on February 04, 2017 »
Hey Marcus, it has been a long time. Sorry to hear about your Mom. I have had a similar loss recently myself. Glad to see NaaLaa is still around. I will give 6 a try. Glad to see you are still working on it.

Rick Clark
95
General discussion / Somethings's fishy about the speed library
« Last post by Marcus on January 27, 2017 »
While looking at a bunch of half finished games, that used to work, I noticed that many of them caused weird runtime errors when compiled with the latest naalaa. I narrowed it down to the Speed library. Replacing the latest Speed library with an older one, from naalaa 5 even, removed the runtime errors.
   I will have a look at this and try to figure out what's going on.
96
Code snippets / Re: Breakout principles (again, maybe)
« Last post by Rick3137 on January 19, 2017 »
   Nice work.

   It's times like this that I need a joystick. Using that laptop finger thingy gets a little tricky.
   Perhaps some arrow key action would work.  ^-^
97
Code snippets / Re: Breakout principles (again, maybe)
« Last post by B+ on January 18, 2017 »
I have recently done versions of Breakout and so am very curious to compare code.

Is there a way to find out what is in Speed.lib?

And I notice the ball angles differently if hits paddle in middle or left or right, is it 3 angles or more variations according to where it hits paddle? In my versions I had to throw in some randomness to prevent monotonous and non productive ball pattern bouncing.

Code: [Select]
rem Collision with paddle?
dx# = ballX + 8.0 - float(paddleX)
if abs#(dx) < 48.0 and ballY + 16.0 > float(paddleY) and ballY < float(paddleY) + 16.0
rem Bounce.
ballDY = -1.0
ballDX = dx/24.0
k# = 1.0/sqr(ballDX*ballDX + ballDY*ballDY)
ballDX = ballDX*k
ballDY = ballDY*k
endif

Yes, angle depends how far from center of paddle, I think?

Bullets!  ;D 

Surely must have some tanks left from Gorillas and Tanks game.  >:D

98
Code snippets / Re: Breakout principles (again, maybe)
« Last post by Marcus on January 18, 2017 »
I've been messing around a bit more with the code originaly from John, not sure if I'll finish it. CrackTheBricks is the game, CTBED is the editor (uses IUP).
99
Showcase / Re: JumpEm
« Last post by B+ on January 13, 2017 »
Yes, interesting game! I think I have to come up with AI for my own play!  ;)

At first I thought it would be 3 against 1 but I guess the other players focus on the other players as they are the real threat!  ;D
100
Showcase / Re: JumpEm
« Last post by Rick3137 on January 13, 2017 »
   Thanks Marcus;

   Feel free to use it on your game page.
   Before I made this game, I had a similar game that I lost and could not find again, so I was forced to make my own version to get it back.
Pages: 1 ... 8 9 [10]