BASIC

Author Topic: Retro Remakes 2006  (Read 5288 times)

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10697
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Retro Remakes 2006
« on: 2006-Jun-07 »
http://www.retroremakes.com/comp2006/
...ooops - hat schon angefangen.

Baggi

  • Guest
Retro Remakes 2006
« Reply #1 on: 2006-Jun-07 »
Hört sich nicht schlecht an der Wettbewerb.

Baggi

  • Guest
Retro Remakes 2006
« Reply #2 on: 2006-Jul-20 »
Hey Gernot,

es gibt bei dem Wettbewerb ja ein GLBasic zu gewinnen, cool.

Ich würde gerne mitmachen, habe auch schon eine Idee und auch schon den Helden des Spiels modelliert, aber wahrscheinlich bekomme ich das Spiel nicht fertig.

Machst du mit?

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10697
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Retro Remakes 2006
« Reply #3 on: 2006-Jul-20 »
Klar. Mit einem Freund zusammen. Such mal nach "Rock Bolt"

Baggi

  • Guest
Retro Remakes 2006
« Reply #4 on: 2006-Jul-20 »
Wow, das sieht ja richtig geil aus. Bin gespannt.

Ich kenn das original Spiel nicht?

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10697
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com

mannybass

  • Guest
Retro Remakes 2006
« Reply #6 on: 2006-Sep-11 »
Hi Gernot, das Spiel scheint toll geworden zu sein. Die Screenshots sehen klasse aus. Kann man den  endgültigen source code irgendwo bekommen?

Offline Kitty Hello

  • code monkey
  • Administrator
  • Prof. Inline
  • *******
  • Posts: 10697
  • here on my island the sea says 'hello'
    • View Profile
    • http://www.glbasic.com
Retro Remakes 2006
« Reply #7 on: 2006-Sep-11 »
Hm... Der Code ist hier:
Code: GLBasic [Select]
// --------------------------------- //
// Project: Rock 'N Bolt
// Start: Monday, June 05, 2006
// IDE Version: 3.138


// Drehricthung!



// That thingy is a platform. Moving/Locked/static - anything
TYPE PLATFORM
        // position (currently)
        x
        y
        // how much did the PF move this frame?
        dx; dy
        // state bits (see ShowLevel)
        state

        direction // positive or negative

        // 1=left.top, 2=bottom.right
        fixbits

        // minimum/maximum position
        // plafrom will move in a since curve between these
        minx; miny
        maxx; maxy

        // extension of the platform (should be >= 1 )
        extx; exty
ENDTYPE

// This is about the player(s)?
TYPE player
        x; y; dir  // x,y pos, direction
        anitime
        drillx; drilly // where he is after drilling
        life  // lives
        state // state bits - see MovePlayers
        on_pf // on what platform have I been -> don't fall!
        drilltime // how much time left for drilling (-1/+1 if any)
        drilldir  // what direction to rotate
ENDTYPE

// This is just a game structure to keep things at one place
TYPE GAME
        pads[] AS PLATFORM
        plys[] AS player
        startx; starty // starting position (that is: the elevator)
        level          // level index
        mapview        // 0 normal, 1 mapview
        leveldone      // done?
        remote_pos     // ypos of remote (1=off, 0=on)

        forcemap       // must assemble correctly
        levelokani     // a counter from 0-1if the level is done
        timeleft       // how  much time is left [sec]
        timepanik      // playing panic music?
        startlevel     // 0,1,2 -> start at different stages
        difficulty=1   // 0,1,2 -> just the time factor
        life           // number of lives
        dollars        // day's wage
        details=1      // true/false for city
ENDTYPE

GLOBAL thegame AS GAME
GLOBAL gameon // or gameover?
GLOBAL screenx, screeny
GLOBAL thistime
        GETSCREENSIZE screenx, screeny

// load + Display Splash screen at first thing you do
BLACKSCREEN
SHOWSCREEN
LOADBMP "gfx/splash.bmp"
SHOWSCREEN
LOCAL thistime = GETTIMERALL()+5000

        X_LOADOBJ "gfx/stahltraeger.ddd", 0;  LOADSPRITE "gfx/stahltraeger.bmp", 0
        X_LOADOBJ "gfx/stahltraeger_mitte.ddd", 1;  LOADSPRITE "gfx/stahltraeger_static.bmp", 1
        X_LOADOBJ "gfx/stahltraeger_seite.ddd", 2
        X_LOADOBJ "gfx/boden.ddd", 3
        X_LOADOBJ "gfx/aufzug.ddd", 4
        X_LOADOBJ "gfx/remote.ddd", 5           ; LOADSPRITE "gfx/remote.bmp", 5
        X_LOADOBJ "gfx/schraube.ddd",     10; LOADSPRITE "gfx/schraube.bmp", 10

// show splash screen (at least 5 secs)
LOCAL fps
GETFILE "limitfps.txt", 0, fps
IF fps <> 0 THEN LIMITFPS fps
WHILE GETTIMERALL() < thistime AND KEY(57)=FALSE AND MOUSEAXIS(3)=FALSE
        SHOWSCREEN
WEND

// fading from splash is not allowed...
BlendBmp("", "gfx/GMDesign.bmp")
                                                                          LOADSPRITE "gfx/schraube_doof.bmp", 11
        X_LOADOBJ "gfx/rodney.ddd",     20;   LOADSPRITE "gfx/rodney.bmp", 20
        // map = 100
        X_LOADOBJ "gfx/skydome.ddd",   200;   LOADSPRITE "gfx/hintergrund.bmp", 200
        X_LOADOBJ "gfx/skydome-sky.ddd",   201; LOADSPRITE "gfx/hintergrund_sky.bmp", 201
        X_LOADOBJ "gfx/skydome-superman.ddd",   202;    LOADSPRITE "gfx/superman.bmp", 202
        X_LOADOBJ "gfx/Stadt.ddd", 203; LOADSPRITE "gfx/Stadt.bmp", 203


BlendBmp("gfx/GMDesign.bmp", "gfx/Credits.bmp")

        X_LOADOBJ "gfx/logo.ddd",   300

        X_LOADOBJ "gfx/status_01.ddd", 301 // life
        X_LOADOBJ "gfx/status_02.ddd", 302 // time
        LOADSPRITE "gfx/wecker.bmp", 302
        X_LOADOBJ "gfx/status_03.ddd", 303 // $

BlendBmp("gfx/Credits.bmp", "gfx/hintergrund.bmp")
        LOADSOUND "sfx/festmachen.wav", 0,2
        LOADSOUND "sfx/loesen.wav", 1,2
        LOADSOUND "sfx/elevator.wav", 2,1
        LOADSOUND "sfx/bell.wav", 3,4




// MAINGAME
// -----------------------------

WHILE TRUE
        TitleScreen()
        MainGame()
WEND



// -----------------------------
// Like Blendscreen
// -----------------------------
FUNCTION BlendBmp: fileold$, filenew$
GLOBAL skip_blend
LOCAL good[], img, dt, start, best, time
        DIM good[2]
        BLACKSCREEN
        IF skip_blend THEN RETURN

        IF DOESFILEEXIST(fileold$)
                LOADSPRITE fileold$, 500
        ELSE
                GRABSPRITE 500,0,0,16,16
        ENDIF

        IF DOESFILEEXIST(filenew$)
                LOADSPRITE filenew$, 501
        ELSE
                GRABSPRITE 501,0,0,16,16
        ENDIF

        start = GETTIMERALL()
        time=start
        best = start + 3000

        WHILE time<best+1000
                IF Joypad(0, 2) THEN skip_blend  =TRUE
                IF skip_blend THEN RETURN
                dt = MIN(1, (time-start)/(best-start))
                FOR img=0 TO 1
                        IF img = 0 THEN ALPHAMODE MIN(-.01, MAX(-1, -(1 - dt) ))
                        IF img = 1 THEN ALPHAMODE MIN(-.01, MAX(-1,     - dt  ))
                        STRETCHSPRITE 500+img, 0, 0, screenx, screeny
                        ALPHAMODE 0
                NEXT

                SHOWSCREEN
                time = GETTIMERALL()
        WEND
        ALPHAMODE 0
