Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Feb 11, 2014 6:47:54 GMT 1
I updated the libbbc5 library with Charles Pegge's (OxygenBasic author) BBC_SHIFT (right/left bit | math right) and BBC_ROTATE which C doesn't do by default with an operator. I also changed BBC_WAITKEY so it no longer forces an exit of the SDL window and returns to the user program. I used Charles's BBC_SHIFT to replace the C << left shift operator for testing. t = BBC_SHIFT(BBC_RND(4) - 1, 6, 0);
vovchik - Can you put your mouse handling routes in a callable function so I can access X/Y position and which mouse button was pressed. Remember that BaCon (with the power of C) isn't always the client calling and it may be an interpreter. Passing back multiple arguments is the trick we need you to perform. I think you're right. Look at my ScriptBasic vs. C BASIC example. Another issue is BBC_PRINTF isn't working. It's not recognizing the variadic parameters. I thought I didn't have MAXSTRING declared in the header but that wasn't it.
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Feb 11, 2014 10:50:12 GMT 1
The solution is using the correct BBC_MODE value. Mode 31 is 16 color. (default assignment for BBC_OPEN) ScriptBasic clocked in at 4.1 seconds so it's good to know SB still has some peddle left. // C BASIC Polygon
#include <stdio.h> #include <math.h> #include <SDL.h> #include "libbbc5.h" #include "cbasic.h"
#define PI 3.14159265358979323846
MAIN BEGIN_FUNCTION DIM AS float64 angle, radius, x[10], y[10]; DIM AS int32 c, t, d, side, sides, xorigin, yorigin, i, l; DIM AS Uint32 t1, t2, t3; DIM AS char strbuff[15]; BBC_OPEN(); BBC_MODE(32); t1 = SDL_GetTicks(); SDL_WM_SetCaption("C BASIC BBC5 - polygon", 0); BBC_VDU(26); DEF_FOR (i = 1 TO i <= 1000 STEP INCR i) BEGIN_FOR xorigin = BBC_RND(1250); yorigin = BBC_RND(840); radius = BBC_RND(300) + 50; BBC_ORIGIN(xorigin, yorigin); sides = BBC_RND(8) + 2; BBC_MOVE(radius, 0); BBC_MOVE(10, 10); c = BBC_RND(64) - 1; t = BBC_SHIFT(BBC_RND(4) - 1, 6, 0); BBC_GCOL(0, c, t); DEF_FOR (side = 1 TO side <= sides STEP INCR side) BEGIN_FOR angle = (side -1) * 2 * PI / sides; x[side] = radius * cos(angle); y[side] = radius * sin(angle); BBC_MOVE(0, 0); BBC_PLOT(85, x[side], y[side]); NEXT BBC_MOVE(0, 0); BBC_PLOT(85, radius, 0); DO d = BBC_RND(64) - 1; WHILE ((d & 63) != (c & 6)); BBC_GCOL(0, d, t); DEF_FOR (side = 1 TO side <= sides STEP INCR side) BEGIN_FOR DEF_FOR (l = side TO l <= sides STEP INCR l) BEGIN_FOR BBC_MOVE(x[side], y[side]); BBC_DRAW(x[l], y[l]); NEXT NEXT NEXT t2 = SDL_GetTicks(); t3 = (t2 - t1) / 1000; sprintf(strbuff, "%d.4 Seconds.", t3); BBC_OFF(); BBC_VDUSTR(strbuff, 0); BBC_WAITKEY(); BBC_CLOSE(); RETURN_FUNCTION(0); END_FUNCTION
|
|
|
Post by vovchik on Feb 11, 2014 12:40:02 GMT 1
Dear John,
I added a mouse event function so that you can exit before the drawing ends by moving towards the bottom right or pressing the right mouse button....but do not yet flush the event buffer before polling. Anybody know how?
With kind regards, vovchik
' Polygon demo using BBC basic (brandy) lib with SDL calls ' added some mouse detection
' *********************** ' COMPILER DIRECTIVES ' ***********************
PRAGMA INCLUDE SDL.h PRAGMA OPTIONS -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT -DHAVE_OPENGL PRAGMA LDFLAGS SDL bbc5
' *********************** ' END COMPILER DIRECTIVES ' ***********************
' *********************** ' EXTERNAL FUNCTIONS ' ***********************
PROTO SDL_GL_SetAttribute ALIAS SDL_ATTRIBUTE PROTO BBC_VDU PROTO BBC_MODESTR PROTO BBC_GCOL PROTO BBC_PLOT PROTO BBC_MOVE PROTO BBC_DRAW PROTO BBC_ORIGIN PROTO BBC_OPEN PROTO BBC_CLOSE PROTO SDL_WM_SetCaption ALIAS SDL_WINTITLE PROTO BBC_WAITKEY PROTO BBC_GETKEY PROTO BBC_RND PROTO BBC_SHIFT PROTO BBC_ROTATE PROTO echo_on PROTO echo_off PROTO printf ALIAS PRINTF PROTO SDL_PollEvent BBC_EVENT
' *********************** ' END EXTERNAL FUNCTIONS ' ***********************
' *********************** ' INITIALIZATION ' ***********************
' define var types DECLARE angle, radius TYPE double DECLARE xorigin, yorigin, i, l TYPE int DECLARE c, t, d, side, sides TYPE int DECLARE x[10] TYPE double DECLARE y[10] TYPE double
' *********************** ' INITIALIZATION ' ***********************
' *********************** ' SUBS & FUNCTIONS ' ***********************
' ------------------ FUNCTION BBC_MOUSE(int choice) ' ------------------ LOCAL event TYPE SDL_Event SLEEP 5 event.button.button = -1 SDL_PollEvent(&event) SELECT choice CASE 0 IF event.type == SDL_MOUSEMOTION THEN PRINTF("Current mouse position is : %d \n", event.motion.x) RETURN event.motion.x END IF CASE 1 IF event.type == SDL_MOUSEMOTION THEN PRINTF("Current mouse position is : %d \n", event.motion.y) RETURN event.motion.y END IF CASE 2 IF event.button.button == SDL_BUTTON_LEFT THEN PRINT "LEFT BUTTON" RETURN 1 ELIF event.button.button == SDL_BUTTON_MIDDLE THEN PRINT "MIDDLE BUTTON" RETURN 2 ELIF event.button.button == SDL_BUTTON_RIGHT THEN PRINT "RIGHT BUTTON" RETURN 3 END IF END SELECT RETURN -1 END FUNCTION
' ------------------ SUB ANTIALIAS() ' ------------------ SDL_ATTRIBUTE(SDL_GL_MULTISAMPLEBUFFERS, 1) SDL_ATTRIBUTE(SDL_GL_MULTISAMPLESAMPLES, 4) END SUB
' ------------------ SUB DRAW() ' ------------------ ' draw polygons LOCAL mymouse TYPE int FOR i = 1 TO 1000 xorigin = BBC_RND(1250) yorigin = BBC_RND(840) radius = BBC_RND(300) + 50 BBC_ORIGIN(xorigin, yorigin) sides = BBC_RND(8) + 2 BBC_MOVE(radius, 0) BBC_MOVE(10, 10) c = BBC_RND(64) + 1 t = BBC_SHIFT(BBC_RND(4) - 1, 6, 0) BBC_GCOL(0, c, t) FOR side = 1 TO sides angle = (double)(((side - 1) * 2) * (PI / sides)) x[side] = (double)(radius * COS(angle)) y[side] = (double)(radius * SIN(angle)) BBC_MOVE(0, 0) BBC_PLOT(85, (int)x[side], (int)y[side]) NEXT side BBC_MOVE(0, 0) BBC_PLOT(85, (int)radius, 0) REPEAT d = BBC_RND(64) - 1 UNTIL (d & 63) <> (c & 6) BBC_GCOL(0, d, t) FOR side = 1 TO sides FOR l = side TO sides BBC_MOVE((int)x[side], (int)y[side]) BBC_DRAW((int)x[l], (int)y[l]) NEXT l NEXT side IF BBC_MOUSE(2) = 3 THEN PRINT "Right button clicked - program exit" BBC_CLOSE() END END IF IF BBC_MOUSE(0) > 400 AND BBC_MOUSE(1) > 400 THEN PRINT "Hotspot entered - program exit" BBC_CLOSE() END END IF NEXT i END SUB
' ------------------ SUB MK_GUI() ' ------------------ ' create SDL window BBC_OPEN() BBC_MODESTR(800, 600, 256, 0, 1, 1, -1) SDL_WM_SetCaption("C BASIC BBC5 - polygon", 0) BBC_VDU(26) ANTIALIAS() ' draw polygons DRAW() END SUB
' *********************** ' END SUBS & FUNCTIONS ' ***********************
' *********************** ' MAIN ' ***********************
' draw polygons MK_GUI() BBC_WAITKEY() BBC_CLOSE()
' *********************** ' END MAIN ' ***********************
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Feb 11, 2014 21:05:10 GMT 1
Joe, Would you have any time to help with the documentation effort with the libbbc5 BBC BASIC V graphics library? We need something folks can refer to if they have a BBC BASIC program that they would like to use BaCon or or any other language to run it. I got a start on it HERE but it's only an introduction of sorts. Please let me know soon as this is something that needs to get rolling if this interface is going to be of use to anyone. John
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Feb 11, 2014 22:55:17 GMT 1
I compiled the latest libbbc5.c on XP and then compiled the C BASIC version of the BBC polygon example.
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Feb 12, 2014 2:49:18 GMT 1
Here is the Android C BASIC version of the BBC5 polygon example. The BaCon version should compile on Android as well.
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Feb 12, 2014 5:40:29 GMT 1
vovchik,
I haven't heard anything from Alex or Joe about an easy to use sprite library for the BBC5 library so I'm going to assume they aren't interested in the BBC5 library. I'm going with my original plan and use Gordon's RTB sprite code for now. Once the sprites are added I'll put on my documentation hat and try to get something put together.
I'm still counting on you for a mouse function. It would be nice to have an event function that could handle both mouse and keyboard events. My SB (non-unicode) keyboard handler returns the key name as a string. It is prefixed with a + (key down) or a - (key up) followed by the key name. (ESC = 'escape') This makes it easy to write a keyboard handler in the host setting the state of modifier keys (shift / ctrl / alt) while process keystrokes. I'm not sure if something like this could also handle mouse events.
John
|
|
|
Post by bigbass on Feb 12, 2014 6:31:42 GMT 1
Hey John
I think that BBC code has a place here on BaCon we may also have some long time users of BBC come on board needing some middle ground to feel comfortable on and there is probably a lot of good code that could be ported
all of the working examples you guys posted here will get posted on the wiki as demo code
Joe
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Feb 12, 2014 7:00:43 GMT 1
Thanks Joe!
I agree that there are still plenty of casual weekend programmers out there that are looking for something like a QB / traditional BASIC to write utilities and games but on Linux. Your SDL efforts are cross platform which gives your project extra mileage.
If you see anything missing in the BBC5 library a BBC BASIC programmer would expect to be there, please let me know.
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Feb 13, 2014 0:13:27 GMT 1
I added BBC_MOUSE based on vovchik's routine.
#include <stdio.h> #include <math.h> #include <SDL.h> #include "libbbc5.h" #include "cbasic.h"
MAIN BEGIN_FUNCTION DIM AS int m, i; BBC_OPEN(); DEF_FOR (i = 1 TO i <= 3 STEP INCR i) BEGIN_FOR m = BBC_MOUSE(2); PRINT ("Button: = %i\n", m); m = BBC_MOUSE(0); PRINT ("X: = %i\n", m); m = BBC_MOUSE(1); PRINT ("Y: = %i\n", m); NEXT BBC_WAITKEY(); BBC_CLOSE(); RETURN_FUNCTION(0); END_FUNCTION
jrs@laptop:~/libbbc$ ./mouse Button: = 1 X: = 426 Y: = 8 Button: = 2 X: = 461 Y: = 164 Button: = 3 X: = 173 Y: = 362 jrs@laptop:~/libbbc$
Update
I'm in the process of adding a bit more functionality to the BBC_MOUSE and BBC_GETKEY functions. If a value of 4 is passed to the BBC_MOUSE function it waits for a mouse button to be pressed before returning to the caller. If a 3 is passed, it only a checks for a mouse button press and returns. The BBC_GETKEY will accept a 0 to check for a key and 1 will wait within SDL for a key to be pressed before returning. This gives the programmer the best of both worlds. Keep in mind the longer you let SDL perk without draining the event que, the more unstable it becomes. If you use a BBC_WAITKEY for example, SDL handles the que. I hope to have the new code posted soon.
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Feb 13, 2014 6:41:34 GMT 1
I think I have the BBC_MOUSE and BBC_GETKEY working in polling or wait mode for events.
BBC_MOUSE(0) - Waits for mouse movement and returns X position. BBC_MOUSE(1) - Waits for mouse movement and returns Y position. BBC_MOUSE(2) - Checks for a mouse button press event and returns. BBC_MOUSE(3) - Waits for a mouse button to be pressed then returns.
BBC_GETKEY(0) - Polls for a key press event and returns. BBC_GETKEY(1) - Waits for a key to be pressed then returns.
This really needs some testing and a good example program.
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Feb 13, 2014 9:59:08 GMT 1
I noticed that SDL doesn't return anything for function keys and other keys when using the UNICODE option. I'm going to add my keyboard handler from the SB SDL extension module that returns key names with up/down status. (returned as a string value) You can check out the thread on All BASIC if your interested. I will add a BBC_KEYNAME function tomorrow that will provide this functionality. It will follow the same rules as BBC_GETKEY.
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Feb 13, 2014 18:15:44 GMT 1
Anyone have a good example of a C function in a shared object (.so) creating and returning a string (pointer) back to the caller? I don't want to make the caller be responsible for freeing it if all possible.
|
|
Deleted
Deleted Member
Posts: 0
|
Post by Deleted on Feb 13, 2014 22:19:29 GMT 1
I tried creating a static global string buffer in the shared object and pass the pointer to the call. It almost works as I'm seeing the pointer to the string returned but not the data. Here is what the BBC_KEYNAME function looks like. FUNCTION char *BBC_KEYNAME(int choice) BEGIN_FUNCTION DIM AS int done, e; DIM AS SDL_Event event; done = 0; e = 1; DEF_WHILE (NOT done) BEGIN_WHILE DEF_WHILE (e) BEGIN_WHILE IF (choice EQ 0) THEN e = SDL_PollEvent(AT event); SDL_Delay(20); ELSE e = SDL_WaitEvent(AT event); END_IF SELECT_CASE (event.type) BEGIN_SELECT CASE SDL_KEYDOWN: strcpy (bbcbuf,"+"); strcat (bbcbuf,SDL_GetKeyName(event.key.keysym.sym)); RETURN_FUNCTION(bbcbuf); done = 1; END_CASE CASE SDL_KEYUP: strcpy (bbcbuf,"-"); strcat (bbcbuf,SDL_GetKeyName(event.key.keysym.sym)); RETURN_FUNCTION(bbcbuf); done = 1; END_CASE CASE SDL_QUIT: done = 1; SDL_Quit(); END_CASE CASE_ELSE RETURN_FUNCTION(0); END_CASE END_SELECT WEND WEND RETURN_FUNCTION(0); END_FUNCTION
This is the test program. #include <stdio.h> #include <SDL.h> #include "libbbc5.h" #include "cbasic.h"
MAIN BEGIN_FUNCTION DIM AS int m, i; DIM AS char *s;
BBC_OPEN(); m = 1; DO s = BBC_KEYNAME(1); PRINT ("%s\n", &s); WHILE (m EQ 1); BBC_CLOSE(); RETURN_FUNCTION(0); END_FUNCTION
|
|
|
Post by vovchik on Feb 13, 2014 23:16:36 GMT 1
Dear John, Try this in BaCon. It works for me... With kind regards, vovchik ' get key function
' *********************** ' COMPILER DIRECTIVES ' ***********************
PRAGMA INCLUDE SDL.h PRAGMA OPTIONS -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT -DHAVE_OPENGL PRAGMA LDFLAGS SDL bbc5
' *********************** ' END COMPILER DIRECTIVES ' ***********************
' *********************** ' EXTERNAL FUNCTIONS ' ***********************
PROTO BBC_OPEN PROTO BBC_CLOSE PROTO SDL_PollEvent BBC_EVENT PROTO SDL_Delay
' *********************** ' END EXTERNAL FUNCTIONS ' ***********************
' *********************** ' INITIALIZATION ' ***********************
DECLARE m TYPE int DECLARE s$ TYPE STRING
' *********************** ' END INITIALIZATION ' ***********************
' *********************** ' SUBS & FUNCTIONS ' ***********************
FUNCTION BBC_KEYNAME$(int choice) LOCAL done, e TYPE int LOCAL event TYPE SDL_Event LOCAL bbc_buffer$ TYPE STRING done = 0 e = 1 bbc_buffer$ = "" WHILE NOT(done) DO WHILE (e) DO IF choice = 0 THEN e = SDL_PollEvent(&event) SDL_Delay(20) ELSE e = SDL_WaitEvent(&event) END IF SELECT event.type CASE SDL_KEYDOWN bbc_buffer$ = "+" & SDL_GetKeyName(event.key.keysym.sym) RETURN bbc_buffer$ done = 1 CASE SDL_KEYUP bbc_buffer$ = "-" & SDL_GetKeyName(event.key.keysym.sym) RETURN bbc_buffer$ done = 1 CASE SDL_QUIT done = 1 m = FALSE RETURN "Let's get out of here..." DEFAULT bbc_buffer$ = "" END SELECT WEND WEND RETURN bbc_buffer$ END FUNCTION
' *********************** ' END SUBS & FUNCTIONS ' ***********************
' *********************** ' MAIN ' ***********************
BBC_OPEN() m = TRUE WHILE m DO s$ = BBC_KEYNAME$(1) PRINT s$ WEND BBC_CLOSE() END
' *********************** ' END MAIN ' ***********************
PS. Nice function. I like it.
|
|