form_do and dialog box

C and PASCAL (or any other high-level languages) in here please

Moderators: simonsunnyboy, Mug UK, Zorro 2, Moderator Team

Post Reply
LuigiThirty
Atari maniac
Atari maniac
Posts: 97
Joined: Sat Sep 03, 2016 12:20 am

form_do and dialog box

Post by LuigiThirty »

I'm trying to display a dialog box with form_do in a game. The dialog box is going to be shown after I receive a keyboard event using evnt_multi. In my routine, I'm just doing:

Code: Select all

OBJECT *dialog;

rsrc_gaddr(R_OBJECT, DLG_MOVE, dialog);
form_do(dialog, 0);
However the desktop freezes when form_do is called and I have to reboot the ST. I checked in the debugger and dialog is being set properly by rsrc_gaddr. Is there more setup I need to do to display a dialog box?
User avatar
wongck
Ultimate Atarian
Ultimate Atarian
Posts: 12928
Joined: Sat May 03, 2008 2:09 pm
Location: Far East
Contact:

Re: form_do and dialog box

Post by wongck »

Not sure what you're doing by the few lines of code you shown.
Don't think it hanged.
You just need to click on the OK button (if you have one), but in your case the dialogbox probably not drawn.
So if you have a default OK with properties of Exit, pressing RETURN will probably continue the program.
My Stuff: FB/Falcon CT63 CTPCI ATI RTL8139 USB 512MB 30GB HDD CF HxC_SD/ TT030 68882 4+32MB 520MB Nova/ 520STFM 4MB Tos206 SCSI
Shared SCSI Bus:ScsiLink ethernet, 9GB HDD,SD-reader @ http://phsw.atari.org
My Atari stuff for sale - click here for list
ThorstenOtto
Atari God
Atari God
Posts: 1190
Joined: Sun Aug 03, 2014 5:54 pm

Re: form_do and dialog box

Post by ThorstenOtto »

LuigiThirty wrote: rsrc_gaddr(R_OBJECT, DLG_MOVE, dialog);
That should be

Code: Select all

rsrc_gaddr(R_TREE, DLG_MOVE, &dialog);
(assuming that DLG_MOVE is the id of the TREE, not the id of some object)
simonsunnyboy
Moderator
Moderator
Posts: 5235
Joined: Wed Oct 23, 2002 4:36 pm
Location: Friedrichshafen, Germany
Contact:

Re: form_do and dialog box

Post by simonsunnyboy »

ThorstenOtto wrote:
LuigiThirty wrote: rsrc_gaddr(R_OBJECT, DLG_MOVE, dialog);
That should be

Code: Select all

rsrc_gaddr(R_TREE, DLG_MOVE, &dialog);
(assuming that DLG_MOVE is the id of the TREE, not the id of some object)
Then "OBJECT dialog" instead of "OBJECT * dialog" - or you are passing the address of an address?
Or is the latter intentional?
Simon Sunnyboy/Paradize - http://paradize.atari.org/

Stay cool, stay Atari!

1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee
ThorstenOtto
Atari God
Atari God
Posts: 1190
Joined: Sun Aug 03, 2014 5:54 pm

Re: form_do and dialog box

Post by ThorstenOtto »

simonsunnyboy wrote:Then "OBJECT dialog" instead of "OBJECT * dialog" - or you are passing the address of an address?
Or is the latter intentional?
Yes, of course you are passing the address of an address. rsrc_gaddr only returns addresses, it does not copy anything, so you have to pass the address where the address should be stored.
LuigiThirty
Atari maniac
Atari maniac
Posts: 97
Joined: Sat Sep 03, 2016 12:20 am

Re: form_do and dialog box

Post by LuigiThirty »

ThorstenOtto wrote:
LuigiThirty wrote: rsrc_gaddr(R_OBJECT, DLG_MOVE, dialog);
That should be

Code: Select all

rsrc_gaddr(R_TREE, DLG_MOVE, &dialog);
(assuming that DLG_MOVE is the id of the TREE, not the id of some object)
OK, now I have the dialog box becoming active but not being drawn. My dialog box contains an input box that's active and I can type in it, but the dialog box isn't being drawn. It should be drawn on top of a window. My whole routine is:

Code: Select all

void process_game_turn(Command command)
{
	OBJECT *dialog;
	
	/* Process a command from the prompt. */
	switch(command)
	{
		case COMMAND_MOVE:
		rsrc_gaddr(R_TREE, DLG_MOVE, &dialog);
		form_dial(FMD_START, 150, 100, 4, 4, 150, 100, 400, 96);
		form_dial(FMD_GROW, 150, 100, 4, 4, 150, 100, 400, 96);
		objc_draw(dialog, 0, 1, 150, 100, 400, 96);
		form_do(dialog, 0);
		form_dial(FMD_SHRINK, 150, 100, 4, 4, 150, 100, 400, 96);
		form_dial(FMD_FINISH, 150, 100, 4, 4, 150, 100, 400, 96);	
		break;
	}
}
User avatar
wongck
Ultimate Atarian
Ultimate Atarian
Posts: 12928
Joined: Sat May 03, 2008 2:09 pm
Location: Far East
Contact:

Re: form_do and dialog box

Post by wongck »