ENDFUNCTION


// -----------------------------
// MAINGAME
// -----------------------------
FUNCTION MainGame:
GLOBAL gameon
LOCAL time$, mins, secs, lasttime

        LOADFONT "bigfont.bmp", 0

        thegame.life = 3
        thegame.dollars = 0
        thegame.level = thegame.startlevel * 5 +1
        LoadLevel(thegame.level)

        gameon  = TRUE
        WHILE gameon
                lasttime = thistime
                thistime = GETTIMERALL()
                MovePlatforms()
                MovePlayers(thistime - lasttime)
                ShowLevel3D(0)
//              X_MAKE2D; ShowLevel(0)

                X_MAKE2D
                PRINT "Crsr  to Move", 0,0
                PRINT "LCtrl to Screw", 0,20

                SHOWSCREEN
        WEND
ENDFUNCTION


// -----------------------------------------
// Sketch - Draw a "free hand line"
// -----------------------------------------
FUNCTION Sketch: x1,y1, dx, dy, striplen, overlen, noise, col
LOCAL phi, dist, cx, cy, noisex, noisey
        phi=ATAN(dy,dx) + (RND(2000)/1000 -1 )*noise
        dist=SQR(dx*dx+dy*dy) * 0.5
        cx=x1+dx/2
        cy=y1+dy/2

        IF dist*2 > striplen AND striplen > 1
                dx=dx/2
                dy=dy/2
                Sketch(x1,y1, dx,dy, striplen, overlen, noise, col)
                Sketch(cx,cy, dx,dy, striplen, overlen, noise, col)
                DRAWLINE x1,y1, x1+dx, y1+dy, col
                RETURN
        ENDIF

        INC dist, overlen
        noisex = SIN(phi)*(RND(2000)/800-1)
        noisey = COS(phi)*(RND(2000)/800-1)

        DRAWLINE cx,cy, cx+COS(phi)*dist+noisex, cy+SIN(phi)*dist+noisey, col
        DRAWLINE cx,cy, cx-COS(phi)*dist+noisex, cy-SIN(phi)*dist+noisey, col
ENDFUNCTION

// -----------------------------------------
// SkArrow - Draw a "free hand arrow" from x1 to x2
// -----------------------------------------
FUNCTION SkArrow: x1,y1, x2,y2, striplen, overlen, noise, col
LOCAL dx, dy, l, i
        dx = x2-x1
        dy = y2-y1
        Sketch(x1,y1, dx, dy, striplen, overlen, noise, col)

        l = SQR(dx*dx + dy*dy)
        dx=dx*4/l
        dy=dy*4/l
        FOR i=0 TO 32
                Sketch(x1,y1, dx, dy, dx+dy, 0, 65, col)
                Sketch(x2,y2,-dx,-dy, dx+dy, 0, 65, col)
        NEXT
ENDFUNCTION

// -----------------------------------------
// GETPOW2 - Get smallest number that's 2^m and >= n
// -----------------------------------------
FUNCTION GetPow2: n
LOCAL x
        x=1
        WHILE x<n
                x=x+x
        WEND
        RETURN x
ENDFUNCTION

// -----------------------------------------
// CREATEMAP
// -----------------------------------------
FUNCTION CreateMap: spr_id
LOCAL i, scale, x,y, sx, sy, fix$
LOCAL col_bk, col_drw, col_arr
LOCAL overlen, striplen, noise, iy, ix
LOCAL sprx, spry, q

        col_bk =  RGB(0x00, 0x00, 0xf0)
        col_drw = RGB(0x60, 0x60, 0xf6)
        col_arr = RGB(0xff, 0xff, 0xff)

        // platform collision = 1x1 unit
        // scaling of gfx is just for better visibility
        scale = screenx/32

        FILLRECT 0,0,screenx, screeny, col_bk

        // pads
        overlen = scale*.08
        striplen= scale*.7
        noise   = 1

        FOR i=0 TO BOUNDS(thegame.pads[], 0)-1
                sx= thegame.pads[i].extx
                sy= thegame.pads[i].exty

                q=4
                // move-to position
                IF thegame.pads[i].minx<>thegame.pads[i].maxx OR thegame.pads[i].miny<>thegame.pads[i].maxy
                        x = INTEGER(thegame.pads[i].maxx * scale)+1
                        y = INTEGER(thegame.pads[i].maxy * scale)+1
                        Sketch(x,y, sx*scale-q, 0, striplen, overlen, noise, col_drw)
                        Sketch(x,y, 0, sy*scale-q, striplen, overlen, noise, col_drw)
                        Sketch(x,y+sy*scale-q, sx*scale-q, 0, striplen, overlen, noise, col_drw)
                        Sketch(x+sx*scale-q,y, 0, sy*scale-q, striplen, overlen, noise, col_drw)
                        Sketch(x,y, sx*scale-q, sy*scale-q, striplen, overlen, noise, col_drw)
                ENDIF

                // must be position / or static one
                x = INTEGER((thegame.pads[i].minx+.1) * scale)+1
                y = INTEGER((thegame.pads[i].miny+.1) * scale)+1
                Sketch(x,y, sx*scale-q, 0, striplen, overlen, noise, col_arr)
                Sketch(x,y, 0, sy*scale-q, striplen, overlen, noise, col_arr)
                Sketch(x,y+sy*scale-q, sx*scale-q, 0, striplen, overlen, noise, col_arr)
                Sketch(x+sx*scale-q,y, 0, sy*scale-q, striplen, overlen, noise, col_arr)

                // moving arrow
                IF thegame.pads[i].minx<>thegame.pads[i].maxx OR thegame.pads[i].miny<>thegame.pads[i].maxy
                        x = INTEGER((thegame.pads[i].minx+.1) * scale)+1
                        y = INTEGER((thegame.pads[i].miny+.1) * scale)+1
                        INC x, sx/2*scale
                        INC y, sy/2*scale
                        ix = INTEGER((thegame.pads[i].maxx+sx/2) * scale)
                        iy = INTEGER((thegame.pads[i].maxy+sy/2) * scale)
                        SkArrow(x,y,ix,iy,striplen*2, overlen/2, noise/2, col_drw)
                ENDIF

                // hatching of static position
                IF thegame.forcemap
                        x = INTEGER((thegame.pads[i].minx+.1) * scale)+1
                        y = INTEGER((thegame.pads[i].miny+.1) * scale)+1
                        VIEWPORT x+1,y+1,sx*scale-q, sy*scale-q
                        FOR iy=-(sx+sy)*scale TO sy*scale STEP scale/4
                                IF thegame.pads[i].minx<>thegame.pads[i].maxx OR thegame.pads[i].miny<>thegame.pads[i].maxy
                                        Sketch(0,iy,sx*scale,sx*scale, striplen, overlen, noise, col_drw)
                                ELSE
                                //      Sketch(0,iy,sx*scale,sx*scale*.5, striplen, overlen, noise, col_arr)
                                        INC iy, scale/6
                                ENDIF
                        NEXT
                        VIEWPORT 0,0,0,0
                ENDIF

