Jump to content
  • Sky
  • Blueberry
  • Slate
  • Blackcurrant
  • Watermelon
  • Strawberry
  • Orange
  • Banana
  • Apple
  • Emerald
  • Chocolate
  • Charcoal

Eunomiac

Members
  • Content Count

    25
  • Joined

  • Last visited

  • Days Won

    4

Posts posted by Eunomiac

  1. Thank you!  That's exactly what I was envisioning, I was just missing a few of the pieces to get it to work.

     

    Unfortunately, you confirmed my main concern---that I have to trigger meExportBus.exportIntoSlot() once per item.  I'm fairly sure iterating on each individual item will begin to cause problems as players hook up extremely high-quantity/high-speed item inflows.

     

     

    One idea I'm tinkering with is to use a long-period timer that, upon firing, records a count of every item in the network, then voids the items by yanking the storage drives themselves and dumping them into a Trash Can (replacing them with blank storage drives pulled from an infinite repository).  Then it's just a matter of processing and tracking the data, and reacting with warnings or the like if any of the "rules" are broken.  That should be more resilient to scaling, I think.

     

    Thanks again for your detailed post---I know there are a few other AE-related questions in this forum that would benefit from reviewing your examples, so you've helped a lot of us!

  2. Bit of Background:  I'm working on an adventure/building/design map that focuses on creating a balanced network of automated systems, with a few twists to spice up the challenge.  One of these twists makes accumulating too much of a resource a problem the player has to address in their automation (long story short: voiding mechanics and high-capacity storage options are disabled and/or against the rules).  So, if you want to automate a MFR Biofuel Generator using nine different types of crops, you'd better make sure you're generating each crop at the same rate... or you'll get a surplus, and FUNishments will ensue (component.debug(WorldEdit commands go here)).

     

    The Puzzle: There is, fortunately, one way to get rid of excess items: certain "pairs" of items can be voided together (usually, one item that requires a bit of automation must be "spent" to void something you're likely going to have too much of).  For example, you can sacrifice 1 stack of Jack o' Lanterns to also sacrifice between 1 to 3 stacks of Rotten Flesh (... making automated Jack o' Lanterns an essential part of a mob farm! Fun times).  I intend this to be very fluid---players can continuously pump both Jack o' Lanterns and Rotten Flesh into the voiding "system", and as long as they're sending 1 (or more) Jack o' Lanterns for every 3 Rotten Flesh, all will be well.

     

    I'm thinking the best way to do this is with AE:  Players dump/pump/pipe/whatever their surplus items into an inaccessible (to them) AE system.  A computer periodically scans the drives looking for valid pairs.  If it finds a valid pair---say, 64x Jack o' Lanterns and 123x Rotten Flesh---it configures an Export Bus to send those items into a Trash Can.

     

    So far, I have Adapters with Database Upgrades ready to configure the trades, and another Adapter with an Inventory Controller Upgrade adjacent to an Export Bus to (hopefully) program it with the correct items to purge.  Thing is, I've never worked with OC databases or AE integration before, so I want to make sure I'm not starting off on the wrong foot before I spend hours learning how it all works ;)

     

    Is this the best set-up?  Will it work at all?  Do you see any issues I'll run into, or things to watch out for? 

     

    One thing I noticed, is I can't figure out how to export a specific number of a certain item---according to the method documentation, it seems I can only run a "single cycle" of the export bus, and I'm not quite sure what that means.  Should I be using the Inventory Controller on the me_controller component instead... or ... something?

     

    Bah, sorry for the wordiness---I can't help it, it's a real problem.  Tons of thanks in advance, and even a little afterwards, for any advice or insights you can provide!

  3. When I'm testing a program, my standard "workflow" is to Ctrl-Alt-C out of the program and simply re-run it, whenever I want to test new code.

     

    I know to use package.loaded[library] = nil to unload libraries, but I'm running into two other issues after I started playing around with event.timer():

    • How do I cancel or purge all timers in response to a Ctrl-Alt-C interrupt?  Is there something similar to package.loaded[lib] = nil; library = require(lib) that I can add to the beginning of my programs to wipe out timers from previous runs?
    • Some elements (I'm not sure which) of my programs are persisting in memory after Ctrl-Alt-C'ing out, resulting in the occasional out-of-memory error if I don't reboot before restarting the program.  I suppose a broader question that would encompass the first bullet might be "is there a command I can call to "purge" everything from the interrupted run of my script, ensuring each time I call my main program it begins in a completely clear environment?"

    Thanks!

  4. ... The current code gives me a 

     

    /autorun.lua:5: unexpected symbol near '.'

     

    EDIT:  Wait!  It's the "local".  Remove "local" from in front of comp.gpu.bind.  (I'll leave my original post, in case it ends up being an issue after all, but I'm 95% sure it's the "local" :) )

     

    I'm just heading to bed, so my apologies for the drive-by attempt at helping... but I used to get this error when I wrote programs in Notepad++, before I switched the encoding to "Encode in UTF-8 without BOM". Other encodings (... codings? encodes?), like ASCII, use hidden characters for things like line breaks that OC doesn't like.

    You can quickly check this by opening the program in OC's edit terminal---if you see a question mark in a box on line 5, delete it and see if that solves your problem. (Otherwise, I can't see anything that would be flagged as an "unexpected symbol".)

    If that does prove to be the problem, you can prevent it from happening in the future by switching the encoding to UTF-8 without BOM. (It's under the Encoding menu in Notepad++, and should be easy-enough to find if you're using a different editor.)

     

  5. Nice, that reference image will probably come in handy at some point. I like what you did there with the heading sizes/layout, looks really fancy yet so simple. :)

    Would those palette changes actually be useful for anything? Color themes are a nice idea, but that's basically it. Most other things that I was thinking of, e. g. highlighting the currently selected text field in a GUI, would require assigning "objects" to the palette slots, and there could only be 16 of them.

     

    Yeah, I wouldn't use palette swaps for that. I'd recommend a few "nuts & bolts" functions to make working with colours easier, and have your GUI objects call those to change their colours. E.g. I made my own versions of gpu.set and gpu.fill, which use my setColor() function, which uses a custom palette that references colors by name:

     

    local palette = {
        Black = 0x000000,
        Grey1 = 0x2D2D2D,
        Grey2 = 0x4B4B4B,
        Grey3 = 0x696969,
        Grey4 = 0x878787,
        Grey5 = 0xA5A5A5,
        White = 0xFFFFFF,
          -- ... and so on, all the colours of the rainbow, till...
        LtPurple = 0xCC92FF
    }
    
    function setColour(bg, fg)
      if not (fg or bg) then
        bg = "Black"; fg = "White"
      end
      if bg then
        bg = assert(palette[bg], "Bad BG colour '" .. tostring(bg) .. "' in setColour().")
        component.gpu.setBackground(bg)
      end
      if fg then
        fg = assert(palette[fg], "Bad FG colour '" .. tostring(fg) .. "' in setColour().")
        component.gpu.setForeground(fg)
      end
    end
    
    gpuFill(" ", 1, 1, 24, 3, "DkPurple") 
    gpuSet("Gold text, purple box.", 2, 2, "DkPurple", "Gold")
    
  6. Thanks, that fits with the results I get with my testing!  Here's a color table reference that I kinda... over-did (as is my way); it's indexed and includes the 240 main colors plus the 16 greys.  Definitely a good resource for anyone who wants to plan color schemes in an image editor before coding them in (feel free to add it to the wiki or wherever, if you like; I happily cede it to you in delayed payment for adding remote component access to the debug card):

     

    zbyB9am.png

     

    Does that mean that palette changes are retrocative? e. g. if you write text in palette color 1 and later reassign that palette slot, will the previously displayed text change color? I never understood that part of the color palette mechanics.

     

    Yes, if you change the color palette, anything you've drawn in that color will change to the new color.  (It's actually a pretty useful feature; you can create a bunch of 16-color "themes" and switch between them with a single setPalette, changing the colors of everything on-screen.)

  7. Those are some very sexy patterned GUIs!

    I'd recommend http://unicode-table.com/ for getting a quick overview, though. Only then check the image lookup tables to see how it'd actually look in-game.

     

    Thanks!  I can't take full credit, I found some ASCII patterns on the web and just replaced the slashes and underscores with the corresponding full-width unicode versions.

     

    The main reason I browse these images rather than other sources online is because I'm usually picking symbols based on how they connect with their neighbors, or how they're positioned inside their "boxes" relative to other symbols I'm using (i.e. if one symbol in a set happens to be positioned lower than the others, it looks awful).  It's impossible to get that information without seeing them rendered in OC---so before I made these images, there was a lot of tedious back-and-forth cross-checking :)

  8. Is there a reason why I'm not getting any help at all.

    Yes.  Or, at least, why it's not coming quickly.  You're asking a question that takes a lot of time and effort to answer: to go through your custom API and figure out how it works, then apply that knowledge to your code, and debug it for you.

     

    Make it easier for people to help you:  Narrow down the issue by debugging it yourself as much as you can. 

     

    Try writing a very simple program, verify that it works, then slowly add functionality until something breaks.

     

    Or, try walking through your program step-by-step in the lua console.  Open the lua console (type lua), and load your library with scr = require("screen").  You can do the same with your main script's functions, by moving them to another library that you can then require.  From there, play around with the functions by calling them with various parameters and checking the results, to see what doesn't work as expected.

     

    Or, and this is my favorite method, create a quick debug function that simply writes whatever parameter you pass to it to a debug text file:

    function db(text)
      local debugFile = io.open("debug.txt","a")
      debugFile:write(tostring(text))
      debugFile:close()
    end
    

    Call "db(text)" throughout your program.  Use it to check the values of variables and function results at specific points ...

    db("Starting Button Click, ret = " .. tostring(ret) .. ", isCityOn = " .. tostring(isCityOn))
    

    ... or, pepper it throughout your program to create a series of "checkpoints" that you can then use to figure out if, when, and in what order things are happening (e.g. db("Starting Draw") at the beginning of the draw function that isn't working, to see if the function is actually being called when it's supposed to, or if the function is misbehaving).

     

    If you can ask for help in a way that doesn't require learning how your whole program works, you'll get that help faster.

  9. Oh yeah, two more things: 

    • I didn't include pages that were entirely Asian characters, as there were a lot of them, and I wanted to focus on symbol-type characters.  (Besides, I assume anyone interested in those characters is more familiar with using them than I)
    • I apologize for the repeats in the albums, and for the (I think) unnecessarily high code numbers---I didn't know unicode very well when I first compiled these images, and scanned codes way higher than I needed to.  I believe unused high-number codes take repeat filler characters... or something... and I haven't been able to spot a clear division point.  Regardless, all the characters should be there, and all the codes do work.
  10. Moderator note: this post is really outdated, and does not represent current OC.

     

    OpenComputers has incredible support for unicode!  Here's a catalogue of OC's unicode support, with each character displayed on a T3 OC monitor.  You can browse these images for the symbols you need, then look up the corresponding unicode.char() value by referring to the numbers at the edges.

    I've divided the characters into two categories.  "Single Width" characters are easy to use, since they take up the same space as a normal letter.  "Double Width" codes are a bit trickier---they don't work well with unicode.length() and can be a hassle to place (I find it best to contain them inside a "box" that's two characters wide, for things like buttons or icons).

     

    ** Make sure to view full-screen for the best detail. **

    And finally, some examples of the nifty art you can make with unicode (in particular, the box-drawing characters, starting at 9470):
     

     


    The block characters (unicode 9600 - 9631) let you divide a character space into quarters and fill in any combination of them, allowing (among other things) nifty block letters. Other box-drawing characters lend nice curved edges to window borders.
    0b9zKsr.png

    Unicode characters 9585, 9586 and 9587 offer diagonal lines and X's that span a full character space, allowing crisp diagonal lines without breaks. A full suite of double-width letters, numbers and punctuation (unicode 65281-65376) makes for nice big-ticket items (e.g. the elemental vertices on this map), and help if you need to center something in a space of even width.
    YOSELPD.png
     
    Those box-drawing characters really shine when used to create tessellating patterns, since they all connect without any gaps. It's easy to convert ASCII art into Unicode---just find an ASCII pattern you like on the web, and convert all the slashes and underscores into the corresponding "full size" unicode versions.
    BHasFxb.png

  11. I've been experimenting with color in OpenComputers, and I have a few questions relating to how the color values I code are changed into the color values I actually get.

     

    I'm trying to create six color schemes (three colors each) to distinguish six modes of a GUI.  After planning a few schemes and programming in the color hex codes, I've found (using gpu.get()) that the colors I enter are very rarely the ones displayed on screen.  Almost all colors are changed to some degree, and quite often (45% of the time in my last test, see spoiler tags) two different colors display as the same color.

     

    I realize this has everything to do with Color Depth, of course.  So I'm interested in learning how OC color depth works, and how I can choose colors that will render accurately on-screen:

    • Is OC's "8-bit Color Depth" equivalent to "3 bits Red, 3 bits Green, 2 bits Blue" 256-color, as described in this Wikipedia article? 
      • If so, is there a color table anywhere that lists the available colors? (I've been unable to find one).
    • Does the color table vary depending on the colors I've already used?  In other words, is it possible that two colors may be valid when used in isolated programs by themselves, but trying to display them together merges them into one color?
    • Is there a way to configure Photoshop (or any other color app) to work with OC's color table?  I'm familiar with Indexed Color mode, which gives you a 256-color palette, but none of the "fixed" options (Websafe, Windows System, Mac System, Spectrum, etc.) seem to fit the colors OC is giving me.  I'd love some way to plan colors that will translate properly to OC.

    Lastly, here's an example of a palette test program I ran that shows what I mean.  It takes an array of different colors defined by hex code, and draws a square of each on the screen.  Then, it checks each square with gpu.get() and identifies any repeating displayed colors with red frowny faces (as, ideally, all of the colors would be different):

     

    E.g. 1: The first red frowny-face is flagging the second square for repeating the first square.  Those squares were set to 0xFFF5EE and 0xFAF0E6, respectively, but both displayed as 0xF0F0F0. 

    E.g. 2: The second red frowny-face flags a repeat two squares earlier---the result of 0xFFE4C4 and 0xFFDAB9 both displaying as 0xFFDBBF.  

    (I realize these are very close colors, and it's entirely expected that they'd render the same at 8-bit color depth---the point of this test was more to figure out why both colors were altered, and what determines which colors change, and how.)aIqSc3n.png

     

    Thanks in advance for your help!

  12. I'm not sure if this is due to a change in more-recent versions, but you'll want to use "package.loaded", rather than packages.loaded, for this to work.

     

    This also works from within programs:  Simply set the package.loaded table to nil for any libraries you frequently edit just before you require them, and any changes made to those libraries will be reflected on a soft reboot (rather than having to manually turn the computer/server off-then-on).  

     

    Here's a C&P from the top of my program:

    --========= DECLARING TOP-SCOPE VARIABLES ============================================================================
    local component, dbCard, cb
    local str, event, term
    local A, D, H
    local CLASS, HEXCLASS
    local CONSOLE, GRID
    local DB, STATUS
    
    do --========= INITIALIZING TOP-LEVEL COMPONENTS, CLASSES & VARIABLES ================================================
      do --*** IMPORTING LIBRARIES & INITIALIZING TABLE VARIABLES ***
        component = require("component")
        dbCard = component.debug
        cb = component.command_block
    
        str = require("unicode")
        event = require("event")
        term = require("term")
    
        package.loaded.ArtLib = nil
        package.loaded.DataLib = nil
        package.loaded.HexConfig = nil
        A = require("ArtLib")
        D = require("DataLib")
        H = require("HexConfig")
    
        --// snip // ... and so on
    

     

  13. Even better! You sneaky wizard you... I cant wait to check it out, I noticed your holoogram handy work on another post and couldnt wait to get more details on what it was about. Lemme know if you wan beta testers or something :).  Also, in the photo with the hologram and the two screens with "The breach"; will that hologram draw out the player created jaunt points?? 

    I thought about it, hadn't planned on it, and then you go ahead and suggest it.  So now... yes, yes it will :P

     

    And I will be looking for testers for a closed alpha relatively soon---just have to finish up some of the remaining programs---so I'll save you a spot.  (You see, by having a closed alpha, then an open beta, and then a release... I get to advertise three different times without it looking like I'm spamming advertisements!  It's BRILLIANT! Muahahahahaha... ahem.)

  14. Whoa.  With the recent changes to the Debug card in builds 142 and 143, OpenComputers has just become the mod for adventure map builders everywhere.  THANK YOU!  

    • Teleporting players is so much faster using the debug card than it is using command blocks.
    • You're telling me I can change entire areas of blocks, WorldEdit style?  That's more power than the Command Block ever dreamed of!
    • And, of course, that one feature I begged you for:  The ability to grab a player's location from a remote terminal.  

    My teleportation program works perfectly.  

     

    In case you wanted to see the fruits of your labour in action, I cobbled together some screen shots.  (Captions at the bottom explain stuff <--- always feel like I need to say this with imgur, because they're just so damn tiny.)

     

    Now, I'mma gonna get started playing with those block-manipulation commands.  And here I thought I was going to have to fiddle with a network of Mechworks Drawbridges... 

  15. Sry for beeing offtopic, but your build looks just awesome. Just had to say this even though it's not helping. Sorry for that. I specially like the combination of the floor screen and hologram.

     

    Thanks!  I'm working on a survival "build" map that, instead of having specific goals (like Skyblock) is more freeform---players find themselves in the ruins of a hexagon-shaped city named Hex (tres original, I know).  It's divided into six triangular districts, each with its own themes (high/low tech, magic, agriculture, etc.).  Working within a few creative constraints, they must define what each district looks like, and rebuild Hex.

     

    The floor is inside a floating hub at the very center (the Hedron); it's actually a touch-screen linked to command blocks, that will teleport players to any of the six districts.  I'm definitely pushing OpenComputers in this build---there are four multiblock screens, all doing different things.

     

    Here's a screenshot of the whole thing from above the Hedron (just because I feel like showing off ;) ):

     

    bWS10vP.png

  16. I've been playing with OpenComputers for some time now, and I've come across a few issues that I'm having trouble with.  I'm not sure if these are bugs (in which case I'll post them to the issue tracker; just let met know), or if they've been fixed in the most current version (I'm still on MC 1.7.2, running OC v. 1.3.1.260), or if they're just me derping :)
     
    1) How to Turn Sounds Off Via Config?
    I've set the "soundVolume" value to "0" in config/OpenComputers.cfg, on both client and server, and yet this doesn't seem to reduce or eliminate the grinding noise whenever my computers execute a command (or perhaps access a file via the filesystem API?).  Is this intended behavior?  Would switching over to Server Racks make for a silent computer?

    2) Large Multiblock Screens Disassemble on Login; Breaking/Replacing Blocks Fixes It

    I've increased the allowable size of multiblocks screens to 12x12 in the configs (server and client).  However, whenever I log in, my large 11x7 screen has fragmented into numerous smaller screens (shown below).  Breaking and replacing various screen blocks eventually "rebuilds" the screen to its full size, but it takes a bit of fiddling until the whole thing eventually snaps together:

     

    3FauWae.jpg

     

     

    3) Hologram RGB Values Randomly Reverse Themselves

    I'm running the following code to set the palette of my (Tier 2) hologram (it's being used to present a 3D image of a fortress):

    hologram.setPaletteColor(1, 0xFFFF99) -- pale-yellow (outer towers)
    hologram.setPaletteColor(2, 0xFFFFFF) -- white (unused)
    hologram.setPaletteColor(3, 0x777777) -- grey (walls)
    

    Whenever I form the hologram, I randomly get either the desired pale-yellow towers, OR I get a pale-cyan instead.  I suspect "0xFFFF99" is being reversed, to  "0x99FFFF", which would explain the cyan color:

    09giK4P.jpg

     

    Hopefully I've given enough information to be helpful; if not, please let me know and I'll supply whatever is missing.  (And I'm sorry if I should have gone straight to the issue tracker with these, but given that I'm running a version behind and aren't entirely sure whether these have been fixed and/or are bugs at all, I thought I'd check here :) )

  17. Have a drink! ;)

     

    You, sir, are a gentleman and a scholar and a sterling example that elevates us all as human beings  :D

     

    You're using OC 1.3, right? so that autorun file is probably on your os disk, right? or is it on a separate hard drive?

     

    Yes, OC 1.3 on MC 1.7.2.  I installed the OS to the hard drive, and placed the autorun.lua in the same location.

     

    Currently, the following "autorun.lua" file almost works.  My current problem is that setPrimary() apparently selects the gpu randomly from the three I have installed, despite the fact that (I think) I've properly passed a valid gpu address to setPrimary().  The weirdness happens somewhere in the section I've commented as "2) Setting Primary GPU", halfway down the code:

    local primaryGPUAddr = "3f5"
    local primaryScreenAddr = "1a1"
    local fs = require("filesystem")
    local component = require("component")
    
    -- A quick list of the components, just so you can verify my addresses are correct.
    -- 'db(text)' is a function I've snipped out for brevity; it just writes the text parameter to a debug file, which I'll post below
    
    db("COMPONENTS:")
    for compAddr, compType in component.list() do
      db(compAddr .. " --- " .. compType)
    end
    db("\n")
    
    -- 1) Mounting the hard drive & verifying
    local address = ...
    local hdCheck, hdError = fs.mount(address, "/main")
    if hdCheck then
      db("1) Mounted hard drive under '/main'")
    else
      db("1) Hard Drive did NOT mount: " .. tostring(hdError))
    end
    
    -- 2) Setting Primary GPU
    -- (a) Checks address of randomly-chosen primary GPU:
    if component.isAvailable("gpu") then
      db("2(a) Primary GPU randomly assigned at Boot: " .. tostring(component.gpu.address))
    end
    
    -- ( Change primary GPU:
    primaryGPUAddr = component.get(primaryGPUAddr) -- resolve full GPU address from the 3-letter abbreviation I set at the very top
    db("2( Setting Primary GPU to: " .. tostring(primaryGPUAddr))
    component.setPrimary("gpu",primaryGPUAddr)
    os.sleep(0.2) -- This "sleep" was advised by Sangar to give setPrimary a chance to catch up; however, as you'll see, it still doesn't seem to work properly.
    
    -- (c) Check again whether primary GPU exists:
    if component.isAvailable("gpu") then
      db("2(c) Primary GPU successfully changed: " .. tostring(component.gpu.address))
    else
      db("2(c) No Primary GPU!")
      db("... GPU Address = (" .. tostring(component.gpu.address) .. ")")
    end
    
    -- 3) Binding Primary GPU to Screen
    primaryScreenAddr = component.get(primaryScreenAddr) -- resolve full screen address
    local gpu = component.gpu
    db("3) Attempting Screen Bind: " .. tostring(gpu.bind(primaryScreenAddr)))
    

    Before I added that "os.sleep(0.2)", the debug output would simply stop at that point---I wasn't giving setPrimary() enough time to configure the gpu, and so the program would stop with a "no primary gpu" error in the event.log.

     

    However, now the above code gives me the following debug file.  Note the randomly-selected gpu, different from the gpu address I used with setPrimary():

    COMPONENTS:
    7ba654c7-9a62-4221-978e-01b9e3e13ede --- computer
    98aa9c50-3f18-433f-99af-93fc83b7bbe5 --- gpu
    3bdd83ae-1559-42b4-98dd-09cb46a8fb16 --- gpu
    dc40b4b8-4663-4378-b4e5-2a4da339b42f --- screen
    b3f856ca-8e6c-484f-9f52-bf30448736f2 --- keyboard
    1a1c197d-bf4d-4b59-90e6-f6ecc3f74035 --- screen
    3f5359d7-b4a9-442b-a17d-26cef3db1e48 --- gpu
    e33dafce-6893-422a-b1b1-61ce080735e3 --- screen
    83c65b98-76c1-44e6-8e71-0df8fbb2d681 --- filesystem
    14bf0dce-d956-4c5e-baa8-f0db51cf11f8 --- filesystem
    
    1) Mounted hard drive under '/main'
    2(a) Primary GPU randomly assigned at Boot: 98aa9c50-3f18-433f-99af-93fc83b7bbe5
    2( Setting Primary GPU to: 3f5359d7-b4a9-442b-a17d-26cef3db1e48
    2(c) Primary GPU successfully changed: 3bdd83ae-1559-42b4-98dd-09cb46a8fb16
    3) Attempting Screen Bind: true
    

    Again, this is random behavior---sometimes the primary GPU is properly set, other times it doesn't change it at all from whichever was randomly chosen at boot... it's very odd, and I'd appreciate any help you can provide (drinks too!)

  18. Well this is just getting weirder and weirder.  Now, setPrimary appears to randomly select the gpu.  Here is the debug output (the only change to the initial file was adding "os.sleep(0.2)" immediately after setPrimary, and adding the output of a component.list to my debug file so you can confirm I'm getting my addresses right):

    COMPONENTS:
    7ba654c7-9a62-4221-978e-01b9e3e13ede --- computer
    98aa9c50-3f18-433f-99af-93fc83b7bbe5 --- gpu
    3bdd83ae-1559-42b4-98dd-09cb46a8fb16 --- gpu
    dc40b4b8-4663-4378-b4e5-2a4da339b42f --- screen
    b3f856ca-8e6c-484f-9f52-bf30448736f2 --- keyboard
    1a1c197d-bf4d-4b59-90e6-f6ecc3f74035 --- screen
    3f5359d7-b4a9-442b-a17d-26cef3db1e48 --- gpu
    e33dafce-6893-422a-b1b1-61ce080735e3 --- screen
    83c65b98-76c1-44e6-8e71-0df8fbb2d681 --- filesystem
    14bf0dce-d956-4c5e-baa8-f0db51cf11f8 --- filesystem
    
    1) Mounted hard drive under '/main'
    2(a) Primary GPU exists at Boot: 98aa9c50-3f18-433f-99af-93fc83b7bbe5
    2( Setting Primary GPU to: 3f5359d7-b4a9-442b-a17d-26cef3db1e48
    2(c) Primary GPU successfully changed: 3bdd83ae-1559-42b4-98dd-09cb46a8fb16
    3) Attempting Screen Bind: true
    
  19. Apologies for the kinda-double post, but the problem I initially described in "[OC 1.3] Inconsistent autorun.lua" seems to be something else entirely---which I only realized after several walls of text ;)

     

    Hardware:  One computer, containing 3x GPU and 1x Hard Drive, linked by Cable to 3x Screens:

    • the "Terminal" --- a simple 1x1 with a keyboard
    • two "Displays" --- each is a large multiblock screen on the far side of the room

    Software:  An autorun.lua file on the hard drive attempts to:

    1. mount the hard drive,
    2. set a specific GPU to be the primary GPU, then
    3. bind the primary GPU to the "Terminal" screen

    Here's the full autorun.lua file (with a debug function edited out; "db(<string>)" simply logs the message to a debug file):

      local primaryGPUAddr = "3f5"
      local primaryScreenAddr = "1a1"
      local fs = require("filesystem")
      local component = require("component")
    
    -- 1) MOUNT HARD DRIVE & VERIFY SUCCESS
      local address = ...
      local hdCheck, hdError = fs.mount(address, "/main")
      if hdCheck then
        db("1) Mounted hard drive under '/main'")
      else
        db("1) Hard Drive did NOT mount: " .. tostring(hdError))
      end
    
    -- 2) SET PRIMARY GPU
    -- (a) Checks address of randomly-chosen primary GPU:
      if component.isAvailable("gpu") then
        db("2(a) Primary GPU exists at Boot: " .. tostring(component.gpu.address))
      end
    
    -- ( Change primary GPU:
      primaryGPUAddr = component.get(primaryGPUAddr) -- resolve full GPU address
      db("2( Setting Primary GPU to: " .. tostring(primaryGPUAddr))
      component.setPrimary("gpu",primaryGPUAddr)
    
    -- (c) Check again whether primary GPU exists: 
      if component.isAvailable("gpu") then
        db("2(c) Primary GPU successfully changed: " .. tostring(component.gpu.address))
      else
        db("2(c) No Primary GPU!")
        db("... GPU Address = (" .. tostring(component.gpu.address) .. ")")
      end
    
    -- 3) BIND PRIMARY GPU TO "TERMINAL" SCREEN:
      primaryScreenAddr = component.get(primaryScreenAddr) -- resolve full screen address
      local gpu = component.gpu
      db("3) Attempting Screen Bind: " .. tostring(gpu.bind(primaryScreenAddr)))

    Debug Output:  

    IF the boot sequence happens to randomly select the same GPU I want as my primary, everything works fine, and by debug output looks like this:

    1) Mounted hard drive under '/main'
    2(a) Primary GPU exists at Boot: 3f5359d7-b4a9-442b-a17d-26cef3db1e48
    2( Setting Primary GPU to: 3f5359d7-b4a9-442b-a17d-26cef3db1e48
    2(c) Primary GPU successfully changed: 3f5359d7-b4a9-442b-a17d-26cef3db1e48
    3) Attempting Screen Bind: true
    

    (note the address at 2(a) is the same as the desired primary GPU)

    However, if the boot sequence picks one of the other two GPUs, "component.setPrimary()" apparently removes the primary GPU instead of changing it, and I get the following debug output:

    1) Mounted hard drive under '/main'
    2(a) Primary GPU exists at Boot: 3bdd83ae-1559-42b4-98dd-09cb46a8fb16
    2( Setting Primary GPU to: 3f5359d7-b4a9-442b-a17d-26cef3db1e48
    2(c) No Primary GPU!
    

    Additionally, the following error shows up in /tmp/event.log:

    boot/03 component.lua:51: no primary 'gpu' available
    

    (I assume this error exits the code, preventing more debug messages, when I first try the "component.gpu.address" immediately after the "No Primary GPU" debug message.)

    Any idea what's going on?  The fact that everything works if the desired GPU is randomly chosen at boot, suggests that the code is working, and that something is fishy with component.setPrimary().

  20. And things keep getting weirder.  Apparently, "setPrimary" isn't working for me.  Here's a test "autorun.lua" I ran after trying to figure out that "no primary gpu" error in the event.log (I used a debug file, since "print" depends on there being a primary GPU, which is the main problem):

    local primaryGPU = "3f5"
    local primaryScreen = "1a1"
    
    function db(text) -- //snip// just writes "text" to a debug file -- end
    
    local component = require("component")
    primaryGPU = component.get(primaryGPU) -- resolve full address
    
    -- First, check whether primary GPU was randomly assigned:
    db("Primary GPU Exists at Init? " .. tostring(component.isAvailable("gpu")))
    if component.isAvailable("gpu") then
    	db("... and Primary GPU at Init is: " .. component.gpu.address)
    end
    
    -- Then, set primary GPU to desired address:
    db("Now Setting Primary to " .. tostring(primaryGPU))
    
    component.setPrimary("gpu",primaryGPU)
    
    -- And check again whether primary GPU exists:
    db("Primary GPU Exists? " .. tostring(component.isAvailable("gpu")))
    if component.isAvailable("gpu") then
      db("... and the new Primary GPU is: " .. component.gpu.address)
    else
      db("What? No Primary GPU!")
    end
    

    And the output to my debug file:

    Primary GPU Exists at Init? true
    ... and Primary GPU at Init is: 98aa9c50-3f18-433f-99af-93fc83b7bbe5
    Now Setting Primary to 3f5359d7-b4a9-442b-a17d-26cef3db1e48
    Primary GPU Exists? false
    What? No Primary GPU!
    

    ... so now I have no idea what's going on, and I've been at this for... uh... five hours now.  I need a drink.  Drinks.  Many drinks.  Please help :P

  21. Ok, I've been at this for a long while, trying all sorts of different strategies.  Please forgive the lengthy post, and thanks in advance for your help!  I've bolded key points as an inline TL;DR.

     

    I think the problem is that the 'init' event isn't being heard by the autorun program.  The listener is being registered, but the callback function isn't being run.

     

    Here's my current autorun.lua, with a bunch of debugging "print()" messages to help see exactly what code is being run:

    local address = ...
    local primaryGPU = "3f5"
    local primaryScreen = "1a1"
    
    print("Mounting Drive: " .. tostring(address))
    
    local fs = require("filesystem")
    fs.mount(address, "/main")
    
    function BindGPU() -- I extracted the function from the event declaration to see if that did anything, but it made no difference.
      component = require("component")
      component.setPrimary("gpu",component.get(primaryGPU))
      gpu = component.gpu
      gpu.bind(component.get(primaryScreen))
      
      print("Init Event Heard.")
      print("Primary GPU = " .. component.get(primaryGPU))
      print("Primary Display = " .. component.get(primaryScreen))
    end
    
    local event = require('event')
    
    print("Waiting for Init Event")
    
    print("Registering Event: " .. tostring(event.listen('init', BindGPU)))
    
    print("Testing Event Registration (should be false): " .. tostring(event.listen('init', BindGPU))) -- Just a check to make sure the listener was registered, by trying to register it again.
    

    The above code does reliably mount the hard drive, which is awesome.  However, the primary screen is still chosen randomly, and none of the print messages inside the listener callback function (BindGPU) appear anywhere:

    ========================================================================
    | OpenOS 1.2 (2048k RAM)                                               |
    | Keyboards have to be attached to or placed next to a screen to work. |
    ========================================================================
    /# Mounting Drive: table: 0000000015AA6F00
    Waiting for Init Event
    Registering Listener: true
    Testing Listener Registration (should be false): false
    

    I also tried eliminating the event code, and running the GPU/screen binding immediately after (successfully) mounting the hard drive:

    local address = ...
    local primaryGPU = "3f5"
    local primaryScreen = "1a1"
    
    local fs = require("filesystem")
    fs.mount(address, "/main")
    
    component = require("component")
    component.setPrimary("gpu",component.get(primaryGPU))
    gpu = component.gpu
    gpu.bind(component.get(primaryScreen))
    

    ... but that didn't work either, and the event.log file in /tmp contains the following error:

    boot/03_component.lua:51: no primary 'gpu' available 

    ... which I assume is what happens when I fiddle with the gpu too quickly, before the system is finished initializing and fires the 'init' event, yes?

     

    Thanks for your help!  It strikes me as weird that I'm the only one having this problem... is anyone else using multiple screens and successfully binding a primary display via autorun?  The code I'm using seems fairly straight-forward, so I don't know what I could be doing differently from others...

     

    Edit:  Other things I've tried:

    • leaving everything except "require('event')" and "address = ..." inside the listener callback function, as you originally suggested (nope)
    • alternating between double and single quotes, to see if inconsistencies there caused the problem (nope)
    • inserting an "os.sleep(5)" after mounting the hard drive, to see if I could give the system time to "catch up" without having to wait for the init event (nope; I gather os.sleep() just puts everything on hold, including the init process)
    • leaving the "BindGPU" function inside the event registration, as SpiritedDusty originally wrote it  (nope)
    • repeatedly registering the event listener inside a "while InitNotHeard do" loop, with the "InitNotHeard" being toggled off inside the listener callback function, breaking the loop if the function is ever called (nope, loop runs endlessly, constantly failing to re-register the listener, as expected)
    • removing "local" from all of the variables, then adding them back, and finally only removing them from within the listener callback function (nope)

    Edit-Edit:  I ran an experiment, in which I repeated "event.pull()" inside a while loop at the very beginning of autorun.lua, just to see what events were being sent.  Apparently, no events are being pushed to autorun; the only output from that loop was a long list of "nil".

  22. Thanks for your quick reply (I had to wait until I had a chance to test before responding in kind)---unfortunately, I'm afraid that doesn't work :( 

     

    Here is the autorun.lua file contained in the root directory of the only hard drive on the computer:

    local event = require('event')
    
    event.listen('init', function()
      local primaryGPU = "3f5"
      local primaryScreen = "1a1"
    
      local component = require("component")
      component.setPrimary("gpu",component.get(primaryGPU))
      local gpu = component.gpu
      gpu.bind(component.get(primaryScreen))
    
      local fs = require("filesystem")
      local proxy = ...
      fs.mount(proxy, "main")
    
      print("Main Screen Bound")
    end)
    

    The above didn't appear to run, and the /tmp/event.log contains the following error:

    /mnt/14b/autorun.lua:13: cannot use '...' outside a vararg function near '...'
    

    That error led me to try mounting the hard drive by referencing its address directly, like so:

    local event = require('event')
    
    event.listen('init', function()
      local primaryGPU = "3f5"
      local primaryScreen = "1a1"
      local primaryHD = "14b"
    
      local component = require("component")
      component.setPrimary("gpu",component.get(primaryGPU))
      local gpu = component.gpu
      gpu.bind(component.get(primaryScreen))
    
      local fs = require("filesystem")
      primaryHD = component.get(primaryHD)
      fs.mount(primaryHD, "main")
    
      print("Main Screen Bound")
    end)
    
    

    ... which eliminated the error from the event log, but took me back to my original problem:  The hard drive isn't mounted, one of my three connected displays is chosen at random, and the "Main Screen Bound" message doesn't appear on any of the screens.

  23. I have a computer with three gpu's, connected to three screens.  One monitor has a keyboard attached to it, and is meant to be the main access terminal; the other two screens are display-only.

     

    I've added the following autorun.lua file to the computer's hard drive, to mount the hard drive and set the appropriate primary gpu and screen:

    local primaryGPUAddr = "3f5"
    local primaryScreenAddr = "1a1"
    
    local component = require("component")
    component.setPrimary("gpu",component.get(primaryGPUAddr))
    local gpu = component.gpu
    gpu.bind(component.get(primaryScreenAddr))
    
    local fs = require("filesystem")
    local proxy = ...
    fs.mount(proxy, "main")
    
    print("Main Screen Bound") -- to test all went well
    

    However, whenever I boot up my computer, autorun.lua doesn't always run---the primary GPU/screen is randomly chosen from among the three I have connected, the hard drive isn't mounted under "main", and I don't see that "Main Screen Bound" message (on any of the screens).

     

    Oddly enough, sometimes it all works perfectly (including the mounting and the printed message), but it usually doesn't---and I'm left with my cursor blinking unhelpfully on one of the giant display screens on the opposite side of the room!

  24. On the subject of UTF8 characters, I've been having trouble getting most of them to display.  

     

    According to the wiki entry for the Unicode API: "Specifically all glyphs defined in code page 437 are supported."  However, I'm very unfamiliar with the distinction between unicode/ascii/utf8, and wasn't sure which of the listed Wikipedia codes I should be using.

     

    Actually, I think a quick example-question might solve all my problems:

     

    Question:  How would I print the "DD = U+258C : LEFT HALF BLOCK" character to the screen?  (And, if I can't, how do I know which characters I can use vs. which ones I can't?)

     

    Assuming all of the appropriate libraries and components are properly loaded and configured, I figured "unicode.char(258C)" would do it, but that throws a "bad number" error.  It just occurs to me now (and I'll check this when I get home), but do I need to convert hexidecimal to decimal for it to work, e.g., "unicode.char(9612)"?  Or am I using the wrong codes entirely?

     

    Thanks for your help!

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use and Privacy Policy.