Descolado Posted February 4, 2019 Share Posted February 4, 2019 Hi, Sorry my english. I'm working in a game that use several screens. My player can move between screens, by example, he can move from Screen 1 to Screen 2 and can go back to Screen 1. After draw the screen I'm putting objects using PRINT AT (my MOB not use "COL" to colision detection, I'm using other system). In Screen 1 my player can open a door or touch a obstacle and I replace the card) and move to Screen 2. If my player go back to Screen 1 I need "remember" what Card he touched and not to put it back on the screen. When my player touch a CARD I need "save" this CARD in any place in memory but I don't know how because CARDs can't be "marked". I can use a "screen memory":Screen_0(X), Screen_1(X), etc, where "X" is the number of sprites in my screen that my MOB can "hit" but I think it's going to be a lot of work because I have more than 50 screens. Quote Link to comment https://forums.atariage.com/topic/287910-screen-memory/ Share on other sites More sharing options...
+DZ-Jay Posted February 4, 2019 Share Posted February 4, 2019 Hi, Sorry my english. I'm working in a game that use several screens. My player can move between screens, by example, he can move from Screen 1 to Screen 2 and can go back to Screen 1. After draw the screen I'm putting objects using PRINT AT (my MOB not use "COL" to colision detection, I'm using other system). In Screen 1 my player can open a door or touch a obstacle and I replace the card) and move to Screen 2. If my player go back to Screen 1 I need "remember" what Card he touched and not to put it back on the screen. When my player touch a CARD I need "save" this CARD in any place in memory but I don't know how because CARDs can't be "marked". I can use a "screen memory": Screen_0(X), Screen_1(X), etc, where "X" is the number of sprites in my screen that my MOB can "hit" but I think it's going to be a lot of work because I have more than 50 screens. That's actually a common problem. One way would be to pack the screen "hit" data in some custom format and store it in memory, as an array. For 50 screens, an array with a byte for every card on screen may be too expensive, but perhaps there are patterns that you could identify in order to pack them. For instance, if it is only the state of a door, and there are 4 doors per screen, then you need at most 4 bits to store the state of each screen. You can then pack 4 screens in a 16-bit variable, which will reduce your RAM requirements to 13 words. I can't help further because I am not familiar with the nature of the state data you wish to track. I hope this helps. dZ. Quote Link to comment https://forums.atariage.com/topic/287910-screen-memory/#findComment-4212904 Share on other sites More sharing options...
+nanochess Posted February 4, 2019 Share Posted February 4, 2019 In Sydney Hunter and the Sacred Tribe, all rooms have the objects drawn in the rooms, but I've a small list for each room, similar to this: DATA 6*20+10,1 ' Position and type of object DATA 0 I think you could use a simple 8-bits array for keeping item state, and once you detected the item is taken, you mark the element of array with a bit to one (in case you have several items). When drawing the room, you erase the object if the bit is set for that room. For keeping an inventory you need to choose between only having one item at a time, or several items. If you have upto 8 items at same time then you can use a single byte to keep track of it. If you can have more objects than these, the you would use another 8-bits array and insert/displace when taking item/losing item. Quote Link to comment https://forums.atariage.com/topic/287910-screen-memory/#findComment-4212937 Share on other sites More sharing options...
Kiwi Posted February 5, 2019 Share Posted February 5, 2019 It should take 4 bytes to remember which tile been taken. You should have a screenID number for the screens that you have, You store the screen number, x,y, #TileID, in 5 bytes. You can probably split the TileID into 2 bytes and not waste word on tileID. After the screen has being printed on screen, you can check what screen ID is in your array, if it is, then poke that tile on screen. Quote Link to comment https://forums.atariage.com/topic/287910-screen-memory/#findComment-4213251 Share on other sites More sharing options...
Descolado Posted February 5, 2019 Author Share Posted February 5, 2019 Hmmm... interesting suggestions! I was thinking. Many cards in my screen are statics, how doors, keys and others objects. When my MOB touch it I "delete" the card (PRINT AT X_Card, 0).When my player touch a CARD I can take only two informations about it: SCREEN and COORDENATES.Before create a screen, I need save this two informations in someplace. I was thinking save in array: DIM Screen_5(3)Screen_5(0) = 181 'left door X positionScreen_5(1) = 186 'key X positionScreen_5(2) = 197 'right X door position Then, if my player touch the KEY card, I will put "zero" in index 1 (Screen_5(1) = 0). If my player go back to the screen 5, I will read all index of Screen_5: If CurrentScreen = 5 THEN If Screen_5(0) > 0 THEN PRINT AT Screen_5(0), DOOR_LEFT If Screen_5(1) > 0 THEN PRINT AT Screen_5(1), KEY If Screen_5(2) > 0 THEN PRINT AT Screen_5(2), DOOR_RIGHTEND IF But if I use SCREEN_0(X), SCREEN_1(X)... SCREEN_50(X) etc, I don't will have enough 8bits variables to save ALL cards because each screen can have 3 to 10 objects that my MOB can "hit" and I have only 179 8-bit variables available. I can use JLP but I do not like this idea. Thanks by suggestions, I'll look for more information in the forum about it. Quote Link to comment https://forums.atariage.com/topic/287910-screen-memory/#findComment-4213363 Share on other sites More sharing options...
emerson Posted February 5, 2019 Share Posted February 5, 2019 You could limit each room to 8 interactive objects and dedicate an object status variable to each room.Dedicate another variable to door status for 4 rooms, and toggle bits when items are hit or doors are opened/closed.Keep all of the coordinate data in tables.Assuming 50 rooms, 50 object vars + (50/4) door vars = 63 8-bit variables If you were to limit the amount of rooms to 40 or 45, you could pack each room into its own 16-bit variable. This allows you to add more doors and items to each room while leaving a couple 16-bit variables for other uses. Example code: Screen_5678_Door_Status = 0000 0000 |||| |||| |||| |||5L |||| ||5R |||| |6L |||| 6R |||| |||7L ||7R |8L 8R Screen_5_Objects = 0000 0000 |||| |||| |||| |||object 0 |||| ||object 1 |||| |object 2 |||| object 3 |||| |||object 4 ||object 5 |object 6 object 7 Screen_5_Data: data (#) left door x position data (#) 'right door x position data (#) 'object 0 position data (#) 'object 1 position data (#) 'object 2 position data (#) 'object 3 position data (#) 'object 4 position data (#) 'object 5 position data (#) 'object 6 position data (#) 'object 7 position '==========Example 16-bit variable========== Screen_5_Status: 0000 0000 0000 0000 |||| |||| |||| |||| |||| |||| |||| |||left door 0 status |||| |||| |||| ||right door 0 status |||| |||| |||| |left door 1 status |||| |||| |||| right door 1 status |||| |||| |||| |||| |||| |||object 0 status |||| |||| ||object 1 status |||| |||| |object 2 status |||| |||| object 3 status |||| |||| |||| |||object 4 status |||| ||object 5 status |||| |object 6 status |||| object 7 status |||| |||object 8 status ||object 9 status |object 10 status object 11 status 2 Quote Link to comment https://forums.atariage.com/topic/287910-screen-memory/#findComment-4213418 Share on other sites More sharing options...
carlsson Posted February 5, 2019 Share Posted February 5, 2019 (edited) Expanding on Emerson's ideas... You can't pick up doors, only open or close them? Does each screen have a different number of doors? I'm thinking something like in ROM you have each room defined in some way, and then you could pack bits: DIM north_doors(7), south_doors(7), east_doors(7), west_doors(7) : REM would be enough for 7*8 = 56 rooms bit = 1 i = CurrentScreen % 8 WHILE i>0 : bit = bit * 2: i=i-1 : WEND : REM I didn't find any ^ operator in the language? IF (north_door(CurrentScreen / 8 ) AND bit) > 0 THEN ... IF (south_door(CurrentScreen / 8 ) AND bit) > 0 THEN ... In case you only have doors in two directions as indicated by the screenshot, you can of course omit two of the arrays. Edited February 5, 2019 by carlsson Quote Link to comment https://forums.atariage.com/topic/287910-screen-memory/#findComment-4213434 Share on other sites More sharing options...
emerson Posted February 5, 2019 Share Posted February 5, 2019 I should have included some bitwise analysis code in my example, so thank you carlsson for doing so. Quote Link to comment https://forums.atariage.com/topic/287910-screen-memory/#findComment-4213450 Share on other sites More sharing options...
intvnut Posted February 9, 2019 Share Posted February 9, 2019 (edited) i = CurrentScreen % 8 WHILE i>0 : bit = bit * 2: i=i-1 : WEND : REM I didn't find any ^ operator in the language? You're probably better off using a lookup table here. And with some DEF FN macros, you can get some rather compact and readable code. Borrowing some code I wrote in a different thread: . DEF FN SetBit(var, bit) = var = NOT (NOT var AND ClrMask(bit)) DEF FN ClrBit(var, bit) = var = var AND ClrMask(bit) DEF FN TstBit(val, bit) = ((val) AND SetMask(bit)) ' This is the same as the power-of-2 table, so you can reuse that ' if you've already got it somewhere, rather than adding a redundant table. SetMask: DATA $0001, $0002, $0004, $0008 DATA $0010, $0020, $0040, $0080 DATA $0100, $0200, $0400, $0800 DATA $1000, $2000, $4000, $8000 ' This is the bitwise-inverse of the SetMask table. ClrMask: DATA $FFFE, $FFFD, $FFFB, $FFF7 DATA $FFEF, $FFDF, $FFBF, $FF7F DATA $FEFF, $FDFF, $FBFF, $F7FF DATA $EFFF, $DFFF, $BFFF, $7FFF . Taking that a step further, you can extend these to index into 8-bit and 16-bit arrays. Note, SetBitXX and ClrBitXX burn one 8-bit variable named 'tmp', but it makes for slightly faster code. You can get rid of 'tmp' by replacing 'tmp' with '(idx)/8'. It's only about 11 cycles slower if I counted right, and doesn't burn an 8-bit variable. . ' Manipulate bitmaps built on 8-bit arrays DEF FN SetBitA8(arr, idx) = tmp = (idx)/8 : arr(tmp) = NOT (NOT arr(tmp) AND ClrMask((idx)%) DEF FN ClrBitA8(arr, idx) = tmp = (idx)/8 : arr(tmp) = arr(tmp) AND ClrMask((idx)% DEF FN TstBitA8(arr, idx) = (arr((idx)/8) AND SetMask((idx)%) ' Manipulate bitmaps built on 16-bit arrays DEF FN SetBitA16(arr, idx) = tmp = (idx)/16 : arr(tmp) = NOT (NOT arr(tmp) AND ClrMask((idx)%16)) DEF FN ClrBitA16(arr, idx) = tmp = (idx)/16 : arr(tmp) = arr(tmp) AND ClrMask((idx)%16) DEF FN TstBitA16(arr, idx) = (arr((idx)/16) AND SetMask((idx)%16)) . So, with that, your example becomes: . DIM NorthDoors(7), SouthDoors(7), EastDoors(7), WestDoors(7) : REM would be enough for 7*8 = 56 rooms IF TstBitA8(NorthDoors, CurrentScreen) THEN ... IF TstBitA8(SouthDoors, CurrentScreen) THEN ... IF TstBitA8(EastDoors, CurrentScreen) THEN ... IF TstBitA8(WestDoors, CurrentScreen) THEN ... . The TstBitA8 sequences above generate pretty decent code as far as IntyBASIC code goes: . ;[34] IF TstBitA8(NorthDoors, CurrentScreen) THEN A = 1 SRCFILE "/tmp/doors.bas",34 MVII #array_NORTHDOORS,R1 MVI var_CURRENTSCREEN,R2 SLR R2,2 SLR R2,1 ADDR R2,R1 MVI@ R1,R0 MVII #label_SETMASK,R1 MVI var_CURRENTSCREEN,R2 ANDI #7,R2 ADDR R2,R1 AND@ R1,R0 BEQ T2 MVII #1,R0 MVO R0,var_A . The SetBitA8 / ClrBitA8 are handy if you need to change the state of the bits in the bitmap—say, to open or close a door or something. Edited February 9, 2019 by intvnut 1 Quote Link to comment https://forums.atariage.com/topic/287910-screen-memory/#findComment-4216198 Share on other sites More sharing options...
Descolado Posted February 11, 2019 Author Share Posted February 11, 2019 Thanks for help, guys. I'm learning to program at Intybasic so sorry, I'm a noob.I'm using TABLES to save X and Y sprites (this project is teaching me a lot of cool things about Intybasic) but your knowledge is a little beyond my understanding. I understand what I need to do, I just need some tips on HOW to do this. Question: How do I verify each BIT position in a 8-bit variable? Example: DIM MyScreen5: MyScreen5 = 255 'REM 1111 1111 When my MOB touch one KEY, I will change variable: MyScreen5 = 1111 1110 'REM Bit[7] OFF If my MOB open a DOOR in screen5, I will change to: MyScreen5 = 1111 1010 'REM BIT[5] OFF Then, positions [5] and [7] are OFF. How I check this positions? I can't use FOR I = 0 TO 7 because "MyScreen5" is not an ARRAY. Thanks! Quote Link to comment https://forums.atariage.com/topic/287910-screen-memory/#findComment-4218070 Share on other sites More sharing options...
intvnut Posted February 16, 2019 Share Posted February 16, 2019 Thanks for help, guys. I'm learning to program at Intybasic so sorry, I'm a noob. I'm using TABLES to save X and Y sprites (this project is teaching me a lot of cool things about Intybasic) but your knowledge is a little beyond my understanding. I understand what I need to do, I just need some tips on HOW to do this. Question: How do I verify each BIT position in a 8-bit variable? Example: DIM MyScreen5: MyScreen5 = 255 'REM 1111 1111 When my MOB touch one KEY, I will change variable: MyScreen5 = 1111 1110 'REM Bit[7] OFF If my MOB open a DOOR in screen5, I will change to: MyScreen5 = 1111 1010 'REM BIT[5] OFF Then, positions [5] and [7] are OFF. How I check this positions? I can't use FOR I = 0 TO 7 because "MyScreen5" is not an ARRAY. Thanks! You can use AND with a lookup table to test individual bits. For example: . FOR I = 0 TO 7 IF MyScreen5 AND SetMask(I) THEN ' Handle case where bit is set ELSE ' Handle case where bit is clear END IF NEXT I ' Elsewhere, outside of a Procedure, ' include this lookup table: SetMask: DATA $0001, $0002, $0004, $0008 DATA $0010, $0020, $0040, $0080 DATA $0100, $0200, $0400, $0800 DATA $1000, $2000, $4000, $8000 . Earlier in the thread, I offered some macros and lookup tables that make this even more convenient: . DEF FN SetBit(var, bit) = var = NOT (NOT var AND ClrMask(bit)) DEF FN ClrBit(var, bit) = var = var AND ClrMask(bit) DEF FN TstBit(val, bit) = ((val) AND SetMask(bit)) ' This is the same as the power-of-2 table, so you can reuse that ' if you've already got it somewhere, rather than adding a redundant table. SetMask: DATA $0001, $0002, $0004, $0008 DATA $0010, $0020, $0040, $0080 DATA $0100, $0200, $0400, $0800 DATA $1000, $2000, $4000, $8000 ' This is the bitwise-inverse of the SetMask table. ClrMask: DATA $FFFE, $FFFD, $FFFB, $FFF7 DATA $FFEF, $FFDF, $FFBF, $FF7F DATA $FEFF, $FDFF, $FBFF, $F7FF DATA $EFFF, $DFFF, $BFFF, $7FFF . This is how you'd use them to set/clear/test flags in your example: . DIM MyScreen5 MyScreen5 = 255 ' To clear bit 7 in MyScreen5: ClrBit(MyScreen5, 7) ' To clear bit 5 in MyScreen5: ClrBit(MyScreen5, 5) ' To clear bit indicated by variable I in MyScreen5: ClrBit(MyScreen5, I) ' Set bit 7 in MyScreen5: SetBit(MyScreen5, 7) ' To test a single bit: IF TstBit(MyScreen5, 5) THEN ... ' To test a bit in a loop: FOR I = 0 to 7 IF TstBit(MyScreen5, I) THEN ' Handle the bit set case ELSE ' Handle the bit clear case END IF NEXT I . And just a note: Typically bits are numbered in decreasing order, rather than increasing order. That is, the bit order goes 76543210. That corresponds to the value of each bit numerically. Bit 7 = 128 = 27, while bit 0 = 1 = 20. If you write them in that order, then the relationship between binary and hexadecimal also becomes clearer, and shows the advantage of using hexadecimal when dealing with bitmaps: . Dec Hex 7654_3210 <- Bit numbers ---------------------- 0 = $00 = 0000_0000 1 = $01 = 0000_0001 2 = $02 = 0000_0010 4 = $04 = 0000_0100 8 = $08 = 0000_1000 16 = $10 = 0001_0000 32 = $20 = 0010_0000 64 = $40 = 0100_0000 128 = $80 = 1000_0000 255 = $FF = 1111_1111 254 = $FE = 1111_1110 253 = $FD = 1111_1101 251 = $FB = 1111_1011 247 = $F7 = 1111_0111 239 = $EF = 1110_1111 223 = $DF = 1101_1111 191 = $BF = 1011_1111 127 = $7F = 0111_1111 1 Quote Link to comment https://forums.atariage.com/topic/287910-screen-memory/#findComment-4220719 Share on other sites More sharing options...
+DZ-Jay Posted February 16, 2019 Share Posted February 16, 2019 You can also flip bits with XOR. That is, sometimes you know already the state of a bit and you just need to toggle it without testing which way it is. The trick to bear in mind when using masks is this: XOR: 0 = leave the bit the same 1 = toggle the bit (if 0, then 1; if 1 then 0) AND: 1 = leave the bit the same 0 = clear the bit So, let's say that you want to clear bit 5: bit 5 = 1 | v 11101101 AND 11011111 -------- 11001101 = Bit 5 cleared without changing the others Or let's say you need to toggle that bit instead, so that if it is zero, it turns to one; and if it is one, it turns to zero: bit 5 = 1 | v 11101101 XOR 00100000 -------- 11001101 = Bit 5 is zero now bit 5 = 0 | v 11001101 XOR 00100000 -------- 11101101 = Bit 5 is one now Quote Link to comment https://forums.atariage.com/topic/287910-screen-memory/#findComment-4220870 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.