//              FILLRECT x, y, x+sx*scale, y+sy*scale, col_drw
//              FILLRECT x+1, y+1, x+sx*scale-2, y+sy*scale-2, col_bk
        NEXT

        GRABSPRITE spr_id, 0,0, 31*scale, 11*scale

        sprx = 31*scale / GetPow2(31*scale)
        spry = 11*scale / GetPow2(11*scale)

        scale = 2 // block scale in 3D view
        i=RGB(255,255,255)
        X_OBJSTART 100
                X_OBJADDVERTEX -scale*.5  , 0,-scale*  .5, 0   ,-spry,i
                X_OBJADDVERTEX -scale*.5  , 0, scale*10.5, 0   ,0    ,i
                X_OBJADDVERTEX  scale*30.5, 0,-scale*  .5, sprx,-spry,i
                X_OBJADDVERTEX  scale*30.5, 0, scale*10.5, sprx,0    ,i
        X_OBJEND
ENDFUNCTION


// -----------------------------------------
// Check if the level is OK this way
// -----------------------------------------
FUNCTION IsLevelDone:
LOCAL i, posbad
        // pads (0=elevator!!)
        FOR i=1 TO BOUNDS(thegame.pads[], 0)-1
                posbad = ABS(thegame.pads[i].x - thegame.pads[i].minx) + ABS (thegame.pads[i].y-thegame.pads[i].miny)
                IF thegame.forcemap=FALSE AND posbad
                        posbad = ABS(thegame.pads[i].x - thegame.pads[i].maxx) + ABS(thegame.pads[i].y-thegame.pads[i].maxy)
                ENDIF

                // not on good position?
                IF posbad
                        RETURN FALSE
                ELSE
                        // moving but not locked?
                        IF thegame.pads[i].minx<>thegame.pads[i].maxx OR thegame.pads[i].miny<>thegame.pads[i].maxy
                                IF thegame.pads[i].fixbits=0 THEN RETURN FALSE
                        ENDIF
                ENDIF

        NEXT
        RETURN TRUE
ENDFUNCTION


// -----------------------------------------
// SHOWLEVEL - guess what? It draws everything
// -----------------------------------------
FUNCTION ShowLevel: nstorey
LOCAL i, scale, x,y, sx, sy, fix$

        // platform collision = 1x1 unit
        // scaling of gfx is just for better visibility
        scale = 16

        // pads
        FOR i=0 TO BOUNDS(thegame.pads[], 0)-1
                x = INTEGER(thegame.pads[i].x * scale)
                y = INTEGER(thegame.pads[i].y * scale)
                sx= thegame.pads[i].extx
                sy= thegame.pads[i].exty
                FILLRECT x, y, x+sx*scale, y+sy*scale, RGB(0x00, 0x80, 0xff)

                fix$="O"
                IF BAND(thegame.pads[i].fixbits, 2) THEN fix$="X"
                PRINT fix$, x+(sx-1)*scale+6, y+(sy-1)*scale+6

                fix$="O"
                IF BAND(thegame.pads[i].fixbits, 1) THEN fix$="X"
                PRINT fix$, x+6, y+6

        NEXT

        // players
        FOR i=0 TO BOUNDS(thegame.plys[], 0)-1
                PRINT "P"+(i+1), thegame.plys[i].x*scale, thegame.plys[i].y*scale
        NEXT
ENDFUNCTION


// -----------------------------------------
// convert x,y to x,y,z (storey) and drop a X_MOVEMNT line
// pos[3] = camera rotation angle!
// -----------------------------------------
FUNCTION xtranslate: x,y, pos[]
LOCAL gx,gy,gz,storey, xzscale
        DIM pos[3]

        xzscale= 2 // size of a block
        pos[0] = x*xzscale
        pos[1] = 0
        pos[2] = y*xzscale
ENDFUNCTION


// -----------------------------------------
// Assemble a girder from the parts we have
// -----------------------------------------
FUNCTION DrawGirder: posx, posy, dx, dy, shift_level, fixed
//X_LOADOBJ "gfx/stahltraeger.ddd", 0;  LOADSPRITE "gfx/stahltraeger.bmp", 0
//X_LOADOBJ "gfx/stahltraeger_mitte.ddd", 1
//X_LOADOBJ "gfx/stahltraeger_seite.ddd", 2

LOCAL x, y, rot, tile, pos[]
        DEC dx, 1
        DEC dy, 1
        X_CULLMODE 1

        IF fixed
                X_SETTEXTURE -1,-1
        ELSE
                X_SETTEXTURE 0,-1
        ENDIF
        X_SCALING 1.01, 1.01, 1.01
        IF dy>=dx
                FOR x=0 TO dx
                        FOR y=0 TO dy
                                tile=1; rot=0
                                IF dy>0 AND y=dy THEN tile=2
                                IF dy>0 AND y=0; tile=2; rot=180; ENDIF
                                IF dy=0 THEN tile=0
                                xtranslate(posx+x, posy+y+shift_level, pos[])
                                X_MOVEMENT pos[0], pos[1], pos[2]
                                X_ROTATION rot, 0,1,0
                                IF fixed THEN tile = 3
                                X_DRAWOBJ tile, 0
                        NEXT
                NEXT
        ELSE
                FOR x=0 TO dx
                        FOR y=0 TO dy
                                tile=1; rot=0
                                IF dx>0 AND x=dx THEN tile=2
                                IF dx>0 AND x=0; tile=2; rot=180; ENDIF
                                IF dx=0 THEN tile=0
                                xtranslate(posx+x, posy+y, pos[])
                                X_MOVEMENT pos[0], pos[1]+shift_level, pos[2]
                                X_ROTATION rot+90, 0,1,0
                                IF fixed THEN tile = 3
                                X_DRAWOBJ tile, 0
                        NEXT
                NEXT
        ENDIF
ENDFUNCTION

