Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - gumby

Pages: 1 2 [3] 4 5 ... 9
31
SCI Development Tools / Ototo - Creating MIDI music
« on: February 22, 2014, 09:29:01 AM »
Found this very interesting over at Kickstarter:

https://www.kickstarter.com/projects/905018498/ototo-make-music-from-anything

From what I can tell, this seems like this would be a great way to create original MIDI music for our games, without having to be classically trained.  I've seen similar devices before, but the variety of input sensors really grabbed me.

The project is already fully funded, and delivery is scheduled for this June.  I'm thinking about funding it; at a minimum it would be fun to with my kids to tinker with.



32
Here's a tip to save a lot of space in your scripts if you use a lot of #titles in your Print() statements.  Create a procedure like this in your Main.sc:

Code: [Select]
(procedure (PrintWithTitle textRes textResIndex titleTextRes titleTextResIndex params)
   Print(textRes textResIndex #title Format("%s" titleTextRes titleTextResIndex) rest params)
)

Then in your scripts, just use the new PrintWithTitle function like this:
Code: [Select]
  PrintWithTitle(0 20 999 3)   // 999 is a text resource where your #titles are held
  
  // you can also use additional Print params and they will be passed through:
  PrintWithTitle(0 20 999 3 #width 200 #at 25 80)

This way you can pull all the actual text for your titles out of your room scripts, saving heap space.

This technique should work for any #attribute (#text, #button, etc) where you want to move the literal text out of the script & into a text resource.

EDIT:  Stop.  Don't do it in the above way.  It'll work, but lets address the root cause of the issue & fix the Print() routine in the template game:

Another edit:  This doesn't work properly, it seemed to in my initial testing.  I'm going to have to do some more debugging to figure out what is going on

In controls.sc, in the Print() procedure change the '(case #button' section:
Code: [Select]
(case #button
    = hButtons[buttonCnt] (DButton:new())
   
(if(>= Abs(params[+ paramCnt 1]) 0 and <= Abs(params[+ paramCnt 1]) 999)
(send hButtons[buttonCnt]:
text(Format("%s" params[+ paramCnt 1] params[+ paramCnt 2]))
value(params[+ paramCnt 3])
setSize()
    )
= paramCnt + paramCnt 3
)(else
(send hButtons[buttonCnt]:
text(params[++paramCnt])
value(params[++paramCnt])
setSize()
    )
)    
    = btnsWidth (+ btnsWidth (+ (send hButtons[buttonCnt]:nsRight) 4))
    ++buttonCnt
)

And the '(case #title' section:
Code: [Select]
(case #title
++paramCnt

(if(>= Abs(params[paramCnt]) 0 and <= Abs(params[paramCnt]) 999)
(send hDialog:text(Format("%s" params[paramCnt] params[+ paramCnt 1])))
++paramCnt
)(else
(send hDialog:text(params[paramCnt]))
      )
)

Now, you can use either technique - specify a static string or a text resource like this:
Code: [Select]
   Print("Hello there" #title 999 1)    //  999 is the text resource holding our title text
   Print("Hello there" #title "Greetings")   // the original way of specifying a title still works too

Same with buttons:
Code: [Select]
   Print("Make a selection" #button 888 2)   // 888 is the text resource holding our button text
   Print("Make a selection" #button "OK")    // the original way of specifying text for buttons still works

Of course, if you are this heap-bound, you'd have the actual text of your Print statement to be in a text resource too, so a more realistic example would be something like this:
Code: [Select]
  Print(0 15 #title 999 1)
  Print(0 22 #button 888 2)

33
SCI Community How To's & Tutorials / PIC drawing tips
« on: September 07, 2013, 09:46:40 PM »
Starting this thread to help document tips to help developers draw top-notch picture resources.  

While attempting to draw tree foliage, I was tempted to simply use a combination of fill areas consisting of lime, green & a green/black dither.  This did a pretty good job, but it lacked a level of authenticity, it just seemed too regular.  In Companion there is a option in the 'pen style' to select a random pattern, essentially a 'spray paint' tool.  Selecting a random pattern with a large pen size & applying it judiciously over the filled areas generated a very pleasing effect.

Also works great for creating 'bunches' of flowers on the ground or creating grassy areas.

34
Community Competitions / KQ2 SCI Remake - Mini competition
« on: August 17, 2013, 04:24:44 PM »
I'd like to propose a new mini-comp with the purpose of collaborating on MusicallyInspired's KQ2 remake.  Easy, short (i.e. completeable) and very accessible for people to contribute.

So here's my idea:  Let's hold a mini-comp for completing room pics (visual screens only, no priority or control screens).  Each competitor will choose a different room screen to complete, and all competition entries will be used in the game, everyone wins!

We'll vote on which screens deserve 1st, 2nd or 3rd place - same as a normal comp.  Again, I wish to emphasize that every submission will be used in the game providing it meets the requirements (see below).  After the competition is complete, I'll update the game with the new room screens & I'll request to have the KQ2 on the Design Desktop (http://sciprogramming.com/desktop.php) to be updated so we can all see the results in-game!

The only requirement is to stay true to the original project, which was to re-create KQ2 using the same style as the KQ1 SCI remake created by Sierra.  Additionally, please read MusicallyInspired's development thread for this project (http://sciprogramming.com/community/index.php/topic,28.0.html) to get some insight as to how he envisioned this game turning out.

If you are interested in competing, just indicate which currently unfinished room you'd like work on & I'll extract the room resource from the game & provide it as a starting point.  I'd like to hold off until we have several committed competitors before actually kicking this off; maybe beginning Sept 1st, with a deadline for submissions by Sept 30th.

Please post here if you are interested in participating.

35
SCI Syntax Help / Move actor off-screen?
« on: August 07, 2013, 06:57:07 PM »
I'm trying to move an actor offscreen: just have the actor move 'down' the Y axis (y = 1000).

Code: [Select]
   (myActor:setMotion(MoveTo 90 1000))

...but when the bottom of the view hits the edge of the screen, the view stops.  Is there some property that I missed specifying for the actor or something?

36
SCI Syntax Help / Cursor questions (move & restrict)
« on: August 01, 2013, 07:39:41 PM »
First Question:
So with this call I can move the cursor to whatever coordinates I wish:

Code: [Select]
/* sets the cursor to CURSOR.997, makes it visible, and positions it at 160,100 */
SetCursor(997 TRUE 160 100)

...which works just fine.  But as soon as I move the cursor it jumps right back to where it previously was.  Anyone know how to make any further movement of the mouse obey the new cursor location?

EDIT:  Never mind, this was the result of using DosBox with 'autolock = false'.  Setting this to true fixed the issue.

Second question:
Anyone know how to restrict the operable space of the cursor?  I'd like to try to limit the cursor to only a region of the screen (specifically the bottom third).

37
SCI Community How To's & Tutorials / SCI Logging
« on: March 27, 2013, 08:46:08 PM »
I'm pleased to announce that the first version of SCI Logging has been hacked together & uploaded to the fan games page.

It essentially logs all the necessary events (all user interaction) that is required for a 'automated replay' of a game.  Useful for testing & troubleshooting and should hopefully work for an automated walkthrough of a game.  Ultimately, I'd like to create automated testing functionality where a recorded log file could be coupled with a file containing expected responses from the game.

Unfortunately I had to make extensive changes to the template game to make this work, too many to list here but here's an overview.  I created a new script (LogEvent.sc) which is responsible for the heavy lifting, reading and writing events to/from a log file.   For logging events, the calls are pretty much all wired into the User.sc and Controls.sc script.  For replaying logs, the replay command is called in the doit() method in the Main.sc.  Logging is enable/disabled in the init() method of the Main.sc script.  Please see the commented/uncommented sections, you'll be able to spot them pretty easily.

Here's the included log file in the game (poorly formatted - it's a fixed width of 115 characters or so):

Ticks: 00000051 Event: gameLClick X: 201 Y: 083 Key:       Msg:                                                  
Ticks: 00000054 Event: openPrint  X:     Y:     Key:       Msg: Initial Print                                    
Ticks: 00000202 Event: closePrint X:     Y:     Key:       Msg:                                                  
Ticks: 00000202 Event: openPrint  X:     Y:     Key:       Msg: Print #2                                          
Ticks: 00000349 Event: closePrint X:     Y:     Key:       Msg:                                                  
Ticks: 00000409 Event: keyMove    X:     Y:     Key: $4d00 Msg:                                                  
Ticks: 00000529 Event: parseOpen  X:     Y:     Key:       Msg: Enter Input:                                      
Ticks: 00000607 Event: parseClose X:     Y:     Key:       Msg: look                                              
Ticks: 00000608 Event: openPrint  X:     Y:     Key:       Msg: I see nothing                                    
Ticks: 00000882 Event: closePrint X:     Y:     Key:       Msg:                                                  
Ticks: 00000990 Event: keyMove    X:     Y:     Key: $4800 Msg:                                                  
Ticks: 00001242 Event: keyMove    X:     Y:     Key: $4800 Msg:                                                  
Ticks: 00001260 Event: leftClick  X: 160 Y: 100 Key:       Msg:  

Initial tests are very promising.  The only thing of concern is to make sure that your game runs quickly enough to log & replay the events at the correct tick count.  If your game is laggy (like 120 Below Zero), you'll need to change your DosBox speed settings to address this.  Tick counts are the Achilles Heel of this entire project.  Right now it does not perform a 'perfect replay', but it is quite close - within one or two ticks.

I'm pretty happy with the result, though I'm sure it needs additional testing & feedback.  I learned a lot about event handling, especially with regard to the print and parser events.

38
SCI Syntax Help / Dismiss Print dialog
« on: March 15, 2013, 10:04:14 PM »
Does anyone know how to programatically close/dismiss a Print dialog window?  I think I've got it tracked down to the Dialog class doit() method in Controls.sc:

Code: [Select]
= isClaimed FALSE
(while((not isClaimed))
    (self:eachElementDo(#cycle))
    = hEvent (Event:new())
    GlobalToLocal(hEvent)
    = isClaimed (self:handleEvent(hEvent))
    (send hEvent:dispose())
    (self:check)
    (if( (== isClaimed -1) or (not busy) )
        = isClaimed FALSE
        EditControl(theItem 0)
        break
    )
    Wait(1)
)

If I'm reading this correctly, this code just loops, creating new events & checking to see if they are handled in the handleEvent() method by mouse click or specific keys before it bails out and closes the print window.

I know that I could have the window close after a certain amount of time elapses.  I did try to just fake a user input with a keystroke or mouse event, but it isn't consumed (I issued these events from within the main script).  Probably because the doit() in the print is issuing it's own event, waiting for it to be claimed and ignoring all other events.

Oh, by the way, I did try this in my room script:

Code: [Select]
    (method (doit)
(super:doit())
        DisposePrintDlg()
    )

Which conceptually seems like it should work, but it doesn't - probably because we are stuck in the while loop within the controls script.

39
SCI Syntax Help / Simulate user input
« on: March 10, 2013, 12:23:20 PM »
I'm attempting to create events programatically (keypresses & mouse clicks) but not having any success.  

My thought is that this code should create a new mouse event where location (30,30) is left clicked which should move the ego to that location:
Code: [Select]
    (if(Said('look'))
            (= hEvent Event:new())

            (send hEvent:
                 type(evMOUSEBUTTON)
                 x(30)
                 y(30)
                 modifiers(512)    // 512 left click, 515 right click
                 claimed(FALSE)
            )
            
            (super:handleEvent(hEvent))
     )
But it's not working, nothing seems to happen.  I've got it placed in a template game in the Rm001 script.

Here's a simpler event that should fire a keyboard event (ALT-M) and trigger the easy-alt debugging that displays the available memory, but doesn't work either:
Code: [Select]
           (send hEvent:
                 type(evKEYBOARD)
                 message($3200)
                 claimed(FALSE)
            )

Is this even possible to do?  I suspect that I'm creating the event properly, but maybe the handleEvent call is incorrect?

40
SCI Community How To's & Tutorials / Dispose all scripts
« on: January 25, 2013, 10:27:25 PM »
Okay, not all the scripts but as many as possible.  I had to exclude a couple to keep the game running correctly.

Anyway, here's a really small script that will do the task.  As far as I know, this can be called safely at any time within a room script.  I use it in Zork when I've loaded up a ton of scripts and have no idea what to unload and I'm out of heap space.

It won't unload Main.sc, Controls.sc, itself, and the current room script and any script number above 988.

Code: [Select]
/******************************************************************************
 DisposeScripts.sc
 Unloads all scripts (with exceptions)
 
 ******************************************************************************/
(include "sci.sh")
(include "game.sh")
/******************************************************************************/
(script DISPOSESCRIPTS_SCRIPT)

(use "main")
/******************************************************************************/
(procedure public (DisposeScripts)
  (var i)

  (for (= i 1) (< i 989) (++i)   // start at 1, excludes Main.sc
    (if (<> i gRoomNumber and <> i DISPOSESCRIPTS_SCRIPT and <> i CONTROLS_SCRIPT)
       DisposeScript(i)
    )
  )
)
/******************************************************************************/

Additionally, this code could possibly replace this section of code in Main.sc:

Code: [Select]
(method (startRoom roomNum)
DisposeLoad(
NULL
FILEIO_SCRIPT JUMP_SCRIPT EXTRA_SCRIPT WINDOW_SCRIPT
       TIMER_SCRIPT FOLLOW_SCRIPT REV_SCRIPT DCICON_SCRIPT
       DOOR_SCRIPT AUTODOOR_SCRIPT WANDER_SCRIPT AVOID_SCRIPT
)
DisposeScript(DISPOSELOAD_SCRIPT)
         ...

like this:

Code: [Select]
(method (startRoom roomNum)
DisposeScripts()
                DisposeScript(DISPOSESCRIPTS_SCRIPT)
         ...

41
Forum Support and Suggestions / Fan game source code
« on: January 20, 2013, 03:05:52 PM »
Here's a suggestion:  how about creating an area for hosting all the fan game source code?  Reason being so it could be fully searchable.  Right now, I've got all fan game source code on my laptop and every time I want to find an example of how something is done I end up grepping the whole directory structure until I find examples of the code I want, then I go and open the script.  Works fine for me, but an online feature like this might make things more accessible for others.

I'm imagining something similar to an online SVN repository browser.

Maybe SMF has a plug-in for something like this?

42
SCI Community How To's & Tutorials / Graphical health meter
« on: January 09, 2013, 08:36:46 PM »
Here's a really simple solution to accomplish this.  First, the laborious part; you need to make a view starting with a health bar at 'full strength', and then in each frame remove one 'line' of heath.  My implementation used a health meter with a length of roughly 100 pixels (so 100 cells in the view).  We will instantiate this as our 'lifeMeter' view.

Once you have your view created, add this code to your room script:

Code: [Select]
   (local
        flag
    )

    (instance public rm001 of Rm
       (method (init)
           ...
           (lifeMeter:init())      // display the life meter on the screen
           = flag FALSE            // init the flag variable
       )

       (method (doit)
           (super:doit)
                // when we hit particular cells in the view, display messages to the user
(switch (lifeMeter:cel())
  (case 35
    (if (not flag)
       Print("You don't feel so well.")
       = flag TRUE
  )
  )
  (case 70
    (if (not flag)
       Print("You are doubling over in pain.")
       = flag TRUE
  )
  )
  (case 95
    (if (not flag)
       Print("Death is imminent.")
       = flag TRUE
  )
  )
  (case 100
    (if (not flag)
       Print("You are dead.")
       = flag TRUE
  )
  )
  (default               // need this so that for the 10 seconds that this cell is active
    = flag FALSE   // for the states specified in the switch above that the message is
                                          // only displayed once
  )
)
        )
    )

    (instance RoomScript of Script
      (method (changeState mainState)
           (var currentCel)
           = seconds 10  // wait 10 seconds
           = currentCel (lifeMeter:cel())   // get the current cell of the health meter view
           (lifeMeter:setCel(+ currentCel 1))  // advance to the next view in the cell, life meter is now shorter
      )
    )

    (instance lifeMeter of Prop (properties y 8 x 165 view 11))  // meter located top-center of screen

Basically, the changeState() method runs continuously, every 10 seconds it shortens the health bar by advancing the view to the next cell.  The doit() method waits for the view to hit certain cells, and when it does it alerts the user of their failing heath.

Obviously, this is a really simple implementation, suitable perhaps if the ego is poisoned and steadily losing health, or maybe dying from starvation.  If you wanted something that was more 'event-driven', you could go without the changeState() entirely, and handle the changing of the lifeMeter view through specific events in your game (monster attack, ego touches a particular control color, etc).

43
SCI Syntax Help / doit() and changeState() in room script
« on: January 06, 2013, 07:47:25 PM »
I can't seem to get these to both work together in the same room script.  When I attempt to have both methods in my room, it seems to break the 'state progression' counter.  The doit() still operates normally, but the 'state' variable used in the changeMethod never gets incremented.

44
I just utilized the dying.sc script for the first time and I immediately noticed that there is a significant delay between calling the the script and the death 'screen' popping up.

This is by design, but I didn't like the fact that the delay length was hard-coded into script.  Making a few modifications, I exposed the delay property for the script:

Code: [Select]
(instance public DyingScript of Script
(properties
   seconds 3     //  Exposed this property (just by adding it here),
        )                    //  which is inherited from the Script class & set the default to 3

(method (changeState newState)
(var mbResult, message)
= state newState
(if(== state 0)
ProgramControl()
(send gTheMusic:fade())
(send gRoom:setScript(0))
Load(rsSOUND 2)
//= seconds 3     // Commented out this line, which set the delay to 3 seconds
)(else
   (if(== state 1)
                ...

So now, when I call the dying script, I can specify seconds like so:

Code: [Select]
  (send dyingScript:
       caller(802)
       seconds(1)   //  You can set this to however long you wish, based on your animation length
       register("You are dead.")
   )

If you need more granularity than seconds, it would be simple to expose the 'cycles' property instead of the 'seconds' property in the Script class, then change the dying script to use cycles instead of seconds.

45
SCI Syntax Help / Detect click on a view
« on: December 27, 2012, 06:09:34 PM »
Okay, so I know I can use the nsTop, nsBottom, nsLeft, and nsRight to detect if I've clicked anywhere on the full area of a view.

What I would like to know is if I've clicked on the visible portions of the current cel within a view.  I have a view that is fairly large, but the viewable pixels only occupy a small portion of the view within a cel.

Any suggestions here?

Pages: 1 2 [3] 4 5 ... 9

SMF 2.0.19 | SMF © 2021, Simple Machines
Simple Audio Video Embedder

Page created in 0.053 seconds with 19 queries.