Jump to content

gokmase

Members
  • Posts

    29
  • Joined

  • Last visited

Profile Information

  • Gender
    Not Telling
  • Location
    Sweden
  • Interests
    GFA

gokmase's Achievements

Space Invader

Space Invader (2/9)

0

Reputation

  1. That is an interesting idea, I never thought about it that way. But that comparison isn't at all a bad allegory - from my point of view the line numbers in earlier/primitive Basic dialects can absolutely be seen as high level languages' equivalents to program counter in machine code, posing as exact references to where you are currently located in the program flow. I made my first attempts at programming around 1984 with a Swedish Z80-based computer (ABC80) which had a Basic interpreter built into ROM. Needless to say, like most Basic versions at the time it was based on the concept of line numbers. At the time I didn't know of any alternatives but I sure recall the hassle of renumbering segments of code in order to be able to insert new code in between existing row numbers. The first time I tried to pick up Basic programming after I had bought my first Atari I quickly found out that none of the Basic alternatives that were any good (and that were at my disposal) used a line number based approach, so that presented a somewhat cumbersome threshold to get past for me. The usage of line number based coding hadn't really encouraged me as a coder to get a proper feel for program flow, so that was something I later on had to battle a bit with to improve. So my take on explaining the biggest downside with line number based coding to someone that never tried it - it is a concept that is very far from being ideal when it comes to writing well structured code. Especially for beginners, it is in my opinion much too easy to end up writing spaghetti-like code and make a bad habit out of it. Once I had adjusted to manage without the line numbers, there was absolutely nothing about them that I felt I was missing. If I'd ever power up my ABC80 (Yes, I still have it!) today and try to do any programming with it, there wouldn't be much choice though. The Basic of ABC80 resides in ROM and its 16kb of RAM certainly isn't enough to soft load a more modern programming solution (if that would even exist) and be able to create anything with it. The only incitement for me to do that would be to create a moment of nostalgia, revisiting my first computing experience. As a way to achieve that, I'd accept the line number approach since that would be part of the retro experience. But from a general (Basic) programming point of view I am inclined to say that line number based programming is only the best option when there are no alternatives.
  2. You might be right on the 8 level limit, although a higher value isn't backfiring at least. I am quite aware you were seeking to redraw individual G_STRINGS and that is why I tried to explain how to do that without the transparency/overlay effect. If you follow my instructions the clipping rectangle of objc_draw() makes the call only output to the area you want (which is the rectangle occupied by the G_STRING). Yes, I did see your reply regarding v_bar solution for clearing the background but since I had already spent >30 minutes preparing an explanation on how to do it through the one simple objc_draw(), I decided to post anyway. In case you only need to perform full redraws, including the whole object tree at a time, then none of this is of course necessary.
  3. Seems you get proper results from the objc_offset() call now. The overlay effect is back since you perform the objc_draw() call starting from the actual G_STRING object and then 3 levels down (which doesn't add anything since the G_STRING objects have no children). Essentially, you are not including the objects in the background at all. You can think of the G_STRING as a transparent object where only the actual text is being output upon objc_draw(). Hence, if you alter the text buffer contents of an object and then redraw only the actual object, it will not clear the background at all, but simply just output the new text contents on top of the old one. Easiest way to perform a redraw that takes care of this situation is to redraw from the root object (obj=0) and include as many levels of depth you can foresee is being used to reach down to the level your object is located. Usually a depth of 5 is more than enough, but make it 10 just to be sure if you want. Now the you have valid data to specify the clipping rectangle for your G_STRING objects, you can thus redraw *everything* from the root level down to your objects depth, but restrict the output by specifying the outer limits of the G_STRING in the clipping rectangle. tree& = address to object tree ob = index of the G_STRING object to redraw 0 = root object 10 = include child objects down to 10 levels depth x&, y& = absolute screen position as returned by objc_offset() w&, h& = height and width of the G_STRING object. You know how to find these out already junk = objc_offset(tree&,ob,x&,y&) junk = objc_draw(tree&,0,10,x&,y&,w&,h&) That should work. Again, chapter #6 in the Atari Compendium actually explains quite a lot on how things are tied together. I agree TOSHYP is a nice reference too (and is still being updated) but IMO the overall explanation of the system is much better described (and much easier to understand) in the Atari Compendium.
  4. Well, the call you need to sort out to locate the area to redraw is for sure objc_offset. Considering it is just one call this should really not be a struggle. In my mind you might at this time want to consult Matt regarding any Hisoft Basic syntax aspects that needs attention for this to work out. I think we established how to do it principal, now it is a matter for you to sort out how to do it in Hisoft Basic and making sure variable postfix aren't causing any trouble.
  5. The values for width/height (56,16) are definitely correct if you mean G_STRING objects in the left column, that can easily be verified by looking at the object data in an RSC-editor (I use RSM 3.651) Strings in the right column seems to have width/height 48,16 which makes sense since they hold one character less. You can find out the offsets to any part of the object structure by looking at the structure definition: (already posted back in post#23) typedef struct object { WORD ob_next; (obadr&+0) WORD ob_head; (obadr&+2) WORD ob_tail; (obadr&+4) UWORD ob_type; (obadr&+6) UWORD ob_flags; (obadr&+ UWORD ob_state; (obadr&+10) VOIDP ob_spec; (obadr&+12) WORD ob_x; (obadr&+16) WORD ob_y; (obadr&+18) WORD ob_width; (obadr&+20 WORD ob_height; (obadr&+22) } OBJECT; NOTE: The ob_x and ob_y values in the object structure specifies the objects position relative to its parent, hence not very useful to you at this time, since you need to know the absolute screen position of the objects you wish to redraw. I think a good way for you to proceed would be to download the Atari Compendium (http://dev-docs.atariforge.org/files/The_Atari_Compendium.pdf) and read through the AES chapter. Reading through the whole chapter would probably be good to get a better overview of the inner workings of the system. Make sure to pay extra attention to the sections covering "Resources" (6.13-6.23) and "Object library" and "Resource library" (6.115-6.129)
  6. My initial thought is that if objc_offset() fills in the return values for x/y with 0/0 then one of these things might have happened: 1) Something went wrong with the actual objc_offset() call. Either a problem with using wrong variable name for either input or output, or overwriting the variable data by accident somewhere in between the call and the evaluation of the data. - Double check for typos on variable names! Also, verify that the returned value from objc_offset (stored in variable "junk" in your example) is filled with a non-zero value - if zero is returned then the objc_offset() call for some reason was unsuccessful. - And as noted before, do pay attention to if a variable might be accidently overwritten before evaluated - that happens all too easy.. 2) The object structure has been partly corrupted, and the area where its position is stored has been trashed. This is perhaps not that likely, but I suppose it could happen. - Try and see if it makes a difference if you make the objc_offset() call *before* manipulating the contents of any string buffer. 3) The object has in fact been moved legally to a x,y-position that corresponds with absolute position 0,0. I don't find this explanation very likely in this case though. A GEM program quickly gets very complex, and it is very easy to insert unwanted functionality by accident. Well, also known as a bug If we use the object #3 as an example, it is located inside object #2 that is a G_IBOX (probably used as a placeholder, to group together G_STRINGS, from obj #3 to obj #17, used for publishing test results). The parent of object #2 is a G_BUTTON, object #1. Now, if any part of the code alters the x,y-position of object #1 or object #2, this will of course affect the absolute position of object #3 as well. That said, this scenario is maybe not the most likely one to be responsible here. Regarding the redraw remark: In order to redraw the text without the transparency problem with the text, it is (as you noticed) not enough to redraw only the G_STRING itself. You need to include at least the parents from object #1 with a depth=2 for this to look right I think. (But for this redraw scheme to work as planned it is an absolute must to find out the correct (absolute) X,Y and width/height of the G_STRING object to use for the clipping rectangle in objc_draw, otherwise it will either redraw too much or too little.)
  7. The size of the text buffers created upon RSRC_LOAD() are static, so beware of writing longer strings than those that are saved from RSC editor! In your example: Text buffer of object#3 can hold max 7 chars + null byte. Text buffer of object#19 can hold max 6 chars + null byte. First thing that happens if you write ascii chars past the limit of the buffer, is that you will trash the ending null byte, making it likely that you will find a longer text snippet than expected drawn to screen. (Sending an ascii byte to obspec%+7 will thus trash the ending null for object#3 in your case.) Writing further bytes beyond that limit will for sure cause corruption of any RSC data that follows the text buffer. Fun, fun
  8. IIRC, issuing an OBJC_DRAW() for a G_STRING object will draw it in a transparent fashion, thus drawing the new (changed) text on top of the original one. You could work around that (the transparency "problem") by instead drawing the root object but including every child object down to depth of 3 (needed in this example) and then apply a clipping rectangle in size of our object. Something like this should work: obj&=3 ! The object we are targeting... ob_adr%=tree%+(obj&*24) ! Locate object address ob_w&=INT{ob_adr%+20} ! Find out width of our object ob_h&=INT{ob_adr%+22} ! Find out height of our object dummy%=OBJC_OFFSET(tree%,obj&,ob_x&,ob_y&) ! Find out the absolute position on screen for our object dummy%=OBJC_DRAW(tree%,0,3,ob_x&,ob_y&,ob_w&,ob_h&) ! Draw the root object (obj=0) and every child is contains down to max. 3 levels, limited by the clipping rectangle ob_x&, ob_y&, ob_w&, ob_h& (I tested this against the GEMBENCH.RSC and you do need to set the depth in objc_draw() to at least 3 in order for the call to reach from the root object to the child object we are targeting in this example) NOTE: The above is GFA-BASIC example code and as in previous examples, you will need to convert the variable postfixes to something better suited for Hisoft Basic
  9. No, ob_spec is not pointing to an object at all, in this particular case it is pointing to the starting address of the text to be displayed. To be accurate ob_spec is a field that is *part* of the actual object structure, not pointing to the object. Depending on the object type ob_spec either contains: 1) A pointer to a TEDINFO structure (Object types: G_TEXT, G_BOXTEXT, G_FTEXT, G_FBOXTEXT) 2) A pointer to a BITBLK structure (Object type: G_IMAGE) 3) A pointer to a APPLBLK structure (Object type: G_PROGDEF) 4) A pointer to a ICONBLK or CICONBLK structure (Object types: G_ICON, G_CICON) 4) A pointer to a text buffer (Object types: G_BUTTON, G_STRING and G_TITLE) 5) A bit pattern (different for the respective object types) with various information regarding colour and borders, etc (Object types: G_BOX, G_BOXCHAR) Regards, /Joakim
  10. Then I think we have found at least one reason why the example fails. My example was based on objects where OB_SPEC contains a pointer to a TEDINFO structure, as mentioned in post #19. For a G_STRING object the OB_SPEC field however contains a pointer directly to the text to be displayed. Regards, /Joakim
  11. Out of curiosity, what object type is INF_FORM1? Regards, /Joakim
  12. Not sure what is stirring up problems, but I have a hunch it may come down to the variable postfix type. In GFA you will find this to be true: Word & 2 bytes -32768 to 32767 Long % 4 bytes -2147483648 to 2147483647 In my example, anywhere a variable with postfix % is used, it refers to a LONG. And when a & is used, it refers to a WORD. I suspect the postfix types are not the same in Hisoft Basic. From one of your lines of working code, I get that you can store the address of a tree in tree&. Hence postfix "&" must mean a LONG (4 bytes). If that is correct, I would try to change the postfix of the variable you store the object address in: obadr& = tree& + (3*24) Regards, /Joakim
  13. Hi Matt, Good to see you around again. You are for sure better suited to advice exxos on issues that involves coding in hisoft basic any day of the week! And furthermore, I think that any excuse that can bring an Atari out of the closet is a good one, so I'd say go with that Regards, /Joakim
  14. RSRC_GADDR() is for most practical cases only ever used to find the address to the object tree(s). dummy%=RSRC_LOAD(0,tree_index&,tree_adr%) ! The address to the object tree (tree_index&) is then stored in tree_adr% But I realize that when coding for GFABASIC I have been spoiled with access to built in commands that offers shortcuts to individual objects and their structures, such as eg. OB_ADR and OB_SPEC. However, the object tree laytout is known: typedef struct object { WORD ob_next; WORD ob_head; WORD ob_tail; UWORD ob_type; UWORD ob_flags; UWORD ob_state; VOIDP ob_spec; WORD ob_x; WORD ob_y; WORD ob_width; WORD ob_height; } OBJECT; From this we can conclude that every object structure occupies exactly 24 bytes (same goes for the root object of course, since it too is an object). And I learned from a discussion earlier today that all the objects structures in a tree are stored one after the other, which means that we can locate the address of an individual object structure within a specified object tree by knowing its index: ob_adr%=tree_adr%+obj&*24 ! Start at the address where object tree begins, move 24 bytes forward for each object you wish to "skip". This line of code locates the address of the individual object. ob_spec%=LONG{ob_adr%+12} ! Essentially, 12 bytes into the individual object structure, you find the ob_spec field. Then we should be able to use the concept previously described: te_txtlen& = WORD{ob_spec%+24} ! Find the size of the text buffer attached to this object te_ptext% = LONG{ob_spec%+0} ! Find the address to the text buffer new_text$="Hello world" ! Find nice example text :-) new_text$=left$(new_text$,te_txtlen&) ! Make sure it fits the available buffer CHAR{te_ptext%}=new_text$ ! Update the text buffer with our brilliant example text (CHAR{} automatically adds en ending NULL byte) dummy%=OBJC_DRAW(tree_adr%,obj&,0,form_x&,form_y&,form_w&,form_h&) ! Draw the updated object contents to screen. Last 4 parameters consist the clipping rectangle. Oh, and I realize the above is GFABASIC code, but it should be dead simple to get the same scheme going with Hisoft Basic I think. Regards, /Joakim
  15. I am afraid I can't help you with exactly how to proceed in Hisoft Basic. IIRC Matthew Bacon was devloping advanced GEM library routines back in the days, maybe he is still around in some of the forums? In GFA I would probably have done something like this: te_txtlen& = WORD{OB_SPEC(addr%,obj&)+24} ! Find the size of the text buffer attached to this object te_ptext% = LONG{OB_SPEC(addr%,obj&)+0} ! Find the address to the text buffer new_text$="Hello world" ! Find nice example text :-) new_text$=left$(new_text$,te_txtlen&) ! Make sure it fits the available buffer CHAR{te_ptext%}=new_text$ ! Update the text buffer with our brilliant example text (CHAR{} automatically adds en ending NULL byte) dummy%=OBJC_DRAW(addr%,obj&,0,form_x&,form_y&,form_w&,form_h&) ! Draw the updated object contents to screen. Last 4 parameters consist the clipping rectangle. Regards, /Joakim
×
×
  • Create New...