// -----------------------------------------
// Show the whole level in 3D
// -----------------------------------------
FUNCTION ShowLevel3D: nstorey
LOCAL i, j, x,y, sx, sy, dx, dy, pos[], d, rot, fixed
LOCAL ani, fullani, from, upto, time, t$
LOCAL secs, mins
LOCAL shift_level, cam_pos[]
LOCAL fog_col

        fog_col = RGB(0xaa, 0xaa, 0xff)
        DIM cam_pos[3]
        DIM pos[3]

        IF thegame.details
                FILLRECT 0,0,screenx, screeny, fog_col
        ELSE
                X_MAKE3D .1, 200, 45

                X_CAMERA 0,5*thegame.mapview,2-2*thegame.mapview+.1, 0,0,0
                X_CULLMODE 1
                X_MOVEMENT 0,0,0
                X_ROTATION (thegame.plys[0].x-thegame.plys[0].y)*8+180, 0,1,0
                X_SETTEXTURE 200,-1
                X_DRAWOBJ 200,0
                IF thegame.mapview
                        X_CLEAR_Z
                        ALPHAMODE -thegame.mapview*.9
                        X_SETTEXTURE 201,-1
                        X_DRAWOBJ 201,0
                        ALPHAMODE 0
                ENDIF
                X_CLEAR_Z
        ENDIF

        // star-dome, level done
        IF thegame.levelokani
                X_MAKE3D .1, 200, 45
                X_CAMERA 0,5*thegame.mapview,2-2*thegame.mapview+.1, 0,0,0
                X_CULLMODE 1
                ALPHAMODE MAX(-1, -thegame.levelokani)
                X_SETTEXTURE 202,-1
                X_SETTEXTUREOFFSET 0, thegame.levelokani*3
                X_DRAWOBJ 202,0
                X_SETTEXTUREOFFSET 0, 0
                ALPHAMODE 0
                X_CLEAR_Z
        ENDIF

        // 80 enough for game
        X_MAKE3D .5, 200, 45
        X_CULLMODE 1
        d = 9
        xtranslate(thegame.plys[0].x, thegame.plys[0].y, pos[])
        X_CAMERAUP -1,1,-1
        cam_pos[0] = pos[0]+d*(1-thegame.mapview)
        cam_pos[1] = pos[1]+d*.75+20*thegame.mapview
        cam_pos[2] = pos[2]+d*(1-thegame.mapview)
        X_CAMERA cam_pos[0],cam_pos[1],cam_pos[2], pos[0],pos[1]+d*.25,pos[2]
        // zoom level down when done
        shift_level = -(1-COS(MIN(1, thegame.levelokani*2)*90)) * 20

        IF thegame.details
                // 3D city
                X_SPOT_LT 0, RGB(0xff,0xff,0xff), pos[0]+350,pos[1]+250,pos[2]+50, 0,1,0,360
                X_FOG RGB(0xb0, 0xb0, 0xff), FALSE, 30, 50
                X_MOVEMENT cam_pos[0]/2, shift_level*1.5, cam_pos[2]/2
                X_SETTEXTURE 203,-1
                X_DRAWOBJ 203, 0
                X_SPOT_LT 0, 0, 0,0,0, 0,1,0,0
        ENDIF

        // Cel Shading
        X_SPOT_LT -2, RGB(0xff,0xff,0xff), pos[0]+350,pos[1]+250,pos[2]+50, 0,1,0,360

        // Life/Clock/$$$
        IF thegame.difficulty
                secs = INTEGER(thegame.timeleft)
                mins = INTEGER(thegame.timeleft/60)
                secs = secs - mins*60
                t$=FORMAT$(2,0,mins)+":"+FORMAT$(2,0,secs)

                rot = GETTIMERALL() / 30
                X_MOVEMENT pos[0]-20, pos[1]+6, pos[2]-10
                X_ROTATION SIN(rot+120)*45+45, .05,1,.1
                X_SETTEXTURE 302,-1
                X_DRAWOBJ 302, 0
                X_PRINT t$, pos[0]-20, pos[1]+4.0, pos[2]-10, 0

                X_MOVEMENT pos[0]-15, pos[1]+5, pos[2]-15
                X_ROTATION SIN(rot)*45+90, .1,1,.05
                X_SETTEXTURE 20,-1
                X_DRAWOBJ 301, 0
                X_PRINT "x"+thegame.life, pos[0]-15, pos[1]+4, pos[2]-15, 0

                X_MOVEMENT pos[0]-10, pos[1]+6, pos[2]-20
                X_ROTATION SIN(rot+240)*45-25, .1,1,-.05
                X_SETTEXTURE -1,-1
                X_DRAWOBJ 303, 0
                X_PRINT FORMAT$(0,2,thegame.dollars), pos[0]-10, pos[1]+4.0, pos[2]-20, 0
        ENDIF

        // Fog
        X_FOG fog_col, FALSE, 20, 40

        // pads (0=elevator!!)
        FOR i=1 TO BOUNDS(thegame.pads[], 0)-1
                x = thegame.pads[i].x
                y = thegame.pads[i].y
                sx= thegame.pads[i].extx
                sy= thegame.pads[i].exty

        X_CULLMODE 1
                // first the screws
                IF thegame.forcemap
                        IF thegame.pads[i].x = thegame.pads[i].minx AND thegame.pads[i].y=thegame.pads[i].miny
                                X_SETTEXTURE 10, -1 // good one
                        ELSE
                                X_SETTEXTURE 11, -1 // bad one
                        ENDIF
                ELSE
                        X_SETTEXTURE 10, -1 // any one
                ENDIF

                IF BAND(thegame.pads[i].fixbits, 2)
                        xtranslate(x+(sx-1), y+(sy-1), pos[] )
                        X_MOVEMENT pos[0], pos[1]+shift_level, pos[2]
                        X_ROTATION i*35+15,0,1,0
                        X_DRAWOBJ 10,0
                ENDIF

                IF BAND(thegame.pads[i].fixbits, 1)
                        xtranslate(x,y, pos[] )
                        X_MOVEMENT pos[0], pos[1]+shift_level, pos[2]
                        X_ROTATION i*35,0,1,0
                        X_DRAWOBJ 10,0
                ENDIF

                fixed=0
                IF      thegame.pads[i].minx=thegame.pads[i].maxx AND _
                        thegame.pads[i].miny=thegame.pads[i].maxy THEN fixed=1
                DrawGirder(x, y, sx, sy, shift_level, fixed)
                X_SCALING 1,1,1
        NEXT

        // Elevator - #need y pos
        X_SETTEXTURE -1,-1
        xtranslate(thegame.pads[0].x, thegame.pads[0].y, pos[] )
        X_SCALING .95,1,.95
        X_MOVEMENT pos[0], pos[1], pos[2]
        X_ROTATION 180,0,1,0
        X_DRAWOBJ 4, 0
        X_SCALING 1,1,1

        // remote control
        IF thegame.remote_pos<>1
                X_MOVEMENT pos[0], pos[1]+thegame.remote_pos*8.0 + SIN(thistime/10)*.1, pos[2]
                X_ROTATION 180+SIN(thistime/15)*5,0,1,0
                X_SETTEXTURE 5,-1
                X_DRAWOBJ 5, 0
        ENDIF

        // players
        X_MOVEMENT 0,0,0
        FOR i=0 TO BOUNDS(thegame.plys[], 0)-1
                xtranslate(thegame.plys[i].x-.5, thegame.plys[i].y-.5, pos[] )
                X_SETTEXTURE 20,-1
                X_SCALING .32, .32, .32
                X_MOVEMENT pos[0], pos[1], pos[2]

                // Superman - animation
                IF thegame.levelokani
                        from=1; upto = 5
                        ani = MIN(1, thegame.levelokani*3)
                        X_DRAWANIM 20,from,upto,ani, FALSE

                        X_MAKE2D
                        ALPHAMODE .5
                ELSE
                        // is drilling (rotation)
                        IF thegame.plys[i].drilltime<>0
                                ani = MIN(1, (1000-ABS(thegame.plys[i].drilltime))/500)
                                fullani=FALSE
                                from = 1
                                upto = 4
                                d=ani
                                IF thegame.plys[i].drilltime<0
                                        d=-ani
                                        upto=3
                                        X_ROTATION SIN(d*90) * 360, 0,1,0
                                ENDIF
                                X_ROTATION SIN(d*90) * 360, 0,1,0
                        ELSE
                                fullani=TRUE
                                from = 0
                                upto = 2
                                time=MOD(thistime - thegame.plys[i].anitime +250, 1000)
                                // ping-pong
                                ani = (1+COS(time/1000*360))/2
                        ENDIF

                        X_ROTATION thegame.plys[i].dir, 0,1,0
                        X_DRAWANIM 20,from,upto,ani, fullani
                ENDIF

        NEXT

        // draw the map object
        X_FOG -1, FALSE, 0,0
        X_SPOT_LT -2, 0, 0,0,0, 0,0,0, 0

        IF thegame.mapview
        //      X_CAMERA pos[0],pos[1]+d*.75+40,pos[2], pos[0],pos[1]+d*.25,pos[2]
                X_CULLMODE 0
                X_SCALING 1,1,1
                X_SETTEXTURE 100, -1
                X_MOVEMENT 0,.05,0
                ALPHAMODE -thegame.mapview*.8
                X_DRAWOBJ 100,0
                ALPHAMODE 0
        ENDIF

        X_MAKE2D
        PRINT "Level"+thegame.level, 0,100
ENDFUNCTION


