Wendigos Custom development thread

Ask and answer questions about making games and related topics. Unrelated topics go in that other forum.

Moderators: marionline, SDHawk

Post Reply
Wendigo
Red Slime
Posts: 52
Joined: Tue Feb 28, 2017 1:15 pm

Wendigos Custom development thread

Post by Wendigo »

After more or less conquering Virtuous Swords Thread for my own development questions I thought I'd create a dedicated one myself.

So I have dug a little more into the slices system and have some more questions:
  • I have successfully managed to add slices manually via code but loading them from previously saved slice collections that I made in the Slice Collection Editor doesn't seem to work. The compiler doesn't throw any errors but all I see is a black screen when I use "SliceLoadFromFile" and then parent it to the root slice via "setSliceParent".

    What is the recommended way to get the size of the screen (width/height in pixels)?

    Is it possible to use images that are of other dimensions than walkabouts, enemy sprites and so on?
    I tried to use standard images and only paint them in the needed size but transparent pixels still trigger mouse events.

    Can I load images directly from a folder on the hard drive?

    When an exported slice collection contains a sprite, does it get bundled with the collection or do I need to set the image path again when I try to "instantiate" the slice collection?

By the way I have added a new feature to my fork: "textbox whole text" to read all text from a textbox into a single string variable.
I Haven't tried to load utf-x coded text yet since I thought I'd better do small tasks at different parts of the engine to get the whole picture of how everything works together before doing harder things.
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

This sound very promising!
I did eventually notice your 'textbox whole text' commit and merged it; thanks. I made some changes to it, and renamed it to 'textbox text'. There was a bug: it looped over lines 0 to 6 instead of 0 to 7. I recommend using ubound() when looping over an array, it avoids bugs and means less code needs to be updated in future if the array changes. Also, I fixed it for consistent indentation again, and changed the error level to serrBadOp (as a rule of thumb, always use serrBadOp... although actually it hardly matters, because the option to set the error reporting level was removed).
What is the recommended way to get the size of the screen (width/height in pixels)?
There are two equivalent ways to get it; either use get_resolution() (which returns an XYPair), or use vpages(page)->w and vpages(page)->h. If you're inside some function where the page is an argument, then you should use the latter because the page could possibly be just a smaller part of the screen. Otherwise it doesn't matter, use what you want.

But most of the time you don't need to know the screen size; instead you can use constants like pBottom, pRight, pCenter, etc to position sprites, text, boxes, and some other stuff relative to edges of the screen. But these can't be used with slices. (The functions that accept them take RelPos arguments instead of integers)

If you want to know the screen size the game will run at, that's gen(genResolutionX) and gen(genResolutionY)
Can I load images directly from a folder on the hard drive?
For Game: not yet, but I'm actually working on that currently. For Custom: yes, just put the file in the data/ directory and it will be packaged with Custom. Use finddatafile to get the full path to the file.

Here's an example of loading 5 icons from a file, from mapsubs.bas (cutting them out of a strip):

Code: Select all

DIM datafile as string = finddatafile("arrows2.bmp")  'Actually a walkabout set
IF LEN(datafile) = 0 THEN
 visible_debug "arrows2.bmp missing"
ELSE
 DIM arrowset as Frame ptr = frame_import_bmp_raw(datafile)
 FOR idx as integer = 0 TO 4
  st.arrow_icons(idx) = frame_resized(arrowset, 20, 20, idx * -20, 0)
 NEXT
 frame_unload @arrowset
