Posts: 922
Threads: 15
Joined: Jun 2003
We could probably add a cmm-line switch to choose which library to use, i dunno.
While Angelo's lib is more compatible, Sterling's has high-res/color support, ppl could choose which to use, but i guess it would be too confusing for new users - plus one lib has no flip() for example, what would need a stub, and the other has no Arcs/PAINT/DRAW (i can't believe you coded that, Angelo :P), so that have to be sorted somehow.. also for Linux, Angelo's lib needs a driver yet.
To complicate things even more (meh), DrV is doing a DOS port of FreeBASIC (using DjGPP), and with Angelo's lib it would be easier to add a new driver (VGA only), as there's no SDL for DOS -- but if adding high-res/color support, the DOS port will become really complex.. anyway.
Sterling had to work hard to make the library and yeah, he was under pressure to get it done fast ;). Simply exchanging his lib now wouldn't be too fair with him, i really don't know what to do.. well, you guys are both members, you can get along, don't leave it to me to decide :P.
Posts: 1,688
Threads: 119
Joined: Jun 2003
make a sort of build... a person can sorta customize their fbc. sort what keywords to add, which gfx lib to use and a person could have a customized fbc.
Freebasic for Dos?!?! Yee gads, you're taking steps backwards here! j/k. That'd be pretty cool, actually. look forward to it.
Jumping Jahoolipers!
Posts: 3,288
Threads: 167
Joined: Nov 2001
v1c:why not a little directive like:
$GFXlib= Sterling
or
@GFXlib =Angelo
Or better still, they could talk and make a kickass lib. Like if the user would use 8BPP, then use lillo's otherwise use Ster's.
Posts: 268
Threads: 9
Joined: Dec 2004
retsyo, PAINT supports patterns and you pass them via a 64 characters string. The internal gfxlib PAINT function requires all possible arguments of PAINT, including this string. Once the compiler know about this, you'll be able to work as with QB, but for now, you have to call it like
Code: paint 120, 70, 2, 15, ""
if you want a normal filled PAINT behaviour with no patterns. For patterns, just call
Code: paint 120, 70, 2, 15, mypatternstring$, 1
V1ctor, I understand your doubts. By my side, I still don't know if it's worth for the standard gfxlib to support hires/hicolor... The gfxlib purpose is backwards compatibility to ease the users transition from QB to FB, isn't it? For real world graphics an user should use a real world gfx library IMHO... But then I also understand a lot of noobs jump in and say "why doesn't the default lib support hires/hicolor? This sux!"
One of the goals of my gfxlib was compactness; supporting hires isn't really a problem at all (just a matter of a couple of lines to change), but for hicolor things get harder: internally the lib always uses just 8bit buffers to be fast... Supporting *all* possible color depths internally is out of question as it'd just bloat the lib and make it slower (think VTABLEs for things like putpixel) and I don't want this. I'd need either to internally support both 8bit buffers (for QB emulated modes) and 32bit buffers (for other modes), either just switch the lib to internally always use 32bit buffers. The former has the advantage that it'll be fast expecially on slow machines, but the lib will be a bit bloated to support both depths internally. The latter has the advantage to be easy to code over the current system, and it'll also not bloat the lib, but has the disadvantage that expecially in hires modes it'll be somewhat slow has it has to move 4 times the data around, and this could be bad for old machines (but hey, we're probably still talking more than 100000 primitives per second)
The latter solution seems the best to me. What do you think? Is it this all really worth the trouble?
Posts: 780
Threads: 49
Joined: Dec 2001
Few things:
Firstly, SC, I congratulate you on your Herculean effort, you got QBGFX done real quick, and were always there to answer any questions or queries I had.
Angelo, excellent job. I am very impressed . While SC did a good job, I wasn't chuffed about the SDL dependancy.
As for writing it in C - who cares?
As for which to use - SC and Angelo, you two should get in touch and then collaborate on this library. Angelo has already mentioned that he has used SC's material - there is a lot you two would be able to learn from each other and share insight about.
Posts: 6,419
Threads: 74
Joined: Mar 2002
Awesome job.
Btw, you mentioned you are supporting QB modes 1,2,7,8,9... did you add support for pages and PCOPY?
You made FLIP unneeded... But it was so cool to draw everything and then make it visible. Does this replacement support any kind of double buffering or paging?
If you want to expand this, the thing that would make it rock (that's not supported in most QB libraries, shame ) is to add the ability to PUT a sprite inside another one, not just the screen (like in Allegro when you blit a bitmap inside another one).
Posts: 242
Threads: 29
Joined: Dec 2004
A little note of a general problem until I track down a more specific culprit...
Using the "original" sdl based graphics lib, I could compile some older QB programs, which would run (when added FLIP to code) but did not allow the keyboard control that worked in the QBasic-ran program (I understand the reason behind this problem).
Using the "new" directx based lib, I could compile but the program would very slowly begin building the background graphic screen and then just completely lock down before it ever finished and went into the main game loop.
(This was on old tetris type game)
ature has its way of warning a person away from danger: The distinct black and white coloration on a skunk, the chilling buzz of a rattlesanke, a redneck handing you his beer and saying "Watch this!"
Posts: 268
Threads: 9
Joined: Dec 2004
na_th_an: thanks. About your question, I could export to the user this set of functions which could suit your needs:
This would lock the framebuffer. No updates are done to the screen while the lock is held.
Function that returns a pointer to the video memory (actually this is just an internal memory buffer the gfxlib uses). You can safely read/write to this memory as long as you have previously called SCREENLOCK.
Unlocks the screen which was previously locked via SCREENLOCK. When you call this function, the screen gets instantly updated again automatically. You cannot touch again the memory buffer returned via SCREENPTR as long as you don't recall SCREENLOCK first.
About PUTing to other buffers, well, I think this is a bit out of the scope of a default FB GFX library... You could still use your own memory buffers, code your blitters and then blit to your buffers, then use the SCREENLOCK/UNLOCK/PTR interface above to blit your buffer to the screen.
steven_basic: could you send me the sources of your program so I can test it here?
Posts: 73
Threads: 6
Joined: Jan 2005
lillo, thank you for the reply and this lib. Now paint works, but it seems that something is buggy. Please check the file I put on my blog to see what I am saying. I donno how to debug this program. I am looking forword to an IDE that can help me step-tracing fbc program, just like what QB has supplied.
NOTE: I found this file on the internet, and the authour write his name on the picture.
http://blog.blogchina.com/upload/2005-01...824141.zip
ps. In case you need it, I use the following regular expression in ultraedit to port qb PAINT to fbc's
Code: search: paint (^([0-9]+^), ^([0-9]+^)), ^([0-9]+^), ^([0-9]+^)
replace by: PAINT ^1, ^2, ^3, ^4, ""
Posts: 242
Threads: 29
Joined: Dec 2004
Quote:steven_basic: could you send me the sources of your program so I can test it here?
It was the BRIX.BAS tetris clone. I added a "FLIP" and commented out the SOUNDs. Otherwise the code is untouched original QBasic. It does everything except keyboard control in the original FB graphics lib.
Code: DECLARE SUB checkField (fields() AS INTEGER, py%, points%, bonus%)
DECLARE SUB main ()
DECLARE SUB drawBox (x%, y%, col%)
DECLARE SUB buildField (fields() AS INTEGER)
DECLARE SUB freq (n1%, n2%, n3%)
DECLARE SUB putObject (fields() AS INTEGER, object() AS INTEGER, px%, py%, n%, rot%)
DECLARE SUB clearObject (fields() AS INTEGER, object() AS INTEGER, px%, py%, n%, rot%)
DECLARE SUB getObject (object() AS INTEGER)
DECLARE FUNCTION checkObject% (fields() AS INTEGER, object() AS INTEGER, px%, py%, n%, rot%)
' Brix.bas (Freeware by Philipp Lenssen 1997 - Jester@T-Online.de)
' Use left, right and down arrows for brick movement. Up arrow is
' for rotation. Press s for sound switch and esc to quit.
CONST false = 0, true = NOT false
TYPE brickType
x AS INTEGER
y AS INTEGER
sx AS INTEGER
sy AS INTEGER
n AS INTEGER
rot AS INTEGER
nrg AS INTEGER
END TYPE
RANDOMIZE TIMER
SCREEN 13
COLOR 7
main
END
bricks:
DATA 0,0,0,0
DATA 1,1,0,0
DATA 0,1,1,0
DATA 0,0,0,0
DATA 0,0,0,0
DATA 0,1,1,0
DATA 1,1,0,0
DATA 0,0,0,0
DATA 0,0,0,0
DATA 1,0,0,0
DATA 1,1,1,0
DATA 0,0,0,0
DATA 0,0,0,0
DATA 1,1,1,0
DATA 1,0,0,0
DATA 0,0,0,0
DATA 0,0,0,0
DATA 0,1,1,0
DATA 0,1,1,0
DATA 0,0,0,0
DATA 0,0,0,0
DATA 1,1,1,1
DATA 0,0,0,0
DATA 0,0,0,0
DATA 0,0,0,0
DATA 1,1,1,0
DATA 0,1,0,0
DATA 0,0,0,0
SUB buildField (fields() AS INTEGER)
FOR n% = 0 TO 500
PSET (RND * 320, RND * 200), 8 - RND * 1
NEXT
LOCATE 1, 1: PRINT "Points 0"
LOCATE 1, 33: PRINT "Level 0"
FOR x% = 0 TO UBOUND(fields, 1)
FOR y% = 0 TO UBOUND(fields, 2)
IF x% = 0 OR y% = 0 OR x% = UBOUND(fields, 1) OR y% = UBOUND(fields, 2) THEN
fields(x%, y%) = true
drawBox px% + x%, py% + y%, 9
ELSE
'fields(x%, y%) = false
drawBox px% + x%, py% + y%, 1
END IF
NEXT
NEXT
END SUB
SUB checkField (fields() AS INTEGER, py%, points%, bonus%)
FOR y% = py% TO py% + 3
IF y% >= UBOUND(fields, 2) THEN EXIT FOR
full% = true
FOR x% = 1 TO UBOUND(fields, 1) - 1
IF NOT fields(x%, y%) THEN
full% = false%
EXIT FOR '###
END IF
NEXT
IF full% = true THEN
lines% = lines% + 1
FOR ny% = y% TO 2 STEP -1
FOR nx% = 1 TO UBOUND(fields, 1) - 1
fields(nx%, ny%) = fields(nx%, ny% - 1)
IF fields(nx%, ny%) THEN
drawBox nx%, ny%, 11
ELSE
drawBox nx%, ny%, 1
END IF
NEXT
NEXT
END IF
NEXT
IF lines% > 0 THEN
freq 100, lines% * 500, 10
points% = points% + ((lines% ^ 2) * 10) * bonus%
LOCATE 1, 7: PRINT points%
ELSE
freq 800, 600, -50
END IF
END SUB
FUNCTION checkObject% (fields() AS INTEGER, object() AS INTEGER, px%, py%, n%, rot%)
checkObject% = true
FOR x% = 0 TO UBOUND(object, 3)
FOR y% = 0 TO UBOUND(object, 4)
IF object(n%, rot%, x%, y%) THEN
IF fields(px% + x%, py% + y%) THEN checkObject% = false
END IF
NEXT
NEXT
END FUNCTION
SUB clearObject (fields() AS INTEGER, object() AS INTEGER, px%, py%, n%, rot%)
FOR x% = 0 TO UBOUND(object, 3)
FOR y% = 0 TO UBOUND(object, 4)
IF object(n%, rot%, x%, y%) THEN
drawBox px% + x%, py% + y%, 1
fields(px% + x%, py% + y%) = false
END IF
NEXT
NEXT
END SUB
SUB drawBox (x%, y%, col%)
CONST fieldSize = 8 '6
LINE (100 + x% * fieldSize + 1, 10 + y% * fieldSize + 1)-STEP(fieldSize - 1, fieldSize - 1), col%, BF
END SUB
SUB freq (n1%, n2%, n3%)
STATIC sfx%
IF n1% = 0 THEN
sfx% = NOT sfx%
ELSEIF sfx% THEN
FOR n% = n1% TO n2% STEP n3%
' SOUND n%, .03
NEXT
END IF
END SUB
SUB getObject (object() AS INTEGER)
'RESTORE bricks '###
FOR n% = 0 TO UBOUND(object, 1)
FOR y% = 0 TO UBOUND(object, 4)
FOR x% = 0 TO UBOUND(object, 3)
READ d%
IF d% = 1 THEN
object(n%, 0, x%, y%) = true
ELSE
object(n%, 0, x%, y%) = false
END IF
FOR rot% = 1 TO 3
FOR px% = 0 TO UBOUND(object, 3)
FOR py% = 0 TO UBOUND(object, 4)
object(n%, rot%, px%, py%) = object(n%, rot% - 1, UBOUND(object, 4) - py%, px%)
NEXT
NEXT
NEXT
NEXT
NEXT
NEXT
END SUB
SUB main
DIM fields(11, 21) AS INTEGER ' 20,30
DIM object(6, 3, 3, 3) AS INTEGER
freq 0, 0, 0
getObject object()
buildField fields()
DIM brick AS brickType
brick.nrg = false
nextBrick% = INT(RND * UBOUND(object, 1) + 1)
DO
clock! = TIMER
IF NOT brick.nrg THEN
brick.x = UBOUND(fields, 1) \ 2
brick.y = 0
brick.sx = 0
brick.sy = 0
brick.rot = 0
brick.n = nextBrick%
nextBrick% = INT(RND * UBOUND(object, 1) + 1)
FOR nbx% = 0 TO UBOUND(object, 3)
FOR nby% = 0 TO UBOUND(object, 4)
drawBox 18 + nbx%, 2 + nby%, ABS(object(nextBrick%, 0, nbx%, nby%)) * 7
NEXT
NEXT
brick.nrg = true
putObject fields(), object(), brick.x, brick.y, brick.n, brick.rot
END IF
IF tick% = 10 - INT(level!) THEN
brick.sy = 1
tick% = 0
IF level! < 7 THEN level! = level! + .01
IF INT(level!) <> lastLevel% THEN
LOCATE 1, 38: PRINT INT(level!)
lastLevel% = INT(level!)
END IF
ELSE
tick% = tick% + 1
SELECT CASE INKEY$
CASE CHR$(0) + "K", "4": brick.sx = -1
CASE CHR$(0) + "M", "6": brick.sx = 1
CASE CHR$(0) + "H", "8": rotate% = true
CASE CHR$(0) + "P", "2": brick.sy = 1
CASE CHR$(27): END
CASE "s": freq 0, 0, 0
END SELECT
clearBuf$ = INKEY$
END IF
IF brick.sx <> 0 OR brick.sy <> 0 OR rotate% THEN
clearObject fields(), object(), brick.x, brick.y, brick.n, brick.rot
IF rotate% THEN
rotate% = false
IF (brick.x > 0 AND brick.x + UBOUND(object, 3) < UBOUND(fields, 1)) AND (brick.y > 1 AND brick.y + UBOUND(object, 4) < UBOUND(fields, 2) - 1) THEN
IF brick.rot < 3 THEN
brick.rot = brick.rot + 1
ELSE
brick.rot = 0
END IF
ELSEIF brick.y > 1 AND brick.sy = 0 THEN '###
IF brick.x > UBOUND(fields) \ 2 THEN
brick.sx = -1
ELSE
brick.sx = 1
END IF
END IF
END IF
IF checkObject%(fields(), object(), brick.x + brick.sx, brick.y + brick.sy, brick.n, brick.rot) THEN
brick.x = brick.x + brick.sx
brick.y = brick.y + brick.sy
putObject fields(), object(), brick.x, brick.y, brick.n, brick.rot
ELSE
IF NOT (brick.sx <> 0 AND brick.sy = 0) THEN
brick.nrg = false
putObject fields(), object(), brick.x, brick.y, brick.n, brick.rot
checkField fields(), brick.y, points%, INT(level!) + 1
IF brick.y <= 2 THEN gameOver% = true
ELSE
putObject fields(), object(), brick.x, brick.y, brick.n, brick.rot
END IF
END IF
brick.sx = 0
brick.sy = 0
END IF
DO UNTIL clock! + .001 - TIMER <= 0: LOOP
FLIP
LOOP UNTIL gameOver%
END SUB
SUB putObject (fields() AS INTEGER, object() AS INTEGER, px%, py%, n%, rot%)
FOR x% = 0 TO UBOUND(object, 3)
FOR y% = 0 TO UBOUND(object, 4)
IF object(n%, rot%, x%, y%) THEN
drawBox px% + x%, py% + y%, 11
fields(px% + x%, py% + y%) = true
END IF
NEXT
NEXT
END SUB
ature has its way of warning a person away from danger: The distinct black and white coloration on a skunk, the chilling buzz of a rattlesanke, a redneck handing you his beer and saying "Watch this!"
|