Cracktro

Find quick help here to get you started with Hollywood
Cool_amigaN
Posts: 12
Joined: Thu Jan 18, 2018 8:28 pm

Cracktro

Post by Cool_amigaN »

Hi there, recently purchased Hollywood and joined the party :) Have no actual experience with code so I am poking around a bit.

Anyhow, I want to produce a cracktro for our magazine. Started messing with the Lemming cracktro example, then added a menu. Till then things looked good (though i can't understand why the cracktro got visually paused every time the menu was accessed or moving around it's window happened), however lately I also incorporated code from the multi display and blanker examples and now the .hws looks somewhat broken:

1) Menu has stopped working (both visually and hotkeys don't work)
2) The resulted compile doesn't work properly on windows 7 32bit (blanker gets offset, display 2 doesn't get activated) - on MorphOS the display works though.

I have uploaded the project, here if anyone can have a look at it (I know that the code needs some clean up).

Some other notes, on the lemmings example can anyone verify whether the doublebuffering was active or not? Because I think near the end of the script the correct one should be doublebuffering(true).

What I need also is to have the blanker non clickable and a workable example with a .gif anim which will replace the .png of the 3D text example.
User avatar
jPV
Posts: 600
Joined: Sat Mar 26, 2016 10:44 am
Location: RNO
Contact:

Re: Cracktro

Post by jPV »

Cool_amigaN wrote:Till then things looked good (though i can't understand why the cracktro got visually paused every time the menu was accessed or moving around it's window happened)
Menu was accessed or the Credits window is opened? I don't see that just menus would pause it, but that window does, because it waits for user input and halts the script (no events are triggered while that). If you want to have intro running while it's open, you must take a different approach..

1) Menu has stopped working (both visually and hotkeys don't work)
You have to assign the menu for both displays, it only works from one now. Change the first display line to: @DISPLAY 1, {Desktop = True, Menu = 1}

You also need to add event handlers for both displays, for example like this:
SelectDisplay(2)
InstallEventHandler({OnMenuSelect = p_MenuFunc})
SelectDisplay(1)
InstallEventHandler({OnMenuSelect = p_MenuFunc})

Or if you just want it to one display, you probably had Menu assigned on other display and event handler on other. Make sure you have them on the same display.

2) The resulted compile doesn't work properly on windows 7 32bit (blanker gets offset, display 2 doesn't get activated) - on MorphOS the display works though.
Hmm.. don't have time to test or read the script better, but is the other display left under the other, and for some reason it isn't brought to front? Or something like that? Maybe if you would open the second display later and not as preprocessor (@-line)? With CreateDisplay/OpenDisplay.

BTW. all those preprocessor lines (starting with @) are executed before the script starts, so it doesn't affect if you try to put them later in the script. For readability it would be good to have them at the beginning.

Some other notes, on the lemmings example can anyone verify whether the doublebuffering was active or not? Because I think near the end of the script the correct one should be doublebuffering(true).
It should be doublebuffered in any case, giving "true" or not just affects if it's trying to be "hardware accelerated" or not. There seem to be flip commands which do the doublebuffering anyway, and I guess they'd fail if doublebuffering wouldn't be enabled.

What I need also is to have the blanker non clickable and a workable example with a .gif anim which will replace the .png of the 3D text example.
For anim gif I'd do something like this (if exact timing isn't that important):
Put these for example before the SetInterval line:
frame=0
frames=GetAttribute(#ANIM,1,#ATTRNUMFRAMES)

And then replace the DisplayBrush(8...) line with:
If frame<frames Then frame=frame+1 Else frame=1
DisplayAnimFrame(1,284,265,frame)

Check the Anim library for more information about anims.

Just some quick thoughts without properly thinking and testing, but maybe they get you forward :)
Cool_amigaN
Posts: 12
Joined: Thu Jan 18, 2018 8:28 pm

Re: Cracktro

Post by Cool_amigaN »

Hey man, thanks for the tips and quick assistance. CreateDisplay did the trick on MorphOS and also the menus are working again without having to assign MENU 1 to both Displays. Plus I added some zoom text.

1. However the problem persists in Windows 7 32bit (my test setup). Now the created (2nd) display, doesn't appear at all (music still run though) :( Is it a bug on Hollywood or an error on the code itself as shown here below?

2. Seems that Sprites and Anims (gifs) one way or another need to have closed double buffering, am I a correct? For the time being I added a static png to follow the pointer, though I would like to have the whole movement of my nick from the gif. Also, why the cool2.png doesn't show up outside the created display as well?

3. How can you pass an argument so that the created display will go fullscreen through its menu? Did a thorough check on the examples but couldn't spot a similar one.

4. Is it possible to make the display (blanker example) non clickable, so the created display doesn't get hide if by?

Hereare the sources, and here's the code itself:

Code: Select all

/*
** Important! Check if the used Hollywood version is at least
** version 6.0!
*/
@VERSION 6,0
@APPTITLE "RP18 CrakTr0"
@APPVERSION "$VER: RP18 CrakTr0 Alpha (0.2 - 16.01.18)"