// -----------------------------------------
// MOVEPLATFORMS - update platform positions if they move
// -----------------------------------------
FUNCTION MovePlatforms:
LOCAL i, j, len_path, dx, dy, plat AS PLATFORM
LOCAL pos, oldx, oldy, dtime, vel
        FOR i=0 TO BOUNDS(thegame.pads[], 0)-1
                plat = thegame.pads[i]
                thegame.pads[i].dx = 0
                thegame.pads[i].dy = 0
                IF plat.fixbits = 0 // moving
                        dx = plat.maxx-plat.minx
                        dy = plat.maxy-plat.miny
                        IF dx<>0 OR dy<>0
                                len_path=SQR(dx*dx + dy*dy)

//                              pos = GETTIMERALL()/len_path * .1
//                              pos = (1+SIN(pos))/2.0 // [0;1]
//                              thegame.pads[i].x = (plat.maxx - plat.minx) * pos + plat.minx
//                              thegame.pads[i].y = (plat.maxy - plat.miny) * pos + plat.miny

                                IF len_path=0 THEN CONTINUE

                                // if this copy of a platform is flipped
                                // then just flip it for interpolation
                                IF plat.minx>plat.maxx
                                        pos = plat.minx
                                        plat.minx=plat.maxx
                                        plat.maxx=pos
                                ENDIF
                                IF plat.miny>plat.maxy
                                        pos = plat.miny
                                        plat.miny=plat.maxy
                                        plat.maxy=pos
                                ENDIF


                                IF plat.minx<>plat.maxx
                                        pos = (plat.x-plat.minx) / ABS(plat.maxx - plat.minx)
                                ELSE
                                        pos = (plat.y-plat.miny) / ABS(plat.maxy - plat.miny)
                                ENDIF

                                dtime  =GETTIMER() / (1000*len_path)
                                IF plat.direction>=0
                                        vel = (SIN(pos*180) + .1) * dtime
                                ELSE
                                        vel = -(SIN((1-pos)*180) + .1) * dtime
                                ENDIF

                                oldx = plat.x
                                oldy = plat.y
                                INC plat.x, vel*(plat.maxx - plat.minx)
                                INC plat.y, vel*(plat.maxy - plat.miny)
                                IF plat.x>plat.maxx OR plat.y>plat.maxy
                                        plat.x = plat.maxx
                                        plat.y = plat.maxy
                                        plat.direction = -1
                                ENDIF

                                IF plat.x<plat.minx OR plat.y<plat.miny
                                        plat.x = plat.minx
                                        plat.y = plat.miny
                                        plat.direction = 1
                                ENDIF

                                // this get's headache due to the flip above
                                plat.minx = thegame.pads[i].minx
                                plat.miny = thegame.pads[i].miny
                                plat.maxx = thegame.pads[i].maxx
                                plat.maxy = thegame.pads[i].maxy
                                thegame.pads[i] = plat

                                // store relative movement for later player movement
                                thegame.pads[i].dx = thegame.pads[i].x - oldx
                                thegame.pads[i].dy = thegame.pads[i].y - oldy
                        ENDIF
                ENDIF
        NEXT
ENDFUNCTION


// -----------------------------------------
// return platform index or -1 for point x,y
// -----------------------------------------
FUNCTION IsThereAPlatform: x, y
LOCAL i, col
        FOR i=0 TO BOUNDS(thegame.pads[],0)-1
                BOXCOLL col, x,y,0,0, thegame.pads[i].x,thegame.pads[i].y, thegame.pads[i].extx,thegame.pads[i].exty
                IF col THEN RETURN i
        NEXT
RETURN -1
ENDFUNCTION


// -----------------------------------------
// Shift the player if possible
// and also shift due to moving platforms
// -----------------------------------------
FUNCTION ShiftPlayer: nply, dx, dy
LOCAL x, y, i, xy
        i = thegame.plys[nply].on_pf
        IF i>=0
                // Move player with the platform
                INC thegame.plys[nply].x, thegame.pads[i].dx
                INC thegame.plys[nply].y, thegame.pads[i].dy
                INC thegame.plys[nply].drillx, thegame.pads[i].dx
                INC thegame.plys[nply].drilly, thegame.pads[i].dy
        ENDIF

        FOR xy=0 TO 1
                x = thegame.plys[nply].x
                y = thegame.plys[nply].y
                IF xy
                        x = thegame.plys[nply].x + dx
                ELSE
                        y = thegame.plys[nply].y + dy
                ENDIF

                i = IsThereAPlatform(x,y)
                IF i>=0
                        thegame.plys[nply].on_pf = i
                        IF xy
                                thegame.plys[nply].x = x
                        ELSE
                                thegame.plys[nply].y = y
                        ENDIF
                ENDIF
        NEXT

        // change walking direction
        IF dx OR dy THEN thegame.plys[nply].dir = (thegame.plys[nply].dir+ATAN(-dy,dx))/2
ENDFUNCTION


// -----------------------------------------
// DRILLPLATFORMAT
// -----------------------------------------
FUNCTION DrillPlatformAt: nply, x,y
LOCAL i, plat AS PLATFORM, fix, drillpos, delta
LOCAL tighten
        i = IsThereAPlatform(x,y)
        IF i<0 THEN RETURN FALSE

        // See if platform is close to ends
        plat = thegame.pads[i]

delta=0.1 // how close must you stand?
        // can't lock a static platform
        IF plat.minx=plat.maxx AND plat.miny=plat.maxy THEN RETURN FALSE
        IF (ABS(plat.x-plat.minx)<delta AND ABS(plat.y-plat.miny)<delta) THEN fix=1
        IF (ABS(plat.x-plat.maxx)<delta AND ABS(plat.y-plat.maxy)<delta) THEN fix=2

        tighten = TRUE // put a screw in

        IF fix
                // Pin fixbit '1' (lower, left corner)
                IF x<plat.x+1 AND y<plat.y+1
                        IF BAND(plat.fixbits, 1)
                                tighten=FALSE
                                DEC plat.fixbits, 1
                                thegame.plys[nply].drilldir=1
                        ELSE
                                INC plat.fixbits, 1
                                thegame.plys[nply].drilldir=-1
                        ENDIF
                ELSE
                        IF x>plat.x+plat.extx-1 AND y>plat.y+plat.exty-1
                                // Pin fixbit '2'
                                IF BAND(plat.fixbits, 2)
                                        tighten=FALSE
                                        DEC plat.fixbits, 2
                                ELSE
                                        INC plat.fixbits, 2
                                ENDIF
                                drillpos = 1
                        ELSE
                                RETURN FALSE // x,y is not close to a fixbit
                        ENDIF
                ENDIF

                // Finally put the platform to its locked position
                thegame.pads[i].fixbits = plat.fixbits
                IF fix = 1
                        thegame.pads[i].x = plat.minx
                        thegame.pads[i].y = plat.miny
                ELSE
                        thegame.pads[i].x = plat.maxx
                        thegame.pads[i].y = plat.maxy
                ENDIF

                // Center the player on the bolt
                thegame.plys[nply].drillx = thegame.pads[i].x+drillpos*(plat.extx-1) + .5
                thegame.plys[nply].drilly = thegame.pads[i].y+drillpos*(plat.exty-1) + .5
                thegame.leveldone = IsLevelDone()
                IF tighten
                        PLAYSOUND 0, 0,1
                        INC thegame.dollars, 2.5
                        thegame.plys[nply].drilltime = 1000
                ELSE
                        PLAYSOUND 1, 0,1
                        thegame.dollars = MAX(0, thegame.dollars-2.5)
                        thegame.plys[nply].drilltime = -1000
                ENDIF
        ENDIF

        RETURN FALSE
ENDFUNCTION


