Reading joystick / keys

  • Thread starter Thread starter MartinW
  • Start date Start date
  • Replies Replies 12
  • Views Views 3814

MartinW

New member
Joined
Feb 17, 2010
Posts
409
Country
UK
Region
West Somerset
OK, making good progress now but I have a question...

I've been using the "battle zone" type example in Amiga Format C tutorial where they draw directly to a custom screen, bypassing the OS as it suits my needs fine for the hacking I want to do.

After a bit of head scratching I managed to rework the example to work with a double-buffered, custom Multiscan screen and it seems OK. All movement seems to leave a trail and I don't know yet if that's my code, the VGA screen or my monitor but I don't really care for the moment.

So, in their example they have a bit of code that hits the CIA directly to read the state of the joystick like so:

Code:
int joystick()
{
	// Scan the joystick and
	// Return a code value
	
	int code=0;

	UWORD dir,fire;

	dir = custom.joy1dat;
	fire = !( cia->ciapra & 0x0080 );

	if (fire) code=1;
	if (dir&2) 					code+=2;  // Right
	if (dir&512) 				code+=4;  // Left
	if ((dir >> 1 ^ dir)& 1)	code+=8;  // Down
	if ((dir >> 1 ^ dir)& 256)	code+=16; // Up

	return code;
}

Any idea where they are getting the values, like 0x0080 from? I've looked in custom.h and via.h and I can't really see anything obvious unless I'm looking in the wrong place.

The code there is OK but it's a button short for me. They exit the program when fire is pressed. I want to use fire in my code so I need some other way to exit the program. Ideally a key, but all the key handling code I see is through intuition messages and as I'm not using a Window, I'm just hitting a custom bitmap directly on the screen, I've not got anywhere to register for the intuition messages that would allow me to use the keyboard as OpenScreenTagList doesn't accept IDCMP event registration.

Or am I barking up the wrong tree here and missing something obvious??
 
You need to look in the Hardware manual for the values for the Joystick/Mouse.

I've got an address for the keyboard as well but can't remember what it is. I can have a look tonight.

As for leaving a trial - are you clearing the screen between screen swaps?
 
Thanks - I'll look more into the Hardware Reference next week as I'll be in hotels all week so will have more time. From an initial glance, I can see the obvious stuff like they use in the magazine article but there's obviously more to it for the other joystick buttons or direct keyboard access as it gets a bit more in-depth than a quick glance is going to give me :lol:

Regarding clearing the screen - yes, I believe so.

From memory I'm doing (and slightly, pseudo code):

Code:
loop...

    swap Bitmaps (myscreen->Rastport.BitMap=BitMapA or BitMapB)
    (also myscreen->ViewPort.RasInfo->Bitmap)

    SetRast(rastport, 0); // This erases??

    DoStuff, inc. Draw commands

    MakeScreen(myscreen);
    RethinkDisplay();
end loop

I have the swap stuff in a separate function to make the main loop a bit cleaner. The bitmaps are globals and I think I could see the references swapping when I looked in debug mode but I confess I'll have to check again to be sure.

---------- Post added at 12:13 ---------- Previous post was at 12:06 ----------

Ah, just occurred to me I should qualify the statement "leaving a trail". I don't mean an indefinite trail which you would get if I were never clearing the rastport, I mean it's like a phosphor trail that you might get on a vector monitor. Or "blurry" if you like. Actually not a bad effect if I actually wanted it :lol:

The "battle zone" code example doesn't do it when I try it in FS-UAE, but I can't just transplant that to my real hardware to try since I only have a VGA monitor connected to that and the example program uses 15Khz.

The example uses the older "OpenScreen()" method with a NewScreen struct. From what I could see, there was no way to get a DeviceID into the NewScreen struct for using anything other than 15Khz so I converted my code to use the "newer" OpenScreenTagList but still employing the custom screen, custom bitmap, swapping / double buffer technique demonstrated in the magazine article.

Hopefully that all makes sense. My actual code is on the A4000 not my laptop so I can't cut / paste it and there's already a surprisingly large amount of it anyway :whistle:
 