@BRUSH 4, "font_big.png", {Transparency = #BLACK}
@BRUSH 5, "font_small.png", {Transparency = #BLACK}
@BRUSH 8, "dan.png"
@BRUSH 9, "cool2.png", {Transparency = #BLACK}
@MUSIC 1, "blaizer.mod"
@DISPLAY 1, {Desktop = True}
w = GetAttribute(#BGPIC, 1, #ATTRWIDTH)
h = GetAttribute(#BGPIC, 1, #ATTRHEIGHT)

BGPicToBrush(1, 2)

BrushToGray(2)

DisplayBrush(2, 0, 0)

For k = 10 To 100 Step 20
        CopyBrush(2, 3)
        TintBrush(3, #BLACK, k)
        DisplayBrush(3, 0, 0)
Next

mx = w - bw
my = h - bh

Function p_Zoomit(t$)

	Local sx, sy, trans = 1, 1, 0

	TextOut(#CENTER, #CENTER, t$, {AnchorX = 0.5, AnchorY = 0.5})

	StartTimer(1)
	
	For Local k = 1 To 20

		sx = sx + 0.2
		sy = sy + 0.2
		trans = trans + (255 / 20)
		
		SetLayerStyle(1, {ScaleX = sx, ScaleY = sy, Transparency = trans})

		WaitTimer(1, 1000\25)
	Next

EndFunction

EnableLayers

SetFont(#MONOSPACE, 40)
SetFontColor(#WHITE)

p_ZoomIt("CrackTr0")
RemoveLayer(1)
p_ZoomIt("is")
RemoveLayer(1)
p_ZoomIt("loading...")
RemoveLayer(1)

SetInterval(2, Function() DisplayBrush(9, MouseX(), MouseY()) EndFunction, 1 / 1)  ; 25fps

MovePointer(#CENTER, #CENTER)

CreateDisplay(2, {BORDERLESS=True, SCALEMODE=true, Menu = 1, Title="RP Issue 18 CrackTr0", ScreenTitle="RP #18 CrackTr0 by Cool_amigaN", SmoothScale=True, Sizeable = True, Width = 360, Height = 284})
width = GetAttribute(#DISPLAY, 0, #ATTRWIDTH)
height = GetAttribute(#DISPLAY, 0, #ATTRHEIGHT)
OpenDisplay(2)

@MENU 1, {
    {"About", {
    	{"Fullscreen", ID = "fullscreen", Hotkey = "NOT YET"},
        {"Credits", ID = "credits", Hotkey = "C"},
        {"Visit for more...", {
            {"Website...", ID = "www"},
            {"Forum...", ID = "forum"}}},
        {""},
        {"Quit", ID = "quit", Hotkey = "Q"}}},
    }

/*
** Event callback that handles menu selections
*/

Function p_MenuFunc(msg)
	
	Switch msg.action
	Case "OnMenuSelect":
		
		Local r$ = ""
		Local doreq = True
		
		Switch msg.item
		Case "fullscreen"
		Case "credits":
			SystemRequest("", "\27c\27bCredits\27n\nCode by Dan of Anarchy - Skidrow\nMusic by Blaizer of Horizon\nPorted by Mr. X of Barracuda\nModed & compiled by Cool_amigaN", "OK", #REQICON_INFORMATION)
			doreq = False
		Case "www" OpenURL ("https://goo.gl/P1eFXE")
		Case "forum" OpenURL ("http://amigacomet.boards.net/thread/112/retro-planet-18")
		Case "toggle":
			SystemRequest("", "Toggle state: " .. IsMenuItemSelected(1, msg.item), "OK", #REQICON_INFORMATION)
			doreq = False	
		Case "quit":
			End		
		Default:
			r$ = msg.item	
		EndSwitch

	EndSwitch

EndFunction		

; listen to "OnMenuSelect" event handler
InstallEventHandler({OnMenuSelect = p_MenuFunc})

/* prepare the background gradient and the color bars */
Function p_CreateBG()

        ; this is the gradient effect for the sine scroller
        CreateBrush(6, 360, 132)
        SelectBrush(6)
        SetFillStyle(#FILLGRADIENT, #LINEAR, #RED, #YELLOW)
        Box(0, 0, 360, 50)
        SetFillStyle(#FILLGRADIENT, #LINEAR, #YELLOW, #WHITE)
        Box(0, 50, 360, 16)
        SetFillStyle(#FILLGRADIENT, #LINEAR, #WHITE, #YELLOW)
        Box(0, 66, 360, 16)
        SetFillStyle(#FILLGRADIENT, #LINEAR, #YELLOW, #RED)
        Box(0, 82, 360, 50)
        EndSelect

        ; the color bars will cycle through these colors
        cols = {$F70000, $F72000, $F74100, $F76100, $F78200, $F7A200, $F7C300, $F7E300, $F7F300, $E7F300,
        $C6F300, $A5F300, $84F300, $63F300, $42F300, $21F300, $00F300, $00F321, $00F342, $00F363,
        $00F384, $00F3A5, $00F3A5, $00F3C6, $00F3E7, $00F3F7, $00E3F7, $00C3F7, $00A2F7, $0082F7,
        $0061F7, $0041F7, $0020F7, $0000F7, $2100F7, $4200F7, $6300F7, $8400F7, $A500F7, $C600F7,
        $E700F7, $F700F7, $F700E7, $F700C6}

        collength = ListItems(cols)
        start2 = collength - 1

EndFunction

/* prepare the text writer */
Function p_InitWriter()

        Local i, c
        Local textcols = {$840000, $844100, $848200, 0, $008200, 0, $004184, $000084, $420084, $840084}   ; base colors for gradient
        Local f$ = " !\"§$%&'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ"  ; format of font_small.iff
        Local x, y

        chars_s = {}

        ; create our lookup table chars_s{}
        For y = 0 To 1
                For x = 0 To 39
                        chars_s[Asc(MidStr(f$, y * 40 + x, 1))] = {x = x * 8, y = y * 8}
                Next
        Next

        Local t$ =
        "              * RETROPLANET *               " ..
        "              PROUDY PRESENTS               " ..
        "         ANOTHER LIGHTSPEED RELEASE         " ..
        "                                            " ..
        "               ISSUE NO. 18                 " ..
        "                                            " ..
        "  SINCE 2013, 52 FULL COLOR PAGES OF RETRO  " ..
        "    GREETINGS TO: DONY, NGANAG, VULTURE     " ..
        "      DINOHATZI, SPYROS, KEROPI, TSAK       " ..
        "     VISIT: RETROPLANET.GR / MOOBUNNY.GR    "

        writertextlen = StrLen(t$)
        writertext = StrToArray(t$)

        ; this brush contains the copper effect for the writer text
        CreateBrush(7, 360, 80)
        SelectBrush(7)

        For k = 0 To 79
                If k % 8 = 1
                        c = textcols[i]
                        i = i + 1
                EndIf

                Line(0, k, 359, k, c)

                If k % 8 < 4
                        c = c + $212021
                Else
                        c = c - $212021
                EndIf
        Next

        EndSelect

        ; clear its mask
        SelectMask(7)
        SetMaskMode(#MASKINVISIBLE)
        Cls
        EndSelect

        ; all future renderings are now in "visible" mode
        SetMaskMode(#MASKVISIBLE)

        cx = 0
        cy = 29

EndFunction

/* init the sine scroller */
Function p_InitScroll()

        Local f$ = " !\"§$%&'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ"   ; format of font_big.iff
        Local x, y

        chars = {}

        ; create lookup table chars{}
        For y = 0 To 2
                For x = 0 To 19
                        chars[Asc(MidStr(f$, y * 20 + x, 1))] = {x = x * 16, y = y * 16}
                Next
        Next

        Local t$ =     "                          - THE LEADING FORCE -                   IS BACK  WITH:" ..
        "                  * ISSUE 18 *                  " ..
        "READ ALL ABOUT:                   " ..
        "AMIGA32 SHOW REPORT BY: WALKERO           " ..
        "8/16BITS REVIEWS FOR AMSTRAD CPC, C=64, ZX SPECTRUM, ATARI ST  - " ..
        " HC508 VS. ACA500+ ALL BY: DONY                   " ..
        "BENCHMARKING VAMPIRE 600 V2 BY: VULTURE                  " ..
        "INCUBATION: TIME IS RUNNING OUT REVIEW BY: COOL AMIGAN                   " ..
        "FLIGHT OF THE AMAZON QUEEN REVIEW BY: PHANTOM                   " ..
        "WINGS OF DESTINY FROM JUDAS PRIEST BY: VULTURE                   " ..
        "AND MUCH - MUCH MORE...                   " ..
        "PLACE YOUR ORDER WHILE STOCKS LAST!                  " ..
        "SEE YOU AT AMICAMP 6, 27-28/01/18 AT FOUNDATION - BE THERE! "..
        "                                     ... SCROLL RESTARTS ..."

        scrolltextlen = StrLen(t$)
        scrolltext = StrToArray(t$)

EndFunction

/* create our sine lookup table */
Function p_MakeSine()

        Local i, s = 0, 2 * #PI / 500

        sine = {}
        sinelen = 500

        For Local k = 0 to sinelen - 1
                sine[k] = Sin(i) * 55 + 55
                i = i + s
        Next

EndFunction

/* prepare starfield */
Function p_InitStars()

    stars = {}

    For Local i = 0 To 199

            stars[i] = {
                x = Rnd(360),
                y = Rnd(238) + 24,
                speed = Rnd(4) + 1,
                color = (Rnd(11) + 4) * 0x111111}

    Next

EndFunction

/* this function is called 50 times a second */
Function p_MainLoop()

	DisableLineHook()
	
        Local charpos_tmp, scrollpos_tmp, sinepos_tmp = charpos, scrollpos, sinepos
        Local char = scrolltext[scrollpos_tmp]
        Local i, k

        ; advance to next positions
        charpos = charpos + 2

        If charpos >= 16
            charpos = 0
            scrollpos = scrollpos + 1
            If scrollpos >= scrolltextlen Then scrollpos = 0
        EndIf

        sinepos = sinepos + 4
        If sinepos >= sinelen Then sinepos = sinepos - sinelen

        ; flip the back buffer into view and make the front buffer the back buffer,
        ; so we can render the next frame!
        Flip

        ; now draw the next frame to the back buffer!
        Cls
        DisplayBrush(8, 284, 265)        ; display "DAN OF ANARCHY"

        ; draw starfield
        For i = 0 To 199

                If stars[i].x >= 360 Then stars[i].x = stars[i].x - 360

                Plot(stars[i].x, stars[i].y, stars[i].color)

                stars[i].x = stars[i].x + stars[i].speed
        Next

        ; display upper color bar
        i = start1

        For k = 0 To collength - 2
                Line(k * 8, 22, k * 8 + 7, 22, cols[i])
                i = i + 1
                If i = collength Then i = 0
        Next

        Line(k * 8, 22, 359, 22, cols[i])

        start1 = start1 + 1
        If start1 = collength Then start1 = 0

        ; display lower color bar (reverse direction!)
        i = start2

        For k = collength To 1 Step -1
                Line(k * 8 + 7, 262, k * 8, 262, cols[i])
                i = i - 1
                If i = -1 Then i = collength - 1
        Next

        Line(9, 262, 0, 262, cols[i])

        start2 = start2 - 1
        If start2 = -1 Then start2 = collength - 1

        ; now render the sine scroller intro the gradient's mask
        SelectMask(6)
        SetMaskMode(#MASKINVISIBLE)
        Cls
        SetMaskMode(#MASKVISIBLE)

        For Local x = 0 To 360 Step 16

            For Local k = 0 To 15

                    charpos_tmp = charpos_tmp + 1

                    if charpos_tmp >= 16
                        charpos_tmp = 0
                        scrollpos_tmp = scrollpos_tmp + 1
                        If scrollpos_tmp >= scrolltextlen Then scrollpos_tmp = 0
                        char = scrolltext[scrollpos_tmp]
                    EndIf

                    DisplayBrushPart(4, chars[char].x + charpos_tmp, chars[char].y, x + k, sine[sinepos_tmp], 1, 16)

                    sinepos_tmp = sinepos_tmp + 1
                    if sinepos_tmp >= sinelen Then sinepos_tmp = 0
            Next

        Next

        EndSelect

        DisplayBrush(6, 0, 132)    ; render the masked gradient to it

        ; writer not finished yet?
        If wc < writertextlen

                ; render its characters to our prepare copper brush's mask

                char = writertext[wc]

                If char <> ' ' And high = 1

                        SelectMask(7)
                        DisplayBrushPart(5, chars_s[char].x, chars_s[char].y, cx, cy - 29, 8, 8)
                        EndSelect

                EndIf

                DisplayBrush(7, 0, 29)

                ; highlight it first!
                If char <> ' ' And high = 0
                        DisplayBrushPart(5, chars_s[char].x, chars_s[char].y, cx, cy, 8, 8)
                EndIf

                ; advance to next character
                If high = 1
                        cx = cx + 8
                        wc = wc + 1

                        If cx = 352
                                cx = 0
                                cy = cy + 8
                        EndIf
                EndIf

                high = 1 - high

        Else

                ; simply display the brush now because the writer is done
                DisplayBrush(7, 0, 29)

        EndIf

	EnableLineHook()
	
EndFunction

p_CreateBG()
p_InitScroll()
p_InitWriter()
p_InitStars()
p_MakeSine()

EscapeQuit(True)

SetInterval(1, p_MainLoop, 500/60)   ; 60 fps

PlayMusic(1)

; begin double buffered output
BeginDoubleBuffer(True)

Repeat
        WaitEvent
Forever
User avatar
jPV
Posts: 600
Joined: Sat Mar 26, 2016 10:44 am
Location: RNO
Contact:

Re: Cracktro

Post by jPV »

Cool_amigaN wrote:1. However the problem persists in Windows 7 32bit (my test setup). Now the created (2nd) display, doesn't appear at all (music still run though) :( Is it a bug on Hollywood or an error on the code itself as shown here below?
Hmm.. yeah. I made a quick try on Win10, and I can see that there's the scroller window running when alt-tabbing, but can't bring it to front. Actually can't bring any other window to front either. It seems that the Desktop option makes the Hollywood window to stay front all the time?

Looks like a bug, Andreas?

If you run for example this:

Code: Select all

@DISPLAY 1, {Desktop = True}
Print("bla")
WaitLeftMouse()    
...you can't bring any other window to front while it's running.


But as a workaround, this does work and other windows can be brought to front:

Code: Select all

@DISPLAY 1, {Borderless=True, Hidden=True}
GrabDesktop(1)
BrushToBGPic(1,1)
DisplayBGPic(1)
OpenDisplay(1)
Print("bla")
WaitLeftMouse() 
2. Seems that Sprites and Anims (gifs) one way or another need to have closed double buffering, am I a correct? For the time being I added a static png to follow the pointer, though I would like to have the whole movement of my nick from the gif.
If you draw the anim frame by frame with DisplayAnimFrame, then it works with double buffering too. I had your anim running on your scroller display when I tried it, read my previous example again :)

Also, why the cool2.png doesn't show up outside the created display as well?
A display (window) is where you draw the graphics, you can't draw outside of it. You probably can change mouse pointer if you want to have it everywhere, but it probably have some restrictions (depending of the system?), didn't look the manual now :) Or you can open a bigger display to draw.. for example you could combine the displays 1 and 2, and have just one full screen display where to draw everything. Just draw the intro in the middle of it.. although it's harder to make it resizeable etc then. Or you should handle when you draw to display 1 and when to display 2... anyway, there's always one display where you draw at the time and that's it.

3. How can you pass an argument so that the created display will go fullscreen through its menu? Did a thorough check on the examples but couldn't spot a similar one.
Maybe something like this:

Code: Select all

		Case "fullscreen"
            If GetAttribute(#DISPLAY,2,#ATTRMODE)=#DISPMODE_WINDOWED
                ChangeDisplayMode(#DISPMODE_FULLSCREEN)
            Else
                ChangeDisplayMode(#DISPMODE_WINDOWED)
            EndIf 
4. Is it possible to make the display (blanker example) non clickable, so the created display doesn't get hide if by?
I don't think so... at least in easy way. Hollywood can't change the behaviour of window management of the host system that much... maybe it would be better to have just one display and forget the resizing of the intro if this is a too big problem.
Cool_amigaN
Posts: 12
Joined: Thu Jan 18, 2018 8:28 pm

Re: Cracktro

Post by Cool_amigaN »

Thanks for your replies man! As always much appreciated :)

Seems that after our combined bitcoin empire we will embark on demo coding taking down razor, silents and the likes :P

Anyhow:

Code: Select all

      Case "fullscreen"
            If GetAttribute(#DISPLAY,2,#ATTRMODE)=#DISPMODE_WINDOWED
                ChangeDisplayMode(#DISPMODE_FULLSCREEN)
            Else
                ChangeDisplayMode(#DISPMODE_WINDOWED)
            EndIf 
Above code works, however I 'd like to know how can you specify on the Menu hotkey the RAMIGA+ENTER.

I tried:

Code: Select all

@MENU 1, {
    {"About", {
    	{"Fullscreen", ID = "fullscreen", Hotkey = "ENTER"},
But it only displays on the actual menu the word "ENTER". If Hotkey = "F" (or any other letter) it gets displayed properly (i.e. "A+F")

Secondly, tried to merge the displays but the Blanker effect requires double buffering switched off, whereas I want to have the cracktro with double buffering and hardware accelarated (especially on MorphOS where the cpu raw power isn't that substantial).

Code: Select all

@DISPLAY 1, {Borderless=True, Hidden=True}
GrabDesktop(1)
BrushToBGPic(1,1)
DisplayBGPic(1)
OpenDisplay(1)
Print("bla")
WaitLeftMouse() 
Above code confirmed as working with dual displays.

How do you think it should be combined to have the grey/fade out effect of the blanker, which was the following:

Code: Select all

@DISPLAY 1, {Desktop = True}
w = GetAttribute(#BGPIC, 1, #ATTRWIDTH)
h = GetAttribute(#BGPIC, 1, #ATTRHEIGHT)

BGPicToBrush(1, 2)

BrushToGray(2)

DisplayBrush(2, 0, 0)

For k = 10 To 100 Step 20
        CopyBrush(2, 3)
        TintBrush(3, #BLACK, k)
        DisplayBrush(3, 0, 0)
Next

mx = w - bw
my = h - bh
Tried a couple of combinations but neither did the trick at all :(

Regarding Anim, below code did work:

Code: Select all

frame=0
frames=GetAttribute(#ANIM,1,#ATTRNUMFRAMES) 

If frame<frames Then frame=frame+1 Else frame=1
DisplayAnimFrame(1,284,265,frame) 
However, if we want to have the anim following the pointer with something similar like:

Code: Select all

DisplayAnimFrame(1, MouseX(), MouseY(), frame)
It won't work. I also tried to mess with the SetInterval Function stolen from the 3D text Hollywood example, but all I could display was a still frame of the actual gif.

Also, I tried to expand the actual cracktro display since it's way too small (say at least 800x600 resolution) but all I got was a black space and the cracktro remained small. I assume that this is because of the absolute values that draw the effects which the original coder (Mr. X) has placed on the script? Is it possible to overcome this problem somehow?

As a side note to anyone interested, I tried to alter the .ico of the compiled windows version through resource hacker and the resulted .exe stopped being functional with error code: [...] is no Hollywood applet!
SamuraiCrow
Posts: 475
Joined: Fri May 15, 2015 5:15 pm
Location: Waterville, Minnesota USA

Re: Cracktro

Post by SamuraiCrow »

re:Windows Icon
Did you try the @APPICON preprocessor function to set a PNG icon for each size?
I'm on registered MorphOS using FlowStudio.
SamuraiCrow
Posts: 475
Joined: Fri May 15, 2015 5:15 pm
Location: Waterville, Minnesota USA

Re: Cracktro

Post by SamuraiCrow »

re:Animated Pointer
If you combine the pointer image with the animation you want following it you can use the CreatePointer and SetPointer commands like the PointerDemo.hws example shows.
I'm on registered MorphOS using FlowStudio.
Cool_amigaN
Posts: 12
Joined: Thu Jan 18, 2018 8:28 pm

Re: Cracktro

Post by Cool_amigaN »

Yo, local amiga party went smooth and Hollywood cracktro was displayed in its prime :) Took a short break away from job and now we are back in business.

Just to point some notes:

1) Based on the ANIM manual my understanding was that it could't get displayed with double buffering enabled however, jPV's code did the trick for me:

Code: Select all

If frame<frames Then frame=frame+1 Else frame=1
DisplayAnimFrame(1, MouseX(), MouseY(), frame)
2) Setting antiblanker on Display 1 indeed disables the blanker however while resuming (ie closing the cracktro) MorphOS freezes and have to hard reset. Will check if it needs to be set on both Displays or on the 2nd one or it just crashes.

3) In order to keep focus on the cracktro itself I installed several event handlers that did the trick (and I am really proud of myself :D):

Code: Select all

InstallEventHandler ({OnMouseDown = ActivateDisplay(2),
   OnMouseUp = ActivateDisplay(2),
   OnRightMouseDown = ActivateDisplay(2),
   OnRightMouseUp = ActivateDisplay(2)})
Otherwise, the user could sellect the background display and the cracktro window was dissapearing.

There is a minimal blank when calling the above code (cracktro window flashes for a split second). Is it possible to eliminate this effect?

Also, I tried to reproduce the same usability with IF/THEN (ie, If SelectDisplay (1) Then ActivateDisplay (2)) but I failed (Hollywood complained either about Double Buffering that had to be switched off or for the layers to be switched off as well, depending where I was placing the code on the script). Is it possible to have it working with a simple IF/THEN statement?

4) When opening the cracktro's display:

Code: Select all

CreateDisplay(2, {BORDERLESS=True, SCALEMODE=true, Menu = 1, Title="RP Issue 18 CrackTr0", ScreenTitle="RP #18 CrackTr0 by Cool_amigaN", SmoothScale=True, Sizeable = True, Width = 360, Height = 284})
width = GetAttribute(#DISPLAY, 0, #ATTRWIDTH)
height = GetAttribute(#DISPLAY, 0, #ATTRHEIGHT)
OpenDisplay(2)
ActivateDisplay(2)
I placed the ActivateDisplay(2) in the hope that it will bring the window at front on my Windows configuration (win 7 32bit version) - like it does on MorphOS) but the problem remains since Display 1 & 2 are opened in different windows but only Display 1 is at front (alt tab previews the cracktro running at the background). So is this a bug or an error in the code?

5) Now, pay attention: I tested the cracktro on several machines around the party, Sam460 OS 4.1 FE (like also my MorphOS 3.9 - PMAC G4 1.6GHZ) runs smooth at 60 fps as I have ordered in the Hollywood script but the newly A1222 (Tabor) which was placed right next to me on the maxed out at 15 fps and wasn't smooth at all. The system had all the latest drivers/OS components installed. Don't know if Andreas should keep caution about the system's performance or the compiled OS4 versions should included special code for AEON's new system. Does Hollywood takes advantage of the FPU? Vampire V2 on A600 run at 7 fps btw.

@SamuraiCrow

No, I didn't set the app icon for every size available. It was the initial attempt, tomorow I will create the full icon size set :)
Cool_amigaN
Posts: 12
Joined: Thu Jan 18, 2018 8:28 pm

Re: Cracktro

Post by Cool_amigaN »

I 've made some progress on the cracktro but I need some help/clarifications for the final touches before releasing it:

1) Is it possible to crossfade between 2 music files? Instead of StopMusic / PlayMusic which cuts off music in a sudden manner?

2) Is is possible to move images on an inactive display that resides in the bakground?

3) Will this code link the font to the compiled versions?

Code: Select all

@FONT 1, "sys:fonts/_ttf/TERMINAT.TTF", 20, {Engine = #FONTENGINE_INBUILT}
If not, the TTF font, when installed by Font manager creates a .font and .otag file. How these files should be treated/linked?

4) I added a quit function. Although it works as supposed via RA+Q hotkey or choosing Quit from Menu, when pressing ESC it loops me back on line 384. Can't figure out why.

5) 360x284, from original cracktro code, is way too tiny for modern resolutions. Tried to manipulate the routines for 800x600 and managed to fill up correctly the star field but could't move rest of the graphics to appropriate positions. Can anybody help on this regard? Is there any other alternative rather than messing directly with the pixel positions one by one? Tried some scaling options but none did the trick.

6) My second biggest concern after point 5, is the Desktop Display 1 which doesn't work on Win as stated from post 3 already. This prohibits the craktro working on Windows. How can we re-create the tint/gray effect? I mean, this code:

Code: Select all

@DISPLAY 1, {Borderless=True, Hidden=True}
GrabDesktop(1)
BrushToBGPic(1,1)
DisplayBGPic(1)
OpenDisplay(1)
With this code:

Code: Select all

@DISPLAY 1, {Desktop = True}
w = GetAttribute(#BGPIC, 1, #ATTRWIDTH)
h = GetAttribute(#BGPIC, 1, #ATTRHEIGHT)

BGPicToBrush(1, 2)

BrushToGray(2)

DisplayBrush(2, 0, 0)

For k = 10 To 100 Step 20
        CopyBrush(2, 3)
        TintBrush(3, #BLACK, k)
        DisplayBrush(3, 0, 0)
Next

mx = w - bw
my = h - bh
Here below follows the code. Sources can be downloaded from here. Script includes combined code from several Hollywood examples such as: menu creation, object transition fx, blanker, Zoom Text, multi displays, cracktro and some more. I 'll comment most of the functions and release full sources. Do you think that the code could be cleaned up and/or re-structured in a better way?

Code: Select all

/*
** Important! Check if the used Hollywood version is at least
** version 6.0!
*/
@VERSION 6,0
@APPTITLE "RP18 CrakTr0"
@APPVERSION "$VER: RP18 CrakTr0 Alpha (0.6 - 27.01.18)"
@APPICON {DefaultIcon="64x64", Ic64x64 = "RP186464.png",Ic64x64s = "186464.png"}
@OPTIONS {RegisterApplication = True}
@BRUSH 4, "font_big.png", {Transparency = #BLACK}
@BRUSH 5, "font_small.png", {Transparency = #BLACK}
@BRUSH 8, "dan.png"
@BRUSH 9, "logo.png", {Transparency = #BLACK}
@BRUSH 10, "RP18cover.jpg"
@ANIM 1, "stefanim.gif", {LoadTransparency = True}
@FONT 1, "sys:fonts/_ttf/TERMINAT.TTF", 20, {Engine = #FONTENGINE_INBUILT}
@MUSIC 1, "blaizer.mod"
@MUSIC 2, "GameOver.mp3"
@DISPLAY 1, {Desktop = True, DisableBlanker = True}
w = GetAttribute(#BGPIC, 1, #ATTRWIDTH)
h = GetAttribute(#BGPIC, 1, #ATTRHEIGHT)

BGPicToBrush(1, 2)

BrushToGray(2)

DisplayBrush(2, 0, 0)

For k = 10 To 100 Step 20
        CopyBrush(2, 3)
        TintBrush(3, #BLACK, k)
        DisplayBrush(3, 0, 0)
Next

mx = w - bw
my = h - bh

Function p_Zoomit(t$)

	Local sx, sy, trans = 1, 1, 0

	TextOut(#CENTER, #CENTER, t$, {AnchorX = 0.5, AnchorY = 0.5})

	StartTimer(1)
	
	For Local k = 1 To 20

		sx = sx + 0.2
		sy = sy + 0.2
		trans = trans + (255 / 20)
		
		SetLayerStyle(1, {ScaleX = sx, ScaleY = sy, Transparency = trans})

		WaitTimer(1, 1000\35)
	Next

EndFunction

EnableLayers

;Some old code: SetFont(#MONOSPACE, 40)
UseFont(1)
SetFontColor(#WHITE)

p_ZoomIt("CrackTr0")
RemoveLayer(1)
p_ZoomIt("is")
RemoveLayer(1)
p_ZoomIt("loading...")
RemoveLayer(1)

;MoveBrush(9, #RIGHTOUT, #BOTTOM, #LEFTOUT, #BOTTOM, {TYPE = #SINE, Speed = #NORMALSPEED})

CreateDisplay(2, {BORDERLESS=True, SCALEMODE=true, Menu = 1, Title="RP Issue 18 CrackTr0", ScreenTitle="RP #18 CrackTr0 by Cool_amigaN", SmoothScale=True, Sizeable = True, Width = 360, Height = 284})
width = GetAttribute(#DISPLAY, 0, #ATTRWIDTH)
height = GetAttribute(#DISPLAY, 0, #ATTRHEIGHT)
OpenDisplay(2)
ActivateDisplay(2)
     
@MENU 1, {
    {"About", {
    	{"Fullscreen", ID = "fullscreen", Hotkey = "F"},
    	{"FPS counter", ID = "fps", Flags = #MENUITEM_TOGGLE, Hotkey = "P"},
        {""},
        {"Credits", ID = "credits", Hotkey = "C"},
        {"Visit for more...", {
            {"Website...", ID = "www"},
            {"Forum...", ID = "forum"}}},
        {""},
        {"Quit", ID = "quit", Hotkey = "Q"}}},
    }

/*
** Event callback that handles menu selections
*/

Function p_MenuFunc(msg)
	
	Switch msg.action
	Case "OnMenuSelect":
		
		Local r$ = ""
		Local doreq = True
		
		Switch msg.item
		Case "fullscreen"
			If GetAttribute(#DISPLAY,2,#ATTRMODE)=#DISPMODE_WINDOWED
				ChangeDisplayMode(#DISPMODE_FULLSCREEN)
		Else
				ChangeDisplayMode(#DISPMODE_WINDOWED)
		EndIf
		Case "credits":
			SystemRequest("", "\27c\27bCredits\27n\nCode by Dan of Anarchy - Skidrow\nMusic by Blaizer of Horizon\nPorted by Mr. X of Barracuda\nAdditional code by jPV\nModed & compiled by Cool_amigaN", "OK", #REQICON_INFORMATION)
			doreq = False
		Case "www" OpenURL ("https://goo.gl/P1eFXE")
		Case "forum" OpenURL ("http://amigacomet.boards.net/thread/112/retro-planet-18")
		Case "toggle":
			SystemRequest("", "Toggle state: " .. IsMenuItemSelected(1, msg.item), "OK", #REQICON_INFORMATION)
			doreq = False	
		Case "quit": p_PrepareExit()
			End		
		Default:
			r$ = msg.item	
		EndSwitch

	EndSwitch

EndFunction		

; listen to "OnMenuSelect" event handler
InstallEventHandler({OnMenuSelect = p_MenuFunc})

/* prepare the background gradient and the color bars */
Function p_CreateBG()

        ; this is the gradient effect for the sine scroller
        CreateBrush(6, 360, 132)
        SelectBrush(6)
        SetFillStyle(#FILLGRADIENT, #LINEAR, #RED, #YELLOW)
        Box(0, 0, 360, 50)
        SetFillStyle(#FILLGRADIENT, #LINEAR, #YELLOW, #WHITE)
        Box(0, 50, 360, 16)
        SetFillStyle(#FILLGRADIENT, #LINEAR, #WHITE, #YELLOW)
        Box(0, 66, 360, 16)
        SetFillStyle(#FILLGRADIENT, #LINEAR, #YELLOW, #RED)
        Box(0, 82, 360, 50)
        EndSelect

        ; the color bars will cycle through these colors
        cols = {$F70000, $F72000, $F74100, $F76100, $F78200, $F7A200, $F7C300, $F7E300, $F7F300, $E7F300,
        $C6F300, $A5F300, $84F300, $63F300, $42F300, $21F300, $00F300, $00F321, $00F342, $00F363,
        $00F384, $00F3A5, $00F3A5, $00F3C6, $00F3E7, $00F3F7, $00E3F7, $00C3F7, $00A2F7, $0082F7,
        $0061F7, $0041F7, $0020F7, $0000F7, $2100F7, $4200F7, $6300F7, $8400F7, $A500F7, $C600F7,
        $E700F7, $F700F7, $F700E7, $F700C6}

        collength = ListItems(cols)
        start2 = collength - 1
    
EndFunction

/* prepare the text writer */
Function p_InitWriter()

        Local i, c
        Local textcols = {$840000, $844100, $848200, 0, $008200, 0, $004184, $000084, $420084, $840084}   ; base colors for gradient
        Local f$ = " !\"§$%&'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ"  ; format of font_small.iff
        Local x, y

        chars_s = {}

        ; create our lookup table chars_s{}
        For y = 0 To 1
                For x = 0 To 39
                        chars_s[Asc(MidStr(f$, y * 40 + x, 1))] = {x = x * 8, y = y * 8}
                Next
        Next

        wc=0  ; Reset writer position for new init

        ; Let's have several texts. You can have one t$[0], or many 1, 2, 3...
        Local t$={}
        t$[0] =
        "              * RETROPLANET *               " ..
        "              PROUDLY PRESENTS              " ..
        "         ANOTHER LIGHTSPEED RELEASE         " ..
        "                                            " ..
        "               ISSUE NO. 18                 " ..
        "                                            " ..
        "  SINCE 2013, 52 FULL COLOR PAGES OF RETRO  " ..
        "     GREETINGS TO: DONY, NGANAG, VULTURE    " ..
        "       DINOHATZI, SPYROS, KEROPI, TSAK      " ..
        "     VISIT: RETROPLANET.GR / MOOBUNNY.GR    "

        t$[1] =
        "              * RETROPLANET *               " ..
        "              PROUDLY PRESENTS              " ..
        "         ANOTHER LIGHTSPEED RELEASE         " ..
        "                                            " ..
        "               ISSUE NO. 18                 " ..
        "                                            " ..
        "  SINCE 2013, 52 FULL COLOR PAGES OF RETRO  " ..
        "     GREETINGS TO: JPV, FIK, TINA, MIKE     " ..
        "        WALKERO, VAGGI6128, MASTERGR        " ..
        "     VISIT: RETROPLANET.GR / MOOBUNNY.GR    "

        writertextlen = StrLen(t$[wt])
        writertext = StrToArray(t$[wt])

        If HaveItem(t$,wt+1) Then wt=wt+1 Else wt=0 ; Switch to the next text


        ; this brush contains the copper effect for the writer text
        CreateBrush(7, 360, 80)
        SelectBrush(7)

        For k = 0 To 79
                If k % 8 = 1
                        c = textcols[i]
                        i = i + 1
                EndIf

                Line(0, k, 359, k, c)

                If k % 8 < 4
                        c = c + $212021
                Else
                        c = c - $212021
                EndIf
        Next

        EndSelect

        ; clear its mask
        SelectMask(7)
        SetMaskMode(#MASKINVISIBLE)
        Cls
        EndSelect

        ; all future renderings are now in "visible" mode
        SetMaskMode(#MASKVISIBLE)

        cx = 0
        cy = 29

EndFunction

/* init the sine scroller */
Function p_InitScroll()

        Local f$ = " !\"§$%&'()*+,-./0123456789:;<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ"   ; format of font_big.iff
        Local x, y

        chars = {}

        ; create lookup table chars{}
        For y = 0 To 2
                For x = 0 To 19
                        chars[Asc(MidStr(f$, y * 20 + x, 1))] = {x = x * 16, y = y * 16}
                Next
        Next

        Local t$ =     "                          - THE LEADING FORCE -                   IS BACK  WITH:" ..
        "                  * ISSUE 18 *                  " ..
        "READ ALL ABOUT:                   " ..
        "AMIGA32 SHOW REPORT BY: WALKERO           " ..
        "8/16BITS REVIEWS FOR AMSTRAD CPC, C=64, ZX SPECTRUM, ATARI ST  - " ..
        " HC508 VS. ACA500+ ALL BY: DONY                   " ..
        "BENCHMARKING VAMPIRE 600 V2 BY: VULTURE                  " ..
        "INCUBATION: TIME IS RUNNING OUT REVIEW BY: COOL AMIGAN                   " ..
        "FLIGHT OF THE AMAZON QUEEN REVIEW BY: PHANTOM                   " ..
        "WINGS OF DESTINY FROM JUDAS PRIEST BY: VULTURE                   " ..
        "AND MUCH - MUCH MORE...                   " ..
        "PLACE YOUR ORDER WHILE STOCKS LAST!                  " ..
        "SEE YOU AT AMICAMP 6, 27-28/01/18 AT FOUNDATION - BE THERE! "..
        "                                     ... SCROLL RESTARTS ..."

        scrolltextlen = StrLen(t$)
        scrolltext = StrToArray(t$)

EndFunction

/* create our sine lookup table */
Function p_MakeSine()

        Local i, s = 0, 2 * #PI / 500

        sine = {}
        sinelen = 500

        For Local k = 0 to sinelen - 1
                sine[k] = Sin(i) * 55 + 55
                i = i + s
        Next

EndFunction

/* prepare starfield */
Function p_InitStars()

    stars = {}

    For Local i = 0 To 199

            stars[i] = {
                x = Rnd(360),
                y = Rnd(238) + 24,
                speed = Rnd(4) + 1,
                color = (Rnd(11) + 4) * 0x111111}

    Next
    
EndFunction

/* this function is called 50 times a second */
Function p_MainLoop()

	DisableLineHook()
	
        Local charpos_tmp, scrollpos_tmp, sinepos_tmp = charpos, scrollpos, sinepos
        Local char = scrolltext[scrollpos_tmp]
        Local i, k

        ; advance to next positions
        charpos = charpos + 2

        If charpos >= 16
            charpos = 0
            scrollpos = scrollpos + 1
            If scrollpos >= scrolltextlen Then scrollpos = 0
        EndIf

        sinepos = sinepos + 4
        If sinepos >= sinelen Then sinepos = sinepos - sinelen

        ; flip the back buffer into view and make the front buffer the back buffer,
        ; so we can render the next frame!
        Flip

        ; now draw the next frame to the back buffer!
        Cls
        DisplayBrush(8, 284, 265)        ; display "DAN OF ANARCHY"

If frame<frames Then frame=frame+1 Else frame=1
DisplayAnimFrame(1, MouseX(), MouseY(), frame)

        ; draw starfield
        For i = 0 To 199

                If stars[i].x >= 360 Then stars[i].x = stars[i].x - 360

                Plot(stars[i].x, stars[i].y, stars[i].color)

                stars[i].x = stars[i].x + stars[i].speed
        Next

        ; display upper color bar
        i = start1

        For k = 0 To collength - 2
                Line(k * 8, 22, k * 8 + 7, 22, cols[i])
                i = i + 1
                If i = collength Then i = 0
        Next

        Line(k * 8, 22, 359, 22, cols[i])

        start1 = start1 + 1
        If start1 = collength Then start1 = 0

        ; display lower color bar (reverse direction!)
        i = start2

        For k = collength To 1 Step -1
                Line(k * 8 + 7, 262, k * 8, 262, cols[i])
                i = i - 1
                If i = -1 Then i = collength - 1
        Next

        Line(9, 262, 0, 262, cols[i])

        start2 = start2 - 1
        If start2 = -1 Then start2 = collength - 1

        ; now render the sine scroller intro the gradient's mask
        SelectMask(6)
        SetMaskMode(#MASKINVISIBLE)
        Cls
        SetMaskMode(#MASKVISIBLE)

        For Local x = 0 To 360 Step 16

            For Local k = 0 To 15

                    charpos_tmp = charpos_tmp + 1

                    if charpos_tmp >= 16
                        charpos_tmp = 0
                        scrollpos_tmp = scrollpos_tmp + 1
                        If scrollpos_tmp >= scrolltextlen Then scrollpos_tmp = 0
                        char = scrolltext[scrollpos_tmp]
                    EndIf

                    DisplayBrushPart(4, chars[char].x + charpos_tmp, chars[char].y, x + k, sine[sinepos_tmp], 1, 16)

                    sinepos_tmp = sinepos_tmp + 1
                    if sinepos_tmp >= sinelen Then sinepos_tmp = 0
            Next

        Next

        EndSelect

        DisplayBrush(6, 0, 132)    ; render the masked gradient to it

        ; writer not finished yet?
        If wc < writertextlen

                ; render its characters to our prepare copper brush's mask

                char = writertext[wc]

                If char <> ' ' And high = 1

                        SelectMask(7)
                        DisplayBrushPart(5, chars_s[char].x, chars_s[char].y, cx, cy - 29, 8, 8)
                        EndSelect

                EndIf

                DisplayBrush(7, 0, 29)

                ; highlight it first!
                If char <> ' ' And high = 0
                        DisplayBrushPart(5, chars_s[char].x, chars_s[char].y, cx, cy, 8, 8)
                EndIf

                ; advance to next character
                If high = 1
                        cx = cx + 8
                        wc = wc + 1

                        If cx = 352
                                cx = 0
                                cy = cy + 8
                        EndIf
                EndIf

                high = 1 - high

        Else

                ; simply display the brush now because the writer is done
                DisplayBrush(7, 0, 29)

        EndIf

	EnableLineHook()

    If fps_counter=60
        fps_result=Round(60000/GetTimer(2))
        fps_counter=1
        StartTimer(2)
    Else
        fps_counter=fps_counter+1
    EndIf
    If IsMenuItemSelected(2, "fps") Then TextOut(#RIGHT,#TOP,"fps: "..fps_result)

InstallEventHandler ({OnMouseDown = ActivateDisplay(2),

   OnMouseUp = ActivateDisplay(2),
   OnRightMouseDown = ActivateDisplay(2),
   OnRightMouseUp = ActivateDisplay(2),
   CloseWindow = p_PrepareExit,
   OnKeyDown = p_CheckKey})

EndFunction

Function p_PrepareExit()

If exit = True Then Return
SelectDisplay(1)
FreeDisplay(2)
StopMusic (1)
PlayMusic (2)
EnableLayers
DisplayBrushFX(10, #CENTER, #CENTER, {Type = #CROSSFADE, Speed = 20})
Wait(100)
UndoFX(#BRUSH, 10,#PIXELZOOM1, #NORMALSPEED)
Wait(50)
DisplayBrushFX(9, #CENTER, #CENTER, {Type = #CROSSFADE, Speed = 20})
Wait(50)
UndoFX(#BRUSH, 9,#WATER1, #NORMALSPEED)

EndFunction

/* check if ESC was pressed */
Function p_CheckKey(msg)

	If msg.key = "ESC" Then p_PrepareExit()

EndFunction

p_CreateBG()
p_InitScroll()
p_InitWriter()
p_InitStars()
p_MakeSine()

frame=0
frames=GetAttribute(#ANIM,1,#ATTRNUMFRAMES) 

SetInterval(1, p_MainLoop, 500/60)   ; 60 fps     
SetInterval(3, p_InitWriter, 30000) ; init writer every 30 seconds

StartTimer(2) ; timer for fps counting
fps_counter=1
fps_result=60
UseFont (1)
SetFontColor(ARGB(128, #GRAY))
;SetFont(#BITMAP_DEFAULT,8)

PlayMusic(1)

; begin double buffered output
BeginDoubleBuffer(True)

Repeat
        WaitEvent
Forever
Cool_amigaN
Posts: 12
Joined: Thu Jan 18, 2018 8:28 pm

Re: Cracktro

Post by Cool_amigaN »

After today's update (7.1), Display 2 (the actual cracktro) dissapeared even on MorphOS. Or to place it differently, Display 1 remains always on top. Can someone explain how the Always on Top feature works? Checked the documentation but could find any reference to it.
Post Reply