// -----------------------------------------
// JOYPAD - wrapper for user input
// -----------------------------------------
FUNCTION Joypad: npad, mode
        SELECT mode
                CASE 0; RETURN KEY(205)-KEY(203) + GETJOYX(0)
                CASE 1; RETURN KEY(208)-KEY(200) + GETJOYY(0)
                CASE 2; RETURN KEY(29)           + GETJOYBUTTON(0, 2) // LCtrl - drill
                CASE 3; RETURN KEY(50)           + GETJOYBUTTON(0, 0) // M - map
        ENDSELECT
ENDFUNCTION

// -----------------------------------------
// MOVEPLAYERS - handle user input
// -----------------------------------------
FUNCTION MovePlayers: dtime
LOCAL i, dx, dy
GLOBAL trigga_down
        IF thegame.difficulty AND thegame.levelokani<=0
                thegame.timeleft = MAX(0, thegame.timeleft - dtime/1000)
                IF thegame.timeleft = 0
                        thegame.timeleft = 1000
                        DEC thegame.life, 1
                        IF thegame.life<0 THEN gameon=FALSE
                ENDIF
        ENDIF

        IF thegame.levelokani <=0 THEN Music()
        dtime = dtime/500.0

        // Mapview
        IF Joypad(0, 3)
                thegame.mapview = MIN(thegame.mapview+dtime/3, 1)
        ELSE
                thegame.mapview = MAX(thegame.mapview-dtime/3, 0)
        ENDIF

        // position of remote control for exit
        IF thegame.leveldone
                thegame.remote_pos = MAX(0, thegame.remote_pos-dtime/3)
        ELSE
                thegame.remote_pos = MIN(1, thegame.remote_pos+dtime/2)
        ENDIF

        FOR i=0 TO BOUNDS(thegame.plys[], 0)-1
                // is the level complete?
                IF thegame.leveldone
                        IF IsThereAPlatform(thegame.plys[i].x, thegame.plys[i].y) = 0 // on exit
                                // Center the player on the bolt
                                thegame.plys[i].drillx = thegame.pads[0].x+ .5
                                thegame.plys[i].drilly = thegame.pads[0].y+ .5
                                IF thegame.levelokani = 0
                                        PLAYSOUND 2,0,1 // elevator
                                        FMod_Stop()
                                ENDIF
                                INC thegame.levelokani, dtime/4

                                // Add score for time left, when level done
                                IF thegame.levelokani>2
                                        IF thegame.timeleft>0
                                                thegame.timeleft = MAX(0, thegame.timeleft-GETTIMER()/100 )
                                                INC thegame.dollars, thegame.timeleft/60
                                                PLAYSOUND 3,0,1 // bell
                                        ENDIF
                                ENDIF

                                // after ani - load level+go
                                IF thegame.levelokani > 5
                                        INC thegame.level, 1
                                        LoadLevel(thegame.level)
                                        g_nSongPlay=-1
                                        Music()
                                ENDIF
                                RETURN
                        ENDIF
                ENDIF

                SELECT thegame.plys[i].state
                        CASE 0 // player
                                IF thegame.plys[i].drilltime<>0
                                        INC thegame.plys[i].x, (thegame.plys[i].drillx - thegame.plys[i].x)*dtime*2
                                        INC thegame.plys[i].y, (thegame.plys[i].drilly - thegame.plys[i].y)*dtime*2

                                        ShiftPlayer(i, 0, 0) // platform might have started to move
                                        IF thegame.plys[i].drilltime>0
                                                thegame.plys[i].drilltime = MAX(0, thegame.plys[i].drilltime-GETTIMER())
                                        ELSE
                                                thegame.plys[i].drilltime = MIN(0, thegame.plys[i].drilltime+GETTIMER()/2)
                                        ENDIF
                                ELSE
                                        dx = Joypad(i, 0)
                                        dy = Joypad(i, 1)
                                        dx = dx * dtime*1.2
                                        dy = dy * dtime*1.2

                                        ShiftPlayer(i, dx, dy)
                                        // no animation
                                        IF dx=0 AND dy=0 THEN thegame.plys[i].anitime = thistime

                                        IF trigga_down=FALSE AND Joypad(i, 2)
                                                trigga_down = TRUE
                                                DrillPlatformAt(i, thegame.plys[i].x, thegame.plys[i].y)
                                        ENDIF
                                        IF Joypad(i, 2) = FALSE THEN trigga_down=FALSE
                                ENDIF
                ENDSELECT
        NEXT
ENDFUNCTION


// -----------------------------------------
// LOADLEVEL
// -----------------------------------------
FUNCTION LoadLevel: nlevel
LOCAL i, npads
        INIOPEN "level"+nlevel+".ini"
        npads = INIGET$("global", "padcount")
        DIM thegame.pads[MAX(1, npads)]
        DIM thegame.plys[1]

        thegame.forcemap = INIGET$("global", "forcemap")

        FOR i=0 TO npads-1
                thegame.pads[i].state=0
                thegame.pads[i].minx=INIGET$("pads"+i, "minx")
                thegame.pads[i].miny=INIGET$("pads"+i, "miny")
                thegame.pads[i].maxx=INIGET$("pads"+i, "maxx")
                thegame.pads[i].maxy=INIGET$("pads"+i, "maxy")

                thegame.pads[i].x=thegame.pads[i].minx
                thegame.pads[i].y=thegame.pads[i].miny

                thegame.pads[i].extx=INIGET$("pads"+i, "extx")
                thegame.pads[i].exty=INIGET$("pads"+i, "exty")
        NEXT


        thegame.plys[0].x = thegame.pads[0].minx+.5
        thegame.plys[0].y = thegame.pads[0].miny+.5

        thegame.levelokani=0
        thegame.leveldone=0
        thegame.mapview=1
        thegame.timepanik = FALSE

        thegame.timeleft = (3-thegame.difficulty)*60

        CreateMap(100)
        BLACKSCREEN
ENDFUNCTION



// -----------------------------------------
// SAVELEVEL
// -----------------------------------------
FUNCTION SaveLevel: nlevel
LOCAL i, n
        KILLFILE "level"+nlevel+".ini"
        INIOPEN "level"+nlevel+".ini"

        n  = BOUNDS(thegame.pads[],0)
        INIPUT "global", "padcount", n
        INIPUT "global", "forcemap", thegame.forcemap
        FOR i=0 TO n-1
                INIPUT "pads"+i, "minx", thegame.pads[i].minx
                INIPUT "pads"+i, "miny", thegame.pads[i].miny
                INIPUT "pads"+i, "maxx", thegame.pads[i].maxx
                INIPUT "pads"+i, "maxy", thegame.pads[i].maxy
                INIPUT "pads"+i, "extx", thegame.pads[i].extx
                INIPUT "pads"+i, "exty", thegame.pads[i].exty
        NEXT
ENDFUNCTION



// -----------------------------------------
// EDITOR
// -----------------------------------------
FUNCTION Editor:
LOCAL i, nlevel
LOCAL x,y, sx,sy, ex,ey, fx,fy, downx, downy, bdown
LOCAL current, scale, plat AS PLATFORM, col, col2, in_dlg
LOCAL b1,b2, mx, my
        scale = INTEGER(screenx / 40)
        nlevel = 1 // 0=temp

        // #NEED: Bug in GLBasic - DDgui is one color else
        X_MAKE3D 1,100,45
        X_CAMERA 0,0,0, 0,0,-1
        X_SETTEXTURE -1, -1
        X_DRAWOBJ 300,0
        X_MAKE2D
        X_CULLMODE 0

        LOADFONT "smalfont.bmp", 0
        LoadLevel(nlevel)

        GETFONTSIZE fx,fy
        BLACKSCREEN

        FMod_Stop()