My ChessboardPuzzle uses double buffering now. It didn't originally which was a right pain in the butt to add afterwards :double

See here for the old version. I've changed it a lot since then but I've got a bug I'm struggling to locate at the minute. Once I've sorted that I'll post the latest version on the original thread.

I'm stuck at work but I'll have a look tonight and compare my code with yours just to see if there is a difference.

Any chance of a photo to show the trail?
 
I don't think a photo will cut it because as soon as the object stops (in this case a single, simple rectangle) the trail catches up. A video might. I'll see what I can do later. And of course I'll have a read through that thread as well.

Thanks for the replies :)
 
Correct, I'm not killing the OS.

All the examples I've seen so far handle the keyboard by registering for intuition messages during creation of the Window. I'm not using a window I'm writing directly to the bitmap attached to the screens raster port and I couldn't see any tags to register for messages when opening the screen.

Open to suggestions on other ways though of course...
 
When you are in your hotel next week you may want to do a bit of reading.

There is a sticky thread here that contains a lot of links to useful sites.

I suggest you have a look at post #26 :thumbsup:
 
I've already grabbed a few books from Dave H's site to have a look at. Any one in particular stick out over the others?

From a complete novice point of view (to the Amiga, not to programming) it's a bit overwhelming and between the amount of early Amiga stuff (1.x) and the late stuff 3.9, 4 it can be difficult to gauge what to read and what not, I have to say.

But I'm more than happy to do the reading! (was quite pleased to have got this far in the first place to be fair).
 
Here's my screen flip routine.

Code:
[SIZE=3]
[SIZE=2]/* Main game loop starts here. */
 do /* Start the game. while (quit==false) */
 {
 if (which_screen==true)
 {
 myscreen->RastPort.BitMap=bitmapA;
 myscreen->ViewPort.RasInfo->BitMap=bitmapA;
 }
 else
 {
 myscreen->RastPort.BitMap=bitmapB;
 myscreen->ViewPort.RasInfo->BitMap=bitmapB;
 }
 rastport=&myscreen->RastPort;
 SetRast(rastport,green); /* Clear the screen to a Green background. */
 SetAPen(rastport,white); /* White writing on all text. */
 SetBPen(rastport,green); /* Green background on all screens. */[/SIZE][/SIZE]
[SIZE=3][SIZE=2]
 Code goes here
 
 MakeScreen(myscreen); /* Update the screen with the current display. */
 RethinkDisplay(); /* And show it. */
 which_screen=!which_screen; /* Flip display for next loop. */
 }
 while (quit==false); /* Continue playing until user selects quit the game. */
[/SIZE][/SIZE]
Which I guess is not a lot different to everybody elses :)

The C Manual by Anders Bjerin is also a good source.

I've attached his dirty keyboard routine.
 

Attachments

Thank you so much!

That's very quickly got my keyboard and joystick sorted. Have downloaded the PDFs to have a read. I'll see if I can capture the motion thing later :)

My code doesn't look any different to yours though with only one exception. I only assign "rastport = &myscreen->RastPort" once, outside of the main loop. But that's not the cause because the raster port never changes, just the assignments of the bitmaps within the raster port, and that IS done inside the game loop. I tried it anyway and it made no difference.

I need to resolve why Storm C just crashes on UAE for me, then I could try this on a different screen in case it's my monitor / resolution.

---------- Post added at 21:41 ---------- Previous post was at 20:34 ----------

I just had a thought. I wonder if my code would compile on MorphOS? It's very simple so I bet it would.

Gives me an excuse to try and find a monitor my Mac Mini / MorphOS combination works with when I get back :)
 
when you don't have a window, you can't use intuition to get input events.. you need to use some of the devices, like input.device, keyboard.device and gameport.device.. If you keep the os alive, and read the keyboard directly from hardware, I think you will upset the os..
 
input.device is the only system friendly method (when not using window and IDCMP) for keyboard input.

keyboard.device can't be used if input.device is already running.
 
Back
Top Bottom