Davvel Posted February 3, 2016 Author Share Posted February 3, 2016 I have a suggestion to whoever builds compilers such as the XGA99 and RAG etc.... If you enter an instruction followed by a question mark "?" it would give you an error and a brief description of what it expects with a small example. Example: CGT ? Will result in ..... Syntax error in GROM address 6020, correct syntax : GT GD,GS IF GD > GS then cond=1 else cond=0 In this way the compiler will expose what it expects irrespective of which manual says what. This avoids a lot of confusion and debates. Thanks. Quote Link to comment Share on other sites More sharing options...
Davvel Posted February 3, 2016 Author Share Posted February 3, 2016 (edited) GPL Program 7 In this example we build on my last demo PROG6G and introduce a small function which identifies which sprite we collided with. I am also making the Sprite pattern change according to the direction our main sprite is moving. I would like comments on both program execution and ideas on how the main code can be improved. * Sprite Collision logic below * * Keys:* A - S move left or right* P - L move up or down* = Exit HitSpr EQU >8306 Sprite we Hit - 8304 - 8305 (2 bytes are needed when value is used as an index)HitSprL EQU >8307 The low byte of HitSpr will actually contain the Sprite NumberCtr EQU >8308 A Two Byte counter to be used as an Index.CtrL EQU >8309LastSp EQU >830A Last Sprite value times 4SPHT EQU >830B Sprite Hit Tolerance in pixels ST 5,@SPHT Set the Sprite Hit tolerance value, in our case 5 seems to work nicely. WhichSP DST >0004,@Ctr * Set counter to 4 so that we start by testing Sprite 1 DCLR @HitSpr * Clear the address that will hold which Sprite we collided with.Find MOVE 2,V@>0300,@SPPY0 * Move the main sprite's co-ordinates into SPPY0 and SPPX0 MOVE 2,V@>0300(@Ctr),@SPPYT * Move the Sprite co-ordinates to test with into SPPYT and SPPXT SUB @SPPYT,@SPPY0 * Find the delta between our Sprite Y and the Sprite Y we might have collided with SUB @SPPXT,@SPPX0 ABS @SPPY0 ABS @SPPX0 blk1 CH @SPHT,@SPPX0 * If Delta in X is greater than the Sprite Tolerance then jump to end of block 1 BS blk1end CHE @SPPY0,@SPHT * If Delta in Y is less or equal to the Sprite Tolerance then jump to Found. BS Foundblk1end add 4,@CtrL ResFind CEQ @LastSp,@CtrL * Is the counter equal to the Last Sprite BR Find * If counter is not last last sprite then branch to the "Find" label. RTN Found SRL 2,@ctrL * Divide Counter by 4 to get the sprite number rather than the 4 byte offset. ST @ctrL,@HitSprL * Store the sprite number in HitSpr ST @LastSp, @ctrL * Place a large value in CTR so the loop exits. B ResFind * Resume the Find. *** Enjoy *** Prog7G.zip Edited February 3, 2016 by Davvel Quote Link to comment Share on other sites More sharing options...
Davvel Posted February 4, 2016 Author Share Posted February 4, 2016 (edited) During the development of my 8th GPL program today I noticed that XGA99 is also not in line with the document I am reading from when it comes to the case statement. http://www.unige.ch/medecine/nouspikel/ti99/gpl.htm#CASE Example: ST 2,@>8300 CASE @>8300 BR G@ONE this statement is skipped BR G@TWO this branch is taken BR G@THREE The document states that if I store 2 in 8300 then the 2nd case will be called but in fact the 3rd will be called as XGA99 is starting from zero to call the first branch. Will upload the 8th program later on this evening (5th Feb) as now I am too tired to explain what it does... it is already 00:52 Malta time and today I need to wake up at 5:30am Edited February 4, 2016 by Davvel Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted February 5, 2016 Share Posted February 5, 2016 Well, The TI docs say that CASE adds twice the value of the operand to the PC. The PC is the address of the next byte after the CASE instruction, which, in your example is BR G@ONE. CASE resets the condition bit, so BR is always taken if it is the object of CASE. BR is also a two-byte instruction (B is three bytes), which is the reason it is usually the object of the CASE statement. Your three BR instructions are 0, 2 and 4 bytes away from the PC, so Thierry is definitely wrong here: PC + 2 * 2 = PC+4, which is BR G@THREE. XGA99's action is correct. ...lee 1 Quote Link to comment Share on other sites More sharing options...
Davvel Posted February 6, 2016 Author Share Posted February 6, 2016 (edited) Hi to all my Atari Age friends The following is my 8th Instalment of a GPL program. In this demo which could with some more effort become a customisable 2d game I try to capture some more things that I learnt. Mainly: 1. Using the Spire Auto Motion in a controlled way where I simulate acceleration, deceleration, slip and friction. 2. Collision with Energy transfer from main sprite to other sprites 3. Collision with background and variable look ahead according to speed of main sprite not to overshoot over background. 4. Using Indexed addressing to control multiple sprite events. Play the pseudo game and kindly comment on speed, general feel (not look for now) and if you agree that GPL may be suited for some kind of games. Read the code and see comments etc... to suggest what can be done better. With a small configuration one can modify this code to add up to 15 sprites which can then react with the main sprite in the same way as the 2 sprites I placed. One can play with acceleration and different energy transfer options such as multiplying the transfer and point of contact to as much as you deem appropriate. I may or may not keep building on this particular demo, but my next experimentation is to use multiple GROMs for same game/app The following Keys move main sprite Up down left and right. "=" to exit. Keeping any of the keys pressed will gradually increase the speed. Once you hit with a sprite you transfer your energy to that sprite. The aim of the "game" is to move both sprites from top left quadrant to the bottom right quadrant without ending with sprites outside of the border. There is no score or game over so it is not a game but a simple concept which probably I will develop further if I get some kind of encouragement. My wife was the first pre beta tester and after 1 minute, she smiled politely, and was kind enough not to laugh. / \ P <A S> L \ / Prog8G.zip Edited February 6, 2016 by Davvel 1 Quote Link to comment Share on other sites More sharing options...
Asmusr Posted February 6, 2016 Share Posted February 6, 2016 Very nice, you are progressing fast. Are you working with floating point or fixed point numbers for the velocities and accelerations? One issue I noticed is that when you change direction you seem to be moving much faster, which is not quite realistic. Quote Link to comment Share on other sites More sharing options...
Davvel Posted February 6, 2016 Author Share Posted February 6, 2016 Rasmus, First of all thanks for your comments, I appreciate it even more coming from a master coder like yourself. I am not using floating point but instead of mapping my integers one to one with my sprite, I am gradually incrementing the sprite speed through auto motion and constantly altering these values in VDP to get the desired effect. Now for corners, I know about the flaw, it is something I intended addressing in my next release, which should be fairly simple as I already have a variable that is updated every time player changes direction. I will keep working on the physics part as soon as I master GROM paging as I know that if I ever will write a game for a cart it has to span many GROMS to have some decent graphics and sound. I may not be the right person to create the backgrounds and music, but hopefully once I get the main game engine ready then I can collaborate with someone who can provide me with Magellan graphics and sound lists. I am not yet ready yet to use Tursi's great music player that you are using in your excellent games as for now I would like to remain a GPL purist David 1 Quote Link to comment Share on other sites More sharing options...
Tursi Posted February 7, 2016 Share Posted February 7, 2016 Very nice work Quote Link to comment Share on other sites More sharing options...
Davvel Posted February 7, 2016 Author Share Posted February 7, 2016 Thanks, Tursi, very kind of you. Quote Link to comment Share on other sites More sharing options...
Davvel Posted February 21, 2016 Author Share Posted February 21, 2016 Sorry for not posting any earlier but I was busy absorbing all I can on GPL. I have made some progress on a game I am writing and put many hours into it's development. For now it is still in a state of flux so I will keep it under wraps not to feel obliged or tied down to its current look and feel, but promise that I will contribute something in a few months time. In the meantime, as I go along I am learning small things that I could not find well documented and felt that anyone who wants to learn GPL might get a head start by sharing what I learnt through many hours of trial and error. In Prog9 I am explaining how to work with Signed Integers and how to divide a 16 bit number with another. Prog9G.zip 1 Quote Link to comment Share on other sites More sharing options...
Davvel Posted February 21, 2016 Author Share Posted February 21, 2016 (edited) Below I am posting how to have a table in GROM with 16bit signed integers, pull the value that you want as pointed by an index pointer and manipulate the values such as DADD. GROM >6000 Header stored in 6000-6030 AORG >30 Program starts at 6030 Index EQU >8306 2 byte index Store2 EQU >8308 2 bytesStore3 EQU >830A 2 bytesStart * Signed Integers and GPL. * 2's complement subtraction using DADD. I need this for my game so I am testing it here.* In GROM we shall have a 16 bit representation of -1 which we can apply to any number we have using DADD.* Using Move we fetch this number as pointed by a 2 byte Index and place it in Store2 (2 bytes in CPU RAM)* Then Store a 16 bit number in Store 3* ADD the 2 stores together and using Classic 99 Debugger view (CPU) * you will see that Store 2 is now 1 less than Store 3. DST 2,@Index MOVE 2,G@DblVal(@Index),@Store2 Store 2 = -1 DST 260,@Store3 Store 3 = 260 DADD @Store3,@Store2 Store 2 = 259 LP SCAN BR LP EXIT DblVal BYTE >FF,-20 BYTE >FF,-1 END Edited February 23, 2016 by Davvel 1 Quote Link to comment Share on other sites More sharing options...
Davvel Posted February 23, 2016 Author Share Posted February 23, 2016 (edited) To: ralph, During my game development using XGA99 I often need to switch between Test Mode and Normal mode. When I compile my game in Test Mode I will get cheats like infinite lives or no collision is detected etc... This is done with a simple flag which throughout the program I skip some code if this is set. I am not keen on this approach as I will eventually need to remove all this extra code later on when I want to make the final release. Would you consider to include #if preprocessor directive within your GPL compiler ? Therefore I could code something like the below: START DST 3,@Lives #if TEST DST 999,@Lives #endif DST 1,@Index MOVE 2,G@DblVal(@Index),@Store2 Store 2 = -1 DST 260,@Store3 Store 3 = 260 DADD @Store3,@Store2 Store 2 = 259 #if TEST CALL ShowBonus #endif More code goes here....... EXIT END And the code in between the #if and #endif will only be included in the compiled BIN file if I compile with a -t option: Example XGA99.py -t -i myfile,gpl Thanks David Edited February 23, 2016 by Davvel Quote Link to comment Share on other sites More sharing options...
ralphb Posted February 24, 2016 Share Posted February 24, 2016 Yeah, I see your point. I think it should be straight-forward to port the pre-processor from xas99 to xga99. I'll give it a shot on the weekend. Quote Link to comment Share on other sites More sharing options...
Davvel Posted February 24, 2016 Author Share Posted February 24, 2016 Thanks RalhB. Much appreciated. Quote Link to comment Share on other sites More sharing options...
ralphb Posted February 28, 2016 Share Posted February 28, 2016 (edited) Turns out it wasn't straight-forward at all , but at least now the code base of xga99 and xas99 is much better aligned again. xga99 now supports conditional assembly, and macros. So regarding your request, you can write . START .ifdef TEST DST 999,@Lives .else DST 3,@Lives .endif DST 1,@Index and assemble with . $ xga99.py sample.gpl <--- 3 lives $ xga99.py sample.gpl -D TEST <--- 999 lives . You can also assign values, so you could write . .ifdef TEST DST TEST,@Lives .else DST 3,@Lives .endif . and assemble with . $ xga99.py sample.gpl -D TEST=69 . You can also use macros now, but note that I don't support the "default" macros like $WHILE etc. yet. Please get the updated xga99 from here, as there's no new release yet. The manual has also been updated, but you can just have a look at the matching sections for xas99. Edit: That forum editor is killing me ... Edited February 28, 2016 by ralphb 1 Quote Link to comment Share on other sites More sharing options...
Davvel Posted February 28, 2016 Author Share Posted February 28, 2016 Thanks a million, this is highly appreciated and will come in very handy. I am making a lot of effort in the GPL front and today I spent most of my time learning how to convert music from sheets to GPL data bytes. Hopefully I can come up with some decent sound lists David Quote Link to comment Share on other sites More sharing options...
Davvel Posted February 28, 2016 Author Share Posted February 28, 2016 I have now gained enough knowledge in how to play music using GPL, can anyone indicate if there is a way to alter the volume of a sound list that already started playing in a continuous loop without disturbing it, given that in no part of this soundlist will I define the attenuation value of the notes? I have found ways of altering the VDP RAM that the sound list is stored and change the volume bytes and then restart the list to take affect with the new volume, but it would be much nicer to have the volume altered without restarting the sequence. Quote Link to comment Share on other sites More sharing options...
+Ksarul Posted February 28, 2016 Share Posted February 28, 2016 I can't help you there, as I've been happily following your journey into GPL even though I can't contribute much. At some point, I will be following you down this trail, so all of the things you have documented will come in VERY useful. 1 Quote Link to comment Share on other sites More sharing options...
+mizapf Posted February 28, 2016 Share Posted February 28, 2016 "Keep in mind ... we're all close behind you." 1 Quote Link to comment Share on other sites More sharing options...
Davvel Posted February 28, 2016 Author Share Posted February 28, 2016 Please note that I am directing this question of altering the Sound Generator attenuation on the fly even to the assembly guys like rasmus and tursi. I am sure this will be a system limitation rather than a GPL limitation. In case I was not understood, can TI 99/4A be made to have a predefined sound list playing a melody in the background using it's internal interrupt routines (as pointed by address >8308) and using any language one would just alter the attenuation of the sound generators without disturbing the melody, example make music fade out etc.... I am sure one can emulate this by writing our own background music controller which plays one note every 1/50th of a second and then you will have full control, but I am more interested if we can use TI's internal music player and altering the volume on the fly. BTW this is not very important, just good to know as a learning exercise. Thanks to all. My wife just couldn't understand why it is so difficult to have a simple middle C playing for half a second on the TI using GPL the data bytes are mind bogglingly difficult to compute by hand. I hope to find the time to create some kind of decent tool for this which everyone can benefit from. Quote Link to comment Share on other sites More sharing options...
+mizapf Posted February 28, 2016 Share Posted February 28, 2016 If you directly access the sound chip, anything is possible. You can do that by writing to >8400; set the frequency bytes, and the attenuation byte of any of the sound generators or the noise generator in the chip. The sound chip does not know anything about length of a tone, and silence is just raising the attenuation to maximum. However ... you said you want to make use of the automatic sound list player. In those lists you usually have frequencies and attenuation bytes. The problem is that those attenuation bytes are just written to the sound chip without caring about your intention to fading out. I think it is possible to create a play list without attenuation so that you could indeed define a customized volume control, but it would probably be easier just to write a new sound player routine. I'd suggest a kind of attenuation bias which is added to the values before they are written to the sound chip. You would, however, be forced to check whether the result exceeds 15, creating an overflow. 1 Quote Link to comment Share on other sites More sharing options...
Tursi Posted February 29, 2016 Share Posted February 29, 2016 an anyone indicate if there is a way to alter the volume of a sound list that already started playing in a continuous loop without disturbing it, given that in no part of this soundlist will I define the attenuation value of the notes? Given the restriction you list, just write to the sound chip directly between interrupts, as was hinted at. Attenuation values range from 0 (no attenuation) to 15 (silent), and they are set independently on each channel. For the first channel, write >80 plus attenuation, for the second, >A0, for the third >C0, and for noise >E0. I believe the I/O command can write to the sound chip so you don't need to use ST, but I don't have notes handy to check that. 2 Quote Link to comment Share on other sites More sharing options...
Davvel Posted February 29, 2016 Author Share Posted February 29, 2016 Thanks Tursi. I will try to do this later on this evening. I will soon be finalising a tool which will help those wanting to convert sheet music to Data Bytes. 1 Quote Link to comment Share on other sites More sharing options...
+mizapf Posted February 29, 2016 Share Posted February 29, 2016 For the first channel, write >80 plus attenuation, for the second, >A0, for the third >C0, and for noise >E0. Small correction: Attenuation is value (0..F) + 90 / B0 / D0 / F0 (so you get >9F, >BF, >DF, >FF for silence). The 80/A0/C0/E0 are used to form the frequency code. Quote Link to comment Share on other sites More sharing options...
Davvel Posted February 29, 2016 Author Share Posted February 29, 2016 Mizapf, thanks for clarifying. Please note that I have read many docs on this during this weekend and covered many aspects including attenuation. The only thing I did not experiment with was on the fly manipulation of the volume of a particular channel while this is happily playing away a sound list which may contain volume settings within it (but I will not include volume settings if I want to modify externally). I will soon be contributing my first tangible item to ATARIAGE members. This tool should come in handy to convert music scores (with chords etc...) directly to GPL code. I still need to polish it up a little. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.