@refresh:
        DDgui_pushdialog(screenx*.65,0,screenx/4, screeny*.75)
        DDgui_set("SCALEABLE", TRUE)
        DDgui_set("MOVEABLE", TRUE)

        DDgui_button("bt_leveldn", "-", 0,0)
        DDgui_widget("st_level", "Level "+nlevel,0,0)
        DDgui_button("bt_levelup", "+", 0,0)
        DDgui_spacer(10000,0)


        DDgui_button("bt_add", "Add", 0,0)
        DDgui_button("bt_del", "Del", 0,0)
        DDgui_button("bt_start", "Start", 0,0)
        DDgui_button("bt_flip", "Flip", 0,0)
        DDgui_spacer(10000,0)
        DDgui_button("bt_test", "-TEST-", 0,0)
        DDgui_button("bt_save", "Save", 0,0)
        DDgui_spacer(10000,0)
        DDgui_checkbox("cb_forcemap", "Has Map", 0,0)
        DDgui_set("cb_forcemapCHECKED", thegame.forcemap)
        DDgui_spacer(10000,0)
        DDgui_widget("", "Move current",0,0)
        DDgui_spacer(10000,0)
        DDgui_spacer(fx*2,0)
        DDgui_button("bt_mvup", "^",0,0)
        DDgui_spacer(10000,0)
        DDgui_button("bt_mvleft", "<-",0,0)
        DDgui_button("bt_mvright", "->",0,0)
        DDgui_spacer(10000,0)
        DDgui_spacer(fx*2,0)
        DDgui_button("bt_mvdown", "v",0,0)

        DDgui_spacer(10000,0)
        DDgui_widget("", "Size current",0,0)
        DDgui_spacer(10000,0)
        DDgui_spacer(fx*2,0)
        DDgui_button("bt_szy-", "smaller",0,0)
        DDgui_spacer(10000,0)
        DDgui_button("bt_szx-", "-> <-",0,0)
        DDgui_button("bt_szx+", "<- ->",0,0)
        DDgui_spacer(10000,0)
        DDgui_spacer(fx*2.5,0)
        DDgui_button("bt_szy+", "bigger",0,0)

        DDgui_spacer(10000,0)
        DDgui_widget("", "Current move",0,0)
        DDgui_spacer(10000,0)
        DDgui_spacer(fx*2,0)
        DDgui_button("bt_mxy-", "^",0,0)
        DDgui_spacer(10000,0)
        DDgui_button("bt_mxx-", "<-",0,0)
        DDgui_button("bt_mxx+", "->",0,0)
        DDgui_spacer(10000,0)
        DDgui_spacer(fx*2,0)
        DDgui_button("bt_mxy+", "v",0,0)

current=2

        WHILE TRUE
                MOUSESTATE mx,my,b1,b2

                BOXCOLL in_dlg, mx,my,1,1, DDgui_get("XPOS"), DDgui_get("YPOS"), DDgui_get("WIDTH"), DDgui_get("HEIGHT")

                // Grid - dots
                FOR x=0.5 TO 29.5
                        FOR y=0.5 TO 9.5
                                SETPIXEL x*scale, y*scale, RGB(255,255,255)
                        NEXT
                NEXT

                // Pads
                FOR i=0 TO BOUNDS(thegame.pads[],0)-1
                        plat = thegame.pads[i]
                        x = INTEGER(plat.minx * scale)
                        y = INTEGER(plat.miny * scale)
                        sx= plat.extx
                        sy= plat.exty
                        IF in_dlg=FALSE AND b1
                                BOXCOLL col, mx,my,1,1, x,y,sx*scale,sy*scale
                                IF col THEN current = i
                        ENDIF

                        // exit
                        IF plat.minx<>plat.maxx OR plat.miny<>plat.maxy
                                col = RGB(0x80, 0x80, 0xff)
                                col2= RGB(0x00, 0x80, 0xff)
                        ELSE
                                col = RGB(0x80, 0xff, 0x80)
                                col2= RGB(0x00, 0xff, 0x80)
                        ENDIF
                        IF i=current THEN col = RGB(0xff, 0xff, 0x40)
                        FILLRECT x, y, x+INTEGER(sx*scale)-2, y+INTEGER(sy*scale)-2, col
                        FILLRECT x+1, y+1, x+INTEGER(sx*scale)-3, y+INTEGER(sy*scale)-3, col2
                        IF i=0
                                PRINT "UP", x+fx/4,y
                        ENDIF

                        // line - connections
                        IF plat.minx<>plat.maxx OR plat.miny<>plat.maxy
                                ex = INTEGER(plat.maxx * scale)
                                ey = INTEGER(plat.maxy * scale)
                                ALPHAMODE .2
                                FILLRECT ex, ey, ex+sx*scale-2, ey+sy*scale-2, RGB(0x00, 0x80, 0xff)
                                ALPHAMODE .1
                                FILLRECT x, y, ex+sx*scale-2, ey+sy*scale-2, RGB(0x80, 0x80, 0xff)
                                INC x, scale/2 + (sx-1)/2*scale
                                INC y, scale/2 + (sy-1)/2*scale
                                INC ex, scale/2+ (sx-1)/2*scale
                                INC ey, scale/2+ (sy-1)/2*scale
                                ALPHAMODE 0
                                DRAWLINE x, y, ex, ey, RGB(0xff, 0xff, 0x40)
                        ENDIF
                NEXT

                // Grid for next-screen
                FOR x=0.5 TO 2.5
                        SETPIXEL (x+ 6)*scale, 2.5*scale, RGB(255,96,96)
                        SETPIXEL (x+ 9)*scale, 6.5*scale, RGB(255,96,96)
                        SETPIXEL (x+15)*scale, 2.5*scale, RGB(255,96,96)
                        SETPIXEL (x+18)*scale, 6.5*scale, RGB(255,96,96)
                NEXT

                // Dialog messages
                DDgui_show(TRUE)

                thegame.forcemap = DDgui_get$("cb_forcemapCHECKED")
                IF DDgui_get("bt_leveldnCLICKED")
                        nlevel = MAX(1, nlevel-1)
                        LoadLevel(nlevel)
                        GOTO refresh
                ENDIF

                IF DDgui_get("bt_levelupCLICKED")
                        nlevel = MIN(99, nlevel+1)
                        LoadLevel(nlevel)
                        GOTO refresh
                ENDIF


                IF DDgui_get("bt_addCLICKED")
                        i = BOUNDS(thegame.pads[],0)
                        REDIM thegame.pads[i+1]
                        thegame.pads[i].extx=1
                        thegame.pads[i].exty=1
                        current = i
                ENDIF

                IF DDgui_get("bt_delCLICKED") OR KEY(211)
                        WHILE KEY(211); WEND
                        i = BOUNDS(thegame.pads[],0)
                        IF current>=0 AND current<i
                                thegame.pads[current] = thegame.pads[i-1]
                                REDIM thegame.pads[i-1]
                                current=i-2
                        ENDIF
                ENDIF
                IF DDgui_get("bt_startCLICKED")
                        i = current
                        IF i>0 AND i<BOUNDS(thegame.pads[],0)
                                plat = thegame.pads[current]
                                thegame.pads[current] = thegame.pads[0]
                                thegame.pads[0] = plat
                        ENDIF
                ENDIF
                IF DDgui_get("bt_flipCLICKED")
                        i = current
                        IF i>0 AND i<BOUNDS(thegame.pads[],0)
                                x = thegame.pads[i].minx; thegame.pads[i].minx=thegame.pads[i].maxx; thegame.pads[i].maxx=x
                                y = thegame.pads[i].miny; thegame.pads[i].miny=thegame.pads[i].maxy; thegame.pads[i].maxy=y
                        ENDIF
                ENDIF
                IF DDgui_get("bt_testCLICKED")
                        x = thegame.level
                        thegame.level = 0
                        SaveLevel(0); LoadLevel(0); MainGame();
                        LoadLevel(0)
                        thegame.level = x
                ENDIF
                IF DDgui_get("bt_saveCLICKED"); SaveLevel(nlevel); ENDIF

                // don't let start be scaled
                thegame.pads[0].extx=1
                thegame.pads[0].exty=1
                thegame.pads[0].maxx=thegame.pads[0].minx
                thegame.pads[0].maxy=thegame.pads[0].miny

                IF current>=0 AND current<BOUNDS(thegame.pads[],0)
                        // pos
                        IF DDgui_get("bt_mvleftCLICKED") OR KEY(203) ;WHILE KEY(203);WEND;DEC thegame.pads[current].minx,1; DEC thegame.pads[current].maxx,1;ENDIF
                        IF DDgui_get("bt_mvrightCLICKED")OR KEY(205) ;WHILE KEY(205);WEND;INC thegame.pads[current].minx,1; INC thegame.pads[current].maxx,1;ENDIF
                        IF DDgui_get("bt_mvupCLICKED" )  OR KEY(200) ;WHILE KEY(200);WEND;DEC thegame.pads[current].miny,1; DEC thegame.pads[current].maxy,1;ENDIF
                        IF DDgui_get("bt_mvdownCLICKED") OR KEY(208) ;WHILE KEY(208);WEND;INC thegame.pads[current].miny,1; INC thegame.pads[current].maxy,1;ENDIF

                        // ext
                        IF DDgui_get("bt_szx-CLICKED") THEN DEC thegame.pads[current].extx,1
                        IF DDgui_get("bt_szx+CLICKED") THEN INC thegame.pads[current].extx,1
                        IF DDgui_get("bt_szy-CLICKED") THEN DEC thegame.pads[current].exty,1
                        IF DDgui_get("bt_szy+CLICKED") THEN INC thegame.pads[current].exty,1
                        thegame.pads[current].extx = MAX(1, thegame.pads[current].extx)
                        thegame.pads[current].exty = MAX(1, thegame.pads[current].exty)

                        // max
                        IF DDgui_get("bt_mxx-CLICKED") THEN DEC thegame.pads[current].maxx,1
                        IF DDgui_get("bt_mxx+CLICKED") THEN INC thegame.pads[current].maxx,1
                        IF DDgui_get("bt_mxy-CLICKED") THEN DEC thegame.pads[current].maxy,1
                        IF DDgui_get("bt_mxy+CLICKED") THEN INC thegame.pads[current].maxy,1
                ENDIF

                PRINT BOUNDS(thegame.pads[],0), 100, 100
                SHOWSCREEN
                HIBERNATE
        WEND