Try making the object depth to 8 in objc_draw.
My Stuff: FB/Falcon CT63 CTPCI ATI RTL8139 USB 512MB 30GB HDD CF HxC_SD/ TT030 68882 4+32MB 520MB Nova/ 520STFM 4MB Tos206 SCSI
Shared SCSI Bus:ScsiLink ethernet, 9GB HDD,SD-reader @ http://phsw.atari.org
My Atari stuff for sale - click here for list
ThorstenOtto
Atari God
Atari God
Posts: 1190
Joined: Sun Aug 03, 2014 5:54 pm

Re: form_do and dialog box

Post by ThorstenOtto »

LuigiThirty wrote:OK, now I have the dialog box becoming active but not being drawn. My dialog box contains an input box that's active and I can type in it, but the dialog box isn't being drawn. It should be drawn on top of a window. My whole routine is:
I guess that is because the dialog is not positioned at the coordinates you pass to objc_draw(). The coordinates there are only the clipping rectangle, if it is positioned elsewhere, it will be just clipped away. Also it is not advisable to use hardcorded coordinates, you should better take the values from the dialog itself. A simple routine might look like this:

Code: Select all

static OBJECT *rs_tree(int num)
{
	OBJECT *tree = NULL;
	rsrc_gaddr(R_TREE, num, &tree);
	return tree;
}

static int do_dialog(int num, int screenx, int screeny)
{
	OBJECT *tree = rs_tree(num);
	int x, y, w, h;
	int ret;

	wind_update(BEG_UPDATE);
	form_center(tree, &x, &y, &w, &h);
	if (screenx != 0 && screeny != 0)
	{
		int dx = tree[ROOT].ob_x - x;
		int dy = tree[ROOT].ob_y - y;
		tree[ROOT].ob_x = screenx;
		tree[ROOT].ob_y = screeny;
		x = screenx - dx;
		y = screeny - dy;
	}
	form_dial(FMD_START, x, y, w, h, x, y, w, h);
	objc_draw(tree, ROOT, MAX_DEPTH, x, y, w, h);
	ret = form_do(tree, ROOT);
	ret &= 0x7fff;
	tree[ret].ob_state &= ~SELECTED;
	form_dial(FMD_FINISH, x, y, w, h, x, y, w, h);
	wind_update(END_UPDATE);
	return ret;
}
Some notes:
  • If you are calling wind_update() already in your main loop, you should remove the calls here. They are not recursive calls like v_show_c (at least not in SingleTOS, and also not in some other multitasking OS).
  • if you don't want to have the dialog being centered on the screen, but control where it appears, you should still call form_center(), because that's the easiest way to take into account the extra space that is needed for the outside borders etc. In the sample code, that is done by passing the coordinates screenx & screeny, if they are zero, the dialog will be centered. If you always draw your dialogs centered, you can omit that extra code.
  • I've used "int" for all the variables, because i compiled it with Pure-C and its GEM library. If you are using GNU-C, or the gemlib from the freemint project, those must be "short" instead.
  • You have to deselect the object that was clicked when the dialog finishes, AES does not do that for you. Otherwise, the next time you draw the dialog again, it will already be in SELECTED state.
  • Depending on how complex the dialog is, you may not always want to terminate it when an object is clicked. You may want do put a loop around form_do() in that case, and only terminate it when things like OK, Cancel etc are clicked.
LuigiThirty
Atari maniac
Atari maniac
Posts: 97
Joined: Sat Sep 03, 2016 12:20 am

Re: form_do and dialog box

Post by LuigiThirty »

Thanks for the explanation.

All my dialogs will be displayed in the same place, centered on the X axis and 100px below the center on the Y axis, so that's perfect. I'm using Pure C and its libraries, so that's not a problem. I'm targeting bog standard TOS, not MiNT or anything.

Now if I could figure out why Pure C throws "call to function with no prototype" errors on functions with prototypes...
User avatar
mfro
Atari Super Hero
Atari Super Hero
Posts: 856
Joined: Thu Aug 02, 2012 10:33 am
Location: SW Germany

Re: form_do and dialog box

Post by mfro »

As Thorsten said.

There is one other thing he didn't mention (and many coders forgot as well): form_do() returns the index of the exit object of the dialog which was used to dismiss it. If your user decides to double click on the exit object on exit, the return value will have the high bit set additionally.

Thus, there is a potential pitfall with the following straightforward code:

Code: Select all

exitobj = form_do(...)
dialog[exitobj].ob_flags &= ~SELECTED;
You can have some fun double clicking on exit objects in many (namely very early) - public domain and commercial - applications...

[just saw Thorsten has it right in his code, but didn't explain it]
ThorstenOtto
Atari God
Atari God
Posts: 1190
Joined: Sun Aug 03, 2014 5:54 pm

Re: form_do and dialog box

Post by ThorstenOtto »

mfro wrote:There is one other thing he didn't mention (and many coders forgot as well): form_do() returns the index of the exit object of the dialog which was used to dismiss it. If your user decides to double click on the exit object on exit, the return value will have the high bit set additionally.
Look at the code i posted ;) This was already taken into account. Only problem there: the bit indicating double-click is also stripped from the code the function returns, so you need to change that if you need the information.
You can have some fun double clicking on exit objects in many (namely very early) - public domain and commercial - applications...
Thats not entirely true. Only objects with the TOUCHEXIT flag will behave this way, objects with EXIT flag don't react on double-clicks (or at least, they don't report it with the high-bit set).
Post Reply

Return to “C / PASCAL etc.”