ZX Power #03
31 декабря 1997 |
|
Likbez - Automatic creation of masks for sprites.
Automatic creation MASK for sprites Bezugly Andrew (Ticklish Jim / BIS), 1997 _________________________________________ Hi all, who decided to spend it-Nogo your time reading this little article. Its theme, I think it will be of interesting to all those who are involved in capacity-games, whether artist or pro-mist. So ... Mask for the sprite. How many seychasmozhno find vserazlichnyh sprite re-daktorov, but how many of them are pro-dure create a mask for a sprite artist's indifference? Personally, I have not videlni one (this, incidentally, one of prichinpochemu I do address this problem-I). It is quite possible, of course, that yaprosto and simply do not know about this editor (Not an artist because in the end). However, I hope that after reading this article, our coders who closely involved in the creation of programs for working with graphics (just is not see new photo editor. Is ART STUDIO will remain only, which is more or less convenient I use it? ") in new versions of their program will introduce the function AUTOMASK. Probably their version of the algorithm described below would look much more attractive My (I'm not a programmer). To get started is to answer two questions. First: what is the mask and why is it necessary? Answer is almost not necessary. Those who makes the game and so everybody knows, and those who does not, can read or INFORKOM'ovskih publications, or see DIZZY on and see why it is not merges with the background, and separated the thin edge. The second question is: what (and for whom) you want to automatically mask? Answer like this: first, the artists no longer have a headache, when before them is a coder with yells, "Why your bun on the right seems a continuation of chair ?!?!", because quite human inattention (more would create a mask much more boring and laborious than to draw face brave Santa Clause or Russianised Dizzy); secondly, when under hand is not the artist, who can be "Go after" for "the continuation of the chair, and mask needed badly, the whole problem can be solved in seconds, third-and last, imagine the following situation: You have an ambitious plan to enter the game mode is going down for the items, or you want to be active subjects (well, those Dizzy who constantly takes it, then throws) do not "take a bite" anywhere on the half of familiarity background, however, places at ext. schedule was nearly empty (because there is support for every conceivable "Wash ";-). Here and useful program that will dynamically create mask only for the sprites, which for example, involved only in that screen (yes, in that;). There are three algorithm (unless, of course, someone will come up again, then let let you know write to the registry :-). Third, the easiest and fastest, is described in more detail at the end of this narrative. The first two are briefly described in view of low feasibility of their application (After reading some try to count how many times the 2-nd algorithm will faster the 1 st and 3 rd - faster 2-nd. This is so for the sake of diversity). 1. Method "vykusyvaniya. As it turned out, it was the most obvious option. The principle of its operation is very simple. Take the sprite is created equal he largest buffer masks, which we fill # FF. Found, created, filled and began to engage the most interesting thing: Scan the base sprite. Ie take a byte of the sprite and check the 7-bit (if the scan goes from left to right). If bit off, then proceed to the next bat without reference to the buffer mask. Otherwise, we find the corresponding bits in the pattern mask and extinguish it, but at the same time reset all the bits around and found neutralized (just note that it is necessary check where exactly is this bits. I will not list all possible options, only to say that there are only 9). After that, go back to the sprite and go to the next bit. And so to the finish. As a result, we obtain excellent mask and a huge break in runtime. So swing this wild idea to implement this algorithm, a better read on the following, which in principle is a modification (Quality) of the preceding. 2. Method "vykusyvaniya # 2." Looks a little bit at first. Once the buffer we fill in # 00. Again scan. Only here, if we found included bits immediately check the district (the same 9 conditions, anywhere they do not share:) for no other of ones. If at least one there, then throw this thing and move on to further line scan sprite. But in that case, when around 1 the crowd was 0 (in an amount of from 3 to 8), we immediately run into the buffer mask, find the appropriate place and put a bunch of units (from 4 to 9). After a complete pass sprite we take the buffer mask and invert the contents. As a result, we have perfect mask and a little less break (Ie tea you will not have time to drink) in their work. But as it is interesting to observe the work of BASIC-program creates this proverbial mask ... Yes, even without the compiler. Can you imagine? No, do not cheat, that's when we ourselves experience this, then I believe. And now we come to the best algorithm. 3. Shift method. It's very simple. Reserve buffer under the mask. Take the part of the sprite (without top line of the image) and throw it in the buffer - this is equivalent to a shift upwards point (namely for the sprite into memory, rather than images on the screen, because In this case there are additional. problems that nobody wants). Then take the other part sprite (not the bottom line, that is, minus the width) and do OR with the contents of the buffer and address of the buffer increase on the same the amount by which we reduced the length of sprite in the first two manipulations (eg, width = 18 familiarity with a total length sprite = 1728 bytes, then we toss and a 1-m, and the 2-m cases 1728-18 = 1710 bytes). As a result, the buffer we got shifted the image up and down on one pixel. It remains only to identify side of the border. There quite simply, we take byte of the sprite, we shift it to the side much more like us and OR'im it with resp. byte buffer mask obtained the result is buffered. Then we do All the same, but in the opposite direction and immediately after the OR CPL'im to mask adopted its legal form. As a result, buffer is a quality mask any complicated and not very sprites, and pause ... Where is she? .. As an example, I quote let still not perfect, but quite workable and tested program, with commentaries. All very simply, I think there should be no ambiguity. The program will automatically create MASKS for sprites AUTOMASK v1.02 (C) 1997 BROKIMSOFT (C) 1997 Idea by TICKLISH JIM, STEELER (C) 1997 Code by TICKLISH JIM WARNING! This version is designed only to demonstrate the algorithm AVTOMASKI, so before you start to clear the buffer MASKS. Who wants to, of course, can alter the procedure formation of borders, good opportunity there. ORG 40000; for illustrative purposes only INSERT "MONAST" SPR_PL EQU 40000; start address Sprite SPR_BUF EQU 30000; ADDRESS BUFFER MASK ORG 25000 LD HL, SPR_PL; HOME Sprite LD (SPR2 +1), HL LD A, (X_SIZE); X_SZ LD (L1 +1), A LD (L2 +1), A LD (L3 +1), A LD B, A LD A, (Y_SIZE); Y_SZ ADD A, A ADD A, A ADD A, A LD HL, 0 LD D, 0 LD E, A MULTADD HL, DE DJNZ MULT ; In HL Length of machined Sprite LD (X1 +1), HL ; LD (X0-2), HL; FOR DEMO LD (L4 +1), HL ; Skidded LENGTH IN BC LD HL, SPR_BUF PUSH HL PUSH HL PUSH HL EXX POP DE SPR2LD HL, SPR_PL PUSH HL L2LD A, 0 ADD A, E LD E, A JR NC, L1_1 INC D ; HL '= SPR_PL, DE' = SPR_BUF + X_SIZE L1_1EXX POP HL POP DE L1LD A, 0 ADD A, L LD L, A JR NC, X1 INC H ; HL = SPR_PL + X_SIZE, DE = SPR_BUF X1LD BC, 0 LOOPDEC BC DEC A JR NZ, LOOP ; BC '= LENGTH Sprite-X_SIZE SCROLLPUSH BC LD A, (DE) EXX OR (HL) EXX OR (HL) LD (DE), A EXX LD A, (DE) EXX OR (HL) INC HL INC DE EXX OR (HL) LD (DE), A INC HL INC DE POP BC DEC BC LD A, B OR C JR NZ, SCROLL ; This part to set an upper and ; Lower Bound create masks. Written by no means perfect and is not optimal, but quite suitable for demonstration, and a place to use their own ideas remains. LD HL, 10072 ; RESTORE HL ' EXX ; Change to Main KIT registration; DOM POP HL L4LD BC, 0 PUSH BC EX AF, AF ' XOR A JR ROLL_RT +1 ROLL_RT EX AF, AF ' LD E, (HL) RR (HL) EX AF, AF ' LD A, E OR (HL) LD (HL), A INC HL DEC BC LD A, B OR C JR NZ, ROLL_RT , Denote the right BORDER MASKS DEC HL POP BC EX AF, AF ' XOR A JR ROLL_LT +1 ROLL_LT EX AF, AF ' LD E, (HL) RL (HL) EX AF, AF ' LD A, E OR (HL) CPL; INVERSION BYTE MASK LD (HL), A DEC HL DEC BC LD A, B OR C JR NZ, ROLL_LT ; THIS SECTION indicating the last, left, ; BORDER OF MASKS AND SIMULTANEOUSLY Inverts ; BYTES to end up Get real ; BYTE mask. ; These two procedures can be combined into , One that significantly speed up the work ; Program. Besides the inversion of bytes ; Masks can do is direct , The derivation of the image on the screen. RET , Variable, indicate the size ; Sprites (in familiarity) X_SIZEDB 18 Y_SIZEDB 12 ; DEMONSTRATION ON MASKS OR AS A RESULT ; The subprogramme C ADDRESSES ; SPR_BUF will be located Sprite VPECHA; culated in Create a mask. ; DEMO LD HL, SPR_BUF ; SPR3 LD DE, SPR_PL ; LD BC, 0 ; X0 LD A, (DE) ; OR (HL) ; LD (HL), A ; INC HL ; INC DE ; DEC BC ; LD A, B ; OR C ; JR NZ, X0 ; RET As you can see an example of this program is good. However, its application can be considered more or less appropriate Is that some sort of editor, sprite but certainly not in the game program, where requires a high speed of the procedure with a relatively small amount memory used by vserazlichnye buffers. In general, the title of this REALTIME procedure is not explicitly drawn. The following program, I dare to hope, will be more it is useful from a practical point of view. As usual, comments are attached. The algorithm works the same as was used in the previous program. Naturally, I do not claim to absolute truth (I repeat: I not a programmer, but only the attacker, who was forced to wallow in koderstve); sure - if you prefer, you can do better than he is, therefore, I say this is just an example. Disassemble, Experiment and use, because the scope of this program is very wide, especially in games of the genre ARKADE-ADVENTURE. When we use two buffers for 8 bytes each (sprite width of 8 familiarity; can, of course, more if necessary), ie 16 bytes total. ORG 40000 ;. INCBIN tree ; File 'tree' - this is handled by sprite ORG 25000 JR START WD DEFB 5; width of sprite in the familiarity HG DEFB 7; height sprite familiarity PL DEFW 40000; start address sprite START LD IX, (PL) LD A, (HG) ADD A, A ADD A, A ADD A, A; height multiplied by 8 , Ie transferred to the familiarity ; Pixels (lines) LD (M1-1), A LD A, (WD) LD (M2 +2), A LD (M2-1), A LD (BF0-1), A LD HL, 16384; address on the screen, where ; Be displayed sprite , With a mask DEC A LD E, A LD D, 0 ADD HL, DE; increased it to (Shea , Width-1), t.k.pechat ve ; Exists a right to left LD (PR_LN +1), HL ; LD HL, 18432; MASK_RESTORE_BUFER ; LD (PR_LN +4), HL ; Specify the address of the buffer to be entered ; Background for a sprite. In this case, I had ; Just do not use. XOR A LD (TT1), A , Blocked a clearing buffer (at startup And must be cleaned) CALL REAL_MASK ; Accessed directly print program ; Sprite with a mask. RET REAL_MASK LD B, 0, count lines sprite M1PUSH BC EX AF, AF ' XOR A; folded flag C in F ' EX AF, AF ' LD HL, BUF0; buffer address for the form ; Formation of the first part ; Tea Mask (shift ; Up-down) EXX LD HL, BUF1; address buffer ; Final mask , (Left-right and Information ; Version) EXX LD B, 0, byte count (the width ; On) M2LD A, (IX +0) OR (IX +0) INC IX LD E, A OR (HL) LD (HL), E; record in BUF0 results ; Tat shift up and down INC HL EXX LD E, A LD D, A EX AF, AF ' RR E; at the same time shift vpra ; During imposed on the pre ; Preceding result and , Enters the resulting ; Bytes BUF1 EX AF, AF ' LD A, E OR D LD (HL), A INC HL EXX DJNZ M2 LD (SPR +1), IX; IX indicates that at ; Chalo next line ; Sprite LD (BF0 +1), HL; HL indicates ; Next byte buffer ; BUF0 CALL PR_LN; print the line ; Sprite with a mask POP BC LD A, B DEC A CP 1 JR NZ, STOP And if we are left untreated village; glacial line of the sprite, then turn on ; Clean main buffer (BUF1), for ; Follow-up and block increments, of IX, in order not to climb beyond nuzh; Nogo us sprite. XOR A LD (M2 +2), A LD A, # 36 LD (TT1), A STOPDJNZ M1 EXX LD HL, 10072; restored HL ' EXX RET PR_LN LD HL, 0; here will be addressed in ; Screen to print ; Sprite (right to left) ; LD DE, 0; buffer address for the background ; (Not fix). PUSH HL EXX LD B, 0, width BF0 LD DE, 0; DE '= BUF0 + width, ; HL '= BUF1 + width XOR A; folded flag C to F T1 DEC HL; HL 'set to on ; Recent bytes used ; Acterized part of the buffer ; BUF1 DEC DE; same for BUF0 LD A, (HL) RL (HL); shifted to the left PUSH AF OR (HL); imposed on the initially ; Initial EX DE, HL OR (HL); imposed on the shifted ; Right TT1LD (HL), 0, clears the buffer (if , Last line) EX DE, HL CPL; invert the byte scale , Ki EXX LD C, (HL); bytes saved background ; (Not fix). AND (HL); used bytes ; Mask PUSH HL SPRLD HL, 0; HL points to the beginning ; Lo ff. line AB. DEC HL; now at the end of the formation ; Oped OR (HL); imposed byte image ; Motion LD (SPR +1), HL; changed pointer , Addresses the JWP. POP HL LD (HL), A; brought to the screen B , With a mask DEC HL; reduced address Pec , T ; LD A, C ; LD (DE), A; log into the buffer B ; Background ; INC DE EXX POP AF; went to print the following ; Blowing bytes AB. DJNZ T1 EXX POP HL CALL NEXT_L; next line in the equivalent ; Wound LD (PR_LN +1), HL; remember ; LD (PR_LN +4), DE; remember the lyrics. hell ; Res buffer RET ; Procedure for calculating the lyrics. line in the screen, ; To explain anything to anybody, I think not. NEXT_L INC H LD A, H AND 7 RET NZ LD A, L ADD A, 32 LD L, A RET C LD A, H SUB 8 LD H, A RET BUF0 DEFS 8, the main buffer BUF1 DEFS 8; auxiliary buffer , The value of both is the maximum possible; natural width of printed sprites. ; And remember that when you print background preserves; Xia backwards - do not get confused (if ; Will be using, of course, is my ; Procedure) during recovery. If anyone ; Unclear, then explain: for example, the width ; Sprite is 3, then the background will be preserved; nyatsya my program is not standard , 1,2,3, 4,5, etc., and in another way - that is, , 3,2,1,6,5, 4,9,8,7, etc. I have not cleaned And this small inconvenience because it ; Really small. . . . And finally, some more common phrases. This article was begun in 1997, and last revised specifically for Journal ZX-POWER is dated April of this year. Quite naturally, the material could become obsolete. However, I still has not appeared human sprite-editor'a, which tries to make can be compared with SPREDIT2.0 (1993!), Not to mention a better program (I've heard that SPRITE MASTER v5.0 is something stunning, but alas - not seen. If someone does not sorry, we share the program that my address is listed at the end of the article). Therefore, we how to use and continue enjoy their own procedure. If anyone is interested, I can advise to delve into the Czech toy TOWDIE. There also used avtomaska, moreover, the rate is a clear leader - 11 cycles per byte. However, there is a "but" - mask is not very high quality. Say, for sprite width of 2 bytes (not more) the mask will be satisfactory, of course, if you do not mind that character will merge with the background top and bottom. However, just download TOWDIE and take a closer look, all at once become clear. Further, to illustrate the above program in Appendix ZX-POWER'a written to two files: "scr1" and "scr2". The first - an example of the construction of the game screen without the use of masks for sprites the second - using. But it's best to download "CSCDV_D2" - where all the rooms are built specifically with the use of procedures avtomaski. Of course, performance has been and remains sensitive issue, but all are known to pay. Although the arcade adventyur speed construction of the screen is not is the determining factor, right? For those interested, I can say that the maximum time it takes for my program to print the game screen of 99i sprites with a mask (in practice, of course, so much is not necessary) is 2 sec. By the way, on the same drive should be write file "REAL". It is a ready program that creates the data block on a "mask byte - byte sprite. REAL written in assembly language STORMv1.1 (interestingly, he's just my "kill" the disks with records, or both? In my view the guys from X-TRADE nevertheless necessary to consider that not all are TEAC'i) and then exported to a format TASM2.0. On this, let finish. A for those who want to contact me here my coordinates: Tel: (0472) 43-37-97 (18:00 to 22:00) Address: 257005, Ukraine, Cherkasy, Shevchenko, d.367 / 1 kv.37, Bezuglov Andrey 04/20/1998. TJ / BIS _________________________________________
Other articles:
Similar articles:
В этот день... 21 November