ENDFUNCTION



// -----------------------------------------
// MUSIC - this keep tha sound alive
// -----------------------------------------
FUNCTION Music:
GLOBAL g_nSong, g_nSongPlay, fmod_init
LOCAL isong
        IF thegame.difficulty AND thegame.timeleft<60
                IF thegame.timepanik=FALSE
                        thegame.timepanik=TRUE
                        FMod_Load("music\\RB_8.IT")
                        FMod_Play()
                ENDIF
                RETURN
        ENDIF

        IF FMod_IsFinished()
                IF g_nSongPlay<=0
                        g_nSongPlay = 1
                        isong = g_nSong
                        WHILE isong = g_nSong
                                isong = RND(6)+1 // song 8 = timeout
                        WEND
                        g_nSong = isong
                        FMod_Load("music\\RB_"+isong+".IT")
                ELSE
                        DEC g_nSongPlay, 1
                ENDIF
                FMod_Play()
        ENDIF
ENDFUNCTION


// -----------------------------------------
// TitleScreen + Game Select
// -----------------------------------------
FUNCTION TitleScreen:
LOCAL start, pos, flicker, x, y
LOCAL flickerperc
LOCAL diff$[], tim$[], detl$[], sel$[], cursel
LOADFONT "bigfont.bmp", 0

        cursel = 3
DIM diff$[3]
        diff$[0] = "Dumb"
        diff$[1] = "Okay"
        diff$[2] = "Hard"
DIM tim$[3]
        tim$[0] = "None"
        tim$[1] = "Okay"
        tim$[2] = "Run!"
DIM detl$[2]
        detl$[0]= "C 64"
        detl$[1]= "Whee"

        flickerperc = 0.005

        thegame.timeleft=1000 // no panic song!

        FMod_Load("music\\RB_6.IT"); FMod_Play()

        start = GETTIMERALL()
        WHILE pos<1
                pos = (GETTIMERALL()-start)/2000
                flicker = ((1+SIN(pos*4000))/2*flickerperc+(1-flickerperc)) * (1-MAX(0, COS(pos*140)) )

                STRETCHSPRITE 200, 0,0,screenx, screeny
                X_MAKE3D 1,100,45
                X_CAMERA 0,0,0, 0,0,-1
                X_SPOT_LT -2, 1, 45,20,35, -.1,-.1,-1, 360
                X_CULLMODE 1
                X_MOVEMENT 0,0,-107 + flicker*100
                X_DRAWOBJ 300,0
                X_MAKE2D
                IF pos>=1 THEN USEASBMP
                SHOWSCREEN
        WEND

        y = -600
        WHILE TRUE
                IF y<-180 THEN y=y+GETTIMER()/10
                ALPHAMODE -.6
                FILLRECT 184, 394+y, screenx-184, 564+y, RGB(0,0,0)
                // selection
                FILLRECT 184, 414+y+cursel*30, screenx-184, 443+y+cursel*30, RGB(255,255,255)
                ALPHAMODE 0

                PRINT "[F1] Startlevel    - "+diff$[thegame.startlevel], 204,414+y
                PRINT "[F2] Timer         - "+ tim$[thegame.difficulty], 204,444+y
                PRINT "[F3] GFX - Details - "+detl$[thegame.details   ], 204,474+y
                PRINT "[F4] Rock the Bolt - Yay!", 204,504+y
                PRINT "[F5] Edit Levels   - Tick", 204,534+y
                SHOWSCREEN

                // up/dn
                pos = Joypad(0, 1)
                IF pos
                        cursel = MIN(4, MAX(0, cursel + pos) )
                        WHILE Joypad(0, 1)<>0; WEND
                ENDIF
                // select
                pos = Joypad(0, 2)
                IF pos
                        WHILE Joypad(0, 2)<>0; WEND
                ENDIF

                IF KEY(59) OR (pos AND cursel=0) THEN thegame.startlevel = MOD(1+thegame.startlevel, 3)
                IF KEY(60) OR (pos AND cursel=1) THEN thegame.difficulty = MOD(1+thegame.difficulty, 3)
                IF KEY(61) OR (pos AND cursel=2) THEN thegame.details    = 1-thegame.details

                WHILE KEY(59); WEND
                WHILE KEY(60); WEND
                WHILE KEY(61); WEND

                // F4
                IF KEY(62) OR (pos AND cursel=3)
                        WHILE KEY(62); WEND
                        RETURN
                ENDIF

                IF KEY(63) OR (pos AND cursel=4) THEN Editor()
        WEND
ENDFUNCTION
Und benötigt die Datei: Projects/Common/DDGui.gbas im Projekt (ausser Du schmeisst den Editor raus)
Nützt das was, oder soll ich alles komplett hochladen?

EDIT: Ich hwar bei dem Prjekt unter Zeitdruck. Der Code ist u.U. kein Spaß zum Lesen und teilweise suboptimal implementiert. Gerne mal reinschauen, aber nicht entmutigen, wenn man's nicht blickt. Die Kommentare sind (wenn überhaupt) sehr dürftig.

mannybass

  • Guest
Retro Remakes 2006
« Reply #8 on: 2006-Sep-11 »
Komplett hochladen wär klasse.