END IF
(Just call fatalerror instead of visible_debug if you don't want to deal with the file being missing. I was considering making Custom check all data files are present when it starts.)
Is it possible to use images that are of other dimensions than walkabouts, enemy sprites and so on?
I tried to use standard images and only paint them in the needed size but transparent pixels still trigger mouse events.
Yes, you can, see above. (I drew arrows2.bmp in the walkabout sprite editor, but it could be any dimension.) But arrows2.bmp is monochrome and I ignore the palette. For a coloured icon you should use frame_import_bmp24_or_32() instead, and pass in master() for the palette, which will load the bmp remapped to the current master palette.
When an exported slice collection contains a sprite, does it get bundled with the collection or do I need to set the image path again when I try to "instantiate" the slice collection?
In future I want slice collections to be able to store images, but right now they can only store the sprite type and spriteset number. So yes, you will need to manually lookup the slice and set it with SetSpriteToFrame. (SetSpriteToFrame didn't support unpaletted Frames, but I just pushed a commit to allow that. I haven't tested that though!)

I have an idea: lets allow sprite slices which load their image from one of the files in data/. We just need to add a string to SpriteSliceData to hold the filename, which can be saved to the .slice file. Then by adding the ability to edit it in the slice collection editor (only when creating a collection for Custom), we'll have an easy way to use icons. I think I'll implement this tomorrow!
I have successfully managed to add slices manually via code but loading them from previously saved slice collections that I made in the Slice Collection Editor doesn't seem to work. The compiler doesn't throw any errors but all I see is a black screen when I use "SliceLoadFromFile" and then parent it to the root slice via "setSliceParent".
You need to draw whichever slice you want manually, using DrawSlice or DrawSliceAt.
I guess by the root slice you mean SliceTable.Root? That SliceTable is a global in Custom is a mistake (it's not used); I've been meaning to move it out of slices.bas. Menus in Custom which draw slices just create their own root slice (but if you're loading a slice collection, you won't necessarily need another root slice, as you can draw the root of the collection directly)
Last edited by TMC on Sat Apr 15, 2017 1:37 pm, edited 5 times in total.
Wendigo
Red Slime
Posts: 52
Joined: Tue Feb 28, 2017 1:15 pm

Post by Wendigo »

I still have problems getting the loaded slice collection to be drawn to screen.
No matter if I attach it to a root node or try to DrawSlice / DrawSliceAt it directly I always get a black screen.
Below is my code, maybe you can find the culprit in there.
I also cannot use the "frame_import_bmp24_or_32" function. It throws an error into the c_debug:

Code: Select all

! ERROR: (BUG) frame_import_bmp24_or_32 should not have been called!
(I'm trying to edit the "choose_rpg_to_open" function that draws the initial new/load/exit menu)
Could it be that the master palette wasn't yet created at that point?
"frame_import_bmp_raw" works and shows the SpriteSlice (the colours are garbage of cause)

Code: Select all

SUB choose_rpg_to_open (rpg_browse_default as string)
 'This sub sets the globals: game and sourcerpg

 DIM root as Slice Ptr
 root = NewSliceOfType(slRectangle)
 WITH *root
  .X = 0
  .Y = 0
  .Width = gen(genResolutionX)
  .Height = gen(genResolutionY)
  .Fill = YES
  ChangeRectangleSlice root, , 112, , 0
 END WITH

 ' TEST
 DIM mysprite as Slice Ptr
 DIM datafile as string = finddatafile("folder.bmp")
 DIM myframe as Frame Ptr = frame_import_bmp_raw(datafile) 'frame_import_bmp24_or_32(datafile, master()) 
 mysprite = NewSliceOfType(slSprite, root)
 WITH *mysprite
  .Y = 0
  .X = 0
  .AlignHoriz = alignMiddle
  .AlignVert = alignMiddle
  .AnchorHoriz = alignMiddle
  .AnchorVert = alignMiddle
  .Fill = NO
  SetSpriteToFrame(mysprite, myframe)
 END WITH
 ' / TEST

 DIM menuslice as Slice Ptr
 
 SliceLoadFromFile(menuslice, finddatafile("choose_rpg.slice"))
 SetSliceParent(menuslice,root)
 
 DO
  setwait 1
  setkeys YES
  
  IF keyval(scESC) > 1 THEN EXIT DO

  DrawSlice root, dpage

  SWAP vpage, dpage
  setvispage vpage
  
  clearpage dpage
  
  dowait
 LOOP
 
 ' TEST
 frame_unload @myframe
 ' / TEST
 
 DeleteSlice @root
 
END SUB
("choose_rpg.slice" and "Folder.bmp" are located tin the "data" directory)
Attachments
Screenshot of the Slice Collection
Screenshot of the Slice Collection
slice_screenshot.bmp (63.55 KiB) Viewed 2081 times
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

Well, this looks promising!

frame_import_bmp24_or_32 can only be called on 24 or 32 bit bmps, and frame_import_bmp_raw can only be called on 1-8 bit bmps. But you don't need to worry about that any more, as I added frame_import_bmp_as_8bit, which loads any bmp and maps it to the master palette (fixing your problem with garbage colours too).

I created those two files and tried your code. The bug was that

Code: Select all

 SliceLoadFromFile(menuslice, finddatafile("choose_rpg.slice"))
 SetSliceParent(menuslice,root)
should be

Code: Select all

 menuslice = NewSliceOfType(slContainer, root)
 SliceLoadFromFile(menuslice, finddatafile("choose_rpg.slice"))
The way that SliceLoadFromFile works is just crazy. I actually have a git branch (loadslice, sitting on bitbucket) where I changed SliceLoadFromFile to do the sensible thing and return a new slice, but I never checked it in and I can't remember why. Maybe it's buggy or not finished.

The way I worked out what was going on was by adding the line:
IF keyval(scF6) > 1 THEN slice_editor root
Pressing F6 showed me that the collection wasn't loaded, and a message in c_debug.txt showed, indirectly, that SliceLoadFromFile was getting passed a null pointer.

Also, doing

Code: Select all

   .Width = gen(genResolutionX)
   .Height = gen(genResolutionY)
Isn't right. As I mentioned before, those are the in-game resolution, not the current screen size (which is get_resolution().x and get_resolution().y). And they are 0 before a game is loaded. And anyway, you don't need to set the width and height, just setting .Fill = YES on the root slice is enough, as that causes it to fill the screen (if a slice has no parent, the screen acts as the parent).

You don't need a separate root slice, rather than use the loaded slice collection as a root, unless you have another use for it... which I have a feeling is your intention.

Finally, don't call frame_unload on the Frame you loaded; the slice takes ownership and deletes it. (Frames are refcounted, so you can keep an additional reference if necessary)

I just added 'asset sprite slices', which are loaded from the data directory automatically. However, I haven't finished the slice editor interface to create them yet. I'm sure I'll get it done tomorrow though. That'll allow simplifying your code further. (You can create them with code, but that saves nothing). It's nice that we're both working on slice-based menus at the same time!
Last edited by TMC on Tue Apr 18, 2017 2:36 pm, edited 5 times in total.
Wendigo
Red Slime
Posts: 52
Joined: Tue Feb 28, 2017 1:15 pm

Post by Wendigo »

Thank you very much for you support, I got the slice collection working now.
But the border of the Rectancle Slice is drawn as a dark 1px line instead of the white border as shown in my previous screen shot. Would I have to load the border tiles separately or could I access the standard ones somehow?

You mentioned that I have to remove some line in order to be able to add negative values for lookup codes in the slice collection editor. But I can't find that posting anymore. Where would I have to edit the code and which numbers would be available for use?

When the "asset sprite slice" is ready I'll add some simple slice widgets.

I have added a sub for showing websites in the default browser. But could only test it on Linux. Have no idea how this is done on Android.
I didn't know in which source file to put it so I decided to just post it here:

Code: Select all

SUB show_link_in_browser(byval link as string)

 IF (NOT LCASE(LEFT(link,8)) = "https://") AND _
    (NOT LCASE(LEFT(link,7)) = "http://") THEN
  link = "http://" & link
 END IF

 #IFDEF __FB_LINUX__ '(Linux)
  SHELL("xdg-open " & link)
 #ENDIF

 #IFDEF __FB_WIN32__ '(Windows)
  SHELL("start " & link)
 #ENDIF

 #IFDEF __FB_DARWIN__ '(MAC OSX)
  SHELL("open " & link)
 #ENDIF

END SUB
I could also add HS bindings so people could add links to their websites in their games.

By the way, someone at the German Free Basic Portal has posted a tutorial on creating an event driven GUI here.
Do you think this would be something we could use in the ohrrpgce?

Until now I have just made changes to the code and run scons that showed me the line if a syntax error occured. What would I have to do if I wanted to use gdb or integrate it into geany (I have found an addon for that but don't know how to configure it.)

@James:
I haven't heard your opinion on my proposal for the slice based GUI yet. Since you are doing the conversion to slice based menus I'd like to know what you think about it. And if you like it how we could coordinate the further development.
Last edited by Wendigo on Wed Apr 19, 2017 10:58 am, edited 1 time in total.
User avatar
Bob the Hamster
Lord of the Slimes
Posts: 7658
Joined: Tue Oct 16, 2007 2:34 pm
Location: Hamster Republic (Ontario Enclave)
Contact:

Post by Bob the Hamster »

I replied about the slice gui proposal in the other thread-- probably should have replied here, that other thread is too busy! ;)

Short answer, I like what you are doing, as long as we don't lose keyboard functionality, and don't go crazy with icons. Menus are still fine for most things.

My slice plan was all about converting the built-in special screens in game, it had nothing to do with converting custom to slices. (I have occasionally switched custom's menus to slices as part of re-writing them for other reasons, but I didn't have an organized overall plan for that like I did for the in-game special screens)

EDIT: actually, just deleted the comment from the other thread, and re-pasting it here:
me in the other thread wrote:That looks cool!

Very ambitious.

I am very wary of making everything icon-based. Text menus take more space, but all you have to do is read them, you don't have to learn new symbols. The icons in your example are clear enough, but if you stick with icons for the whole theme, some of them are going to get pretty cryptic. You can see this problem in the screenshots tmc posted from the old jormungand project.

Also, I love the first-class mouse support. That is something we have been lacking for way to long-- but also keyboard controls for everything is vital. It looks like you are already thinking of this with the shortcuts.

You mentioned how after a while people just memorize that the menu they want is enter-down-down without reading, but that muscle memory is super important to existing users of the engine. If the layout changes too much all at once, we risk losing *existing* users of the engine. I don't mention this to discourage you, because I love what you are doing. Please continue! Just making you aware of some concerns :)
Last edited by Bob the Hamster on Wed Apr 19, 2017 2:21 pm, edited 2 times in total.
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

OK, I just committed a change to make Game and Custom use the default box border sprites before any game is loaded.
However, if you want to override the game's box border sprites to ensure a consistent look, or even to use special 'window frame' borders, currently there's no way to do that. Hmm, in fact I didn't even think about it until right now, but we definitely want that. I guess we need to add some special boxborder codes understood by edgebox().

Heh, we already have a function to open a URL, it's called open_url. It seems you weren't expecting that :) I haven't implemented it on Android yet; it's a nuisance to write all the glue code for it. (BTW, never use __FB_LINUX__ ... I should fix that gotcha)
A script command to open a URL is actually on my todo list (it was, however, specifically requested for use on Android, since there are no readme files there). I think it should show the player an in-game prompt to confirm they want to open the URL.
You mentioned that I have to remove some line in order to be able to add negative values for lookup codes in the slice collection editor. But I can't find that posting anymore. Where would I have to edit the code and which numbers would be available for use?
Change sliceedit.bas:1080 from
sliceed_rule rules(), "lookup", erIntgrabber, @.Lookup, 0, UBOUND(ses.slicelookup), slgrPICKLOOKUP
to
sliceed_rule rules(), "lookup", erIntgrabber, @.Lookup, -999999, UBOUND(ses.slicelookup), slgrPICKLOOKUP
You will have to type in the values.
Use negative values. Maybe values from -100 downwards. I decided that we should have a slicelookup.txt file in data/ for editor lookup codes, just like .rpgs contain a slicelookup.txt. That way we can use the regular lookup code 'editor' to name the lookup codes, and I could easily autogenerate a header with constants from it.
What would I have to do if I wanted to use gdb or integrate it into geany (I have found an addon for that but don't know how to configure it.)
To run under gdb, either run "gdb ./ohrrpgce-custom", or run "./gdbcustom.sh", which is more useful because it halts if FB detects an error. I recently wrote a section on the wiki about this.
I've never used geany. What do you want to integrate, a key to run scons?

I think that OO and specifically event driven programming would be very useful for GUIs. (Feel free to use classes and polymorphism in your code.) That tutorial uses threads and mutexes, which seems pretty unnecessary, however if we want to allow running existing editors side-by-side we're going to need to use threads or fibres.

So much for getting the slice editor support for asset sprites done today. I looked into using plank menus instead. They will be useful for tiled icons/menu items, because they handle the logic for keyboard movement between arbitrarily placed slices. However right now they're not available in Custom, and are a bit tedious to create anyway.
Last edited by TMC on Wed Apr 19, 2017 3:34 pm, edited 3 times in total.
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

I'm confused about why it sometimes worked before, but box borders generally displayed black (with no palette) before a game was loaded. I've fixed it now.

I finally added the ability to create asset sprite slices in the slice editor. Go to the spam menu and select "Editor Slice Editor". Right now the only differences are being able to create them, and being able to type negative lookup codes (no negative lookup code editor yet). Create a sprite slice and change its sprite type.

However, I've just realised that rect slice and text slice colours use master palette indices, which is bad because the master palette is unpredictable. (This is very similar to the problem of box borders and styles differing by game). I guess that we should store RGB triples in .slice files instead, and map to nearest when loading. (However it's not 100% safe to do this always, since the game might have multiple master palettes, and if a slice collection was created for a different master palette the colours would change if you browsed through all your collections, which loads and resaves them). We can just add an argument to SliceLoadFromFile though.

Also, someone requested the ability to use UI colours in slices, which is something I have half finished, I should commit that. It'll be a partial fix.
Actually, an even better fix would be define new UI colours (and box styles) just for Custom, and store them in an external file. Then you could reskin Custom by changing those UI colours instead of changing each slice-based-menu's .slice file.

We should write some utility code for clicking on slices, tooltips, hovering, etc. for slice-based menus.
Last edited by TMC on Fri Apr 21, 2017 2:37 pm, edited 1 time in total.
Wendigo
Red Slime
Posts: 52
Joined: Tue Feb 28, 2017 1:15 pm

Post by Wendigo »

I have tried the "Editor Slice Collection" but the application crashes with a runtime error when reaching the new option in "Sprite Type".

Code: Select all

Aborting due to runtime error 6 (out of bounds array access) at line 1040 of sliceedit.bas::SLICE_EDIT_DETAIL_KEYS()
I couldn't test it yet, will I be able to set a filename for the image in the "data" folder or does it just create a number?

I have been experimenting with the event driven GUI but there seems to be a problem with the linking. When I put everything in one bas file it works but after I spread the code into the new files "slgui.bas" and "slgui.bi" I get an error in the compiler:

Code: Select all

build/custom.o: In function `SLGUI_TEST':
/home/xxx/Dokumente/ohrrpgce_myfork/ohrrpgce-svn/custom.bas:647: undefined reference to `EVENTTYPE::WINDOWCREATE(int, int, void (*)())'
/home/xxx/Dokumente/ohrrpgce_myfork/ohrrpgce-svn/custom.bas:648: undefined reference to `EVENTTYPE::BUTTONCREATE(int, int, int, int, void (*)())'
/home/xxx/Dokumente/ohrrpgce_myfork/ohrrpgce-svn/custom.bas:649: undefined reference to `EVENTTYPE::BUTTONCREATE(int, int, int, int, void (*)())'
collect2: error: ld returned 1 exit status
scons: *** [ohrrpgce-custom] Error 1
scons: building terminated because of errors.
I have put the types (used the tutorial code for experimenting) into "slgui.bi", the implementation functions into "slgui.bas" and the instantiation + declaration of WindowClick, Button1/2Click together with an "#include "slgui.bi"" into "custom.bas".
Do I need to edit the scons script in order to add new source files?

Concerning the debugger plugin for geany, there is a known bug that prevents it from running. The bug is fixed in the repository of the current Linux Mint 18.x but not in my 17.3 and I don't want to compile the plugin myself.
(The plugin itself integrates GDB into geany so one can set breakpoints, step through the code or observe variables directly in the texteditor)
I'm now using "Nemiver" as a graphical frontend for GDB which works ok.

I'm also not sure how I should implement the new GUI at all.
Currently I took the same approach as the "spam" menu so by typing "eggs" (I don't like spam! ;) ) in the choose game menu brings up the new GUI.
Or do you think it woud be better so completely separate the new GUI in a different development branch? However this could lead to "Out of sight, out of mind" and result in another failed attempt to create a new GUI.

@James:
Don't worry, I have no intention to replace every menu point by an icon. I'll just do it where it is applicable and intend to either keep the "select_by_typing" functionality or add some other keyboard shortcuts for accessing options by keyboard.
But I still have no idea how to implement it. The menu and input code is glued together pretty well.
Last edited by Wendigo on Wed May 03, 2017 5:27 pm, edited 2 times in total.
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

Oh damn, sorry! I missed your post again. I really need to stop using that unreliable "New posts" page.

I'm not certain which commit you were using, but that line seems to be:

Code: Select all

WITH sprite_sizes(dat->spritetype)
I can't figure out why you get a crash here; it works for me. Could you try attaching gdb (or Nemiver, if that can support languages like FB it doesn't know about) or adding some print statements to see what is going on? What's dat->spritetype (or *dat, for that matter)? Is sprite_sizes corrupt? It's meant to have an LBOUND of -1. (Hint, if you use gdb, you will have to write "p *DAT" or "p DAT->SPRITETYPE" since FB symbols are capitalised unless they're in an 'EXTERN "C"' block. You can run ./gdbcustom.sh to get it to break on a "out of bounds array access" error message, but will have to go a couple frames up the call stack.)
Do I need to edit the scons script in order to add new source files?
Yes, add "slgui" to edit_modules.

So you adapted that tutorial to slices and tried building a GUI out of it? I'd be interested to have a look at that.
I think that the only way to design something like this is to test out your ideas in practice, build it up as you find more features you need, and repeatedly refactor it as you think of better ways of doing it.
Or do you think it woud be better so completely separate the new GUI in a different development branch? However this could lead to "Out of sight, out of mind" and result in another failed attempt to create a new GUI.
I'm not sure whether you're talking about the general slgui code, or a new GUI interface for the initial menu specifically. But either way, if it's experimental and optional, but likely to be used in future, it can definitely be merged into the SVN repo sooner rather than later. Then it can be improved upon, and in the case of code I can make use of it too!
In some special cases, like the main menu of custom, it could even make sense to have two versions, such as icon based as a drop-down toolbar, or maybe even classic and new which people can select between with an option.

Regarding select_by_typing, I'm not sure whether to try to implement it everywhere, or switch to unique shortcut keys as is more common, with one of the letters of each menu item name highlighted, so that each menu item has a distinct letter. Well, I guess we could support both at once!

Yes, unfortunately the logic of each menu is totally locked together with the presentation and input. Often I have to half-rewrite a menu just to change the order of the menu items! It's dreadful. If we had some better framework for creating menus, existing menus will just need to be upgraded one-by-one as needed. (We should make it as easy as possible to do so, because there are a lot of menus!)
Last edited by TMC on Thu May 11, 2017 3:32 pm, edited 2 times in total.
Wendigo
Red Slime
Posts: 52
Joined: Tue Feb 28, 2017 1:15 pm

Post by Wendigo »

The value of dat->spritetype jumps from 9 (backdrop) to 4294967295 (asset) same if I cycle backwards (0->4294967295). I'm doing a 64 bit build, maybe that's the culprit.

I have added slgui to Sconscript and it compiles now, thanks.
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

Oh! You're right, this is a 64 bit bug. And it wasn't just asset sprites; a lot of other menu options in the slice editor were potentially broken too! I've committed a fix. It was because in FB, enums are 64 bit when targetting a 64 bit arch, which is very annoying. It's the only way that I can think of in which FB is not compatible with C.

Also, I forgot how annoying gdb is to use with 64 bit FB builds, because the variable names all have an unpredictable suffix starting with $ appended, and the $ also causes problems with autocomplete.
Tomorrow I'll fix the extremely long 64 bit compile times for sliceedit.bas; that's the reason I don't test it very often.

BTW, I also experimented with adding a logo to the initial menu to see how it would look, but didn't commit it to avoid clashing with your work. I'm not sure about the background colour. Unfortunately since the logo has an antialiased outline it's specific to a certain background colour..
Attachments
title.png
title.png (4.77 KiB) Viewed 1973 times
Post Reply