Welcome, Guest. Please login or register.

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - ssr86

Pages: 1 [2] 3
Programming / Sprite flipping and shifting methods
« on: 2015.November.10. 22:43:01 »
Here's a code example for flipping a standard sprite "in place".
You would need to call this only when the sprite changes it's facing direction.
This method doesn't need an additional buffer.
The sprite data is stored normally.

It should be good in cases when the sprite seldom changes the direction it is facing.
Maybe when the direction of the sprite's standing pose changes only after a jump then the sprite data for the standing animation could be reversed during the jumping animation...

The code is written for sprites with even width but can be modified to work with odd widths too...
Here there's a byte pair in the middle and for the odd version there would be a single byte to reverse.
The values to add to hl and de to get to the next line of the sprite data would slightly change too.

The lookup table at the end is for 16-color mode pixels.

Code: [Select]
                     ld b,reverse_table/256                                          ;; bc is used for accessing the reversed byte values
                     ld de,sprite_data+sprite_width_in_bytes-1                       ;; de = address of the end of the first sprite data line
                     ld hl,sprite_data                                               ;; hl = address of the sprite data

                     ld b,sprite_height

                     ld a,(de)          ;; get left byte
                     ld c,a             ;;
                     ld a,(bc)          ;; reverse left byte
                     ex af,af'
                     ld c,(hl)          ;; get right byte
                     ld a,(bc)          ;; reverse it
                     ld (de),a          ;; store it on the left side of the sprite data line
                     ex af,af'
                     ld (hl),a          ;; store the left byte on the right side of the sprite data line
                     dec e              ;; here I assume that the sprite data is aligned (not necessarily page aligned)
                     inc l              ;;

                     ;; repeat the part above k = (sprite_width_in_bytes / 2 - 1 ) times
                     ;; for the last pair of bytes in the line loop we can drop the dec/inc part:

                     ld a,(de)
                     ld c,a
                     ld a,(bc)
                     ex af,af'
                     ld c,(hl)
                     ld a,(bc)
                     ld (de),a
                     ex af,af'
                     ld (hl),a        

                     ;; get to the next sprite data line

                     ld a,l
                     add a,sprite_width_in_bytes/2+1
                     ld l,a
                     adc a,h
                     sub l
                     ld h,a

                     ld a,e
                     add a,3*sprite_width_in_bytes/2-1
                     ld e,a
                     adc a,d
                     sub e
                     ld d,a

                     djnz  flip_line_loop


org ($/256+1)*256
db $00,$02,$01,$03,$08,$0A,$09,$0B,$04,$06,$05,$07,$0C,$0E,$0D,$0F
db $20,$22,$21,$23,$28,$2A,$29,$2B,$24,$26,$25,$27,$2C,$2E,$2D,$2F
db $10,$12,$11,$13,$18,$1A,$19,$1B,$14,$16,$15,$17,$1C,$1E,$1D,$1F
db $30,$32,$31,$33,$38,$3A,$39,$3B,$34,$36,$35,$37,$3C,$3E,$3D,$3F
db $80,$82,$81,$83,$88,$8A,$89,$8B,$84,$86,$85,$87,$8C,$8E,$8D,$8F
db $A0,$A2,$A1,$A3,$A8,$AA,$A9,$AB,$A4,$A6,$A5,$A7,$AC,$AE,$AD,$AF
db $90,$92,$91,$93,$98,$9A,$99,$9B,$94,$96,$95,$97,$9C,$9E,$9D,$9F
db $B0,$B2,$B1,$B3,$B8,$BA,$B9,$BB,$B4,$B6,$B5,$B7,$BC,$BE,$BD,$BF
db $40,$42,$41,$43,$48,$4A,$49,$4B,$44,$46,$45,$47,$4C,$4E,$4D,$4F
db $60,$62,$61,$63,$68,$6A,$69,$6B,$64,$66,$65,$67,$6C,$6E,$6D,$6F
db $50,$52,$51,$53,$58,$5A,$59,$5B,$54,$56,$55,$57,$5C,$5E,$5D,$5F
db $70,$72,$71,$73,$78,$7A,$79,$7B,$74,$76,$75,$77,$7C,$7E,$7D,$7F
db $C0,$C2,$C1,$C3,$C8,$CA,$C9,$CB,$C4,$C6,$C5,$C7,$CC,$CE,$CD,$CF
db $E0,$E2,$E1,$E3,$E8,$EA,$E9,$EB,$E4,$E6,$E5,$E7,$EC,$EE,$ED,$EF
db $D0,$D2,$D1,$D3,$D8,$DA,$D9,$DB,$D4,$D6,$D5,$D7,$DC,$DE,$DD,$DF
db $F0,$F2,$F1,$F3,$F8,$FA,$F9,$FB,$F4,$F6,$F5,$F7,$FC,$FE,$FD,$FF

Other methods will follow as I have to adapt the examples for the Enterprise...

EDIT: added a working example...

Programming / Some palette-swapping methods for sprites
« on: 2015.November.10. 22:26:46 »
Imagine a team-sports game where one team should have red uniforms and the other blue. Or maybe you'd want to have some of the baddies appear in different colors? Or just have some sprites(/letters/digits) appear to flash... One way to obtain this effect would be using a lookup-table for translating each byte of the drawn sprite to a new "reordered" color palette. You could also use a separate set of the same sprites but with changed color usages I present here one other method for this. It's somewhat limited but maybe someone finds it useful nonetheless.

Basically the method could be broken into three steps:

1. store all data for the sprite rotated one bit left (right) - like performing a rlca (rrca) instruction on all its bytes
2. before drawing a byte of the sprite data rotate it using rlca (rrca)
3. have a separate drawing routine for each "palette".

Below I assume using mode 0.

The table shows how the colors change when we rotate data stored in standard form (not pre-rotated):

Code: [Select]
3-2-1-0  || 2-1-0-3 || 0-3-2-1 || 1-0-3-2
 standard || 2x_rlca || 2x_rrca || 4x_rrca = 4x_rlca
    0     ||    0    ||    0    ||    0
    1     ||    2    ||    8    ||    4
    2     ||    4    ||    1    ||    8
    3     ||    6    ||    9    ||    c
    4     ||    8    ||    2    ||    1
    5     ||    a    ||    a    ||    5
    6     ||    c    ||    3    ||    9
    7     ||    e    ||    b    ||    d
    8     ||    1    ||    4    ||    2
    9     ||    3    ||    c    ||    6
    a     ||    5    ||    5    ||    a
    b     ||    7    ||    d    ||    e
    c     ||    9    ||    6    ||    3
    d     ||    b    ||    e    ||    7
    e     ||    d    ||    7    ||    b
    f     ||    f    ||    f    ||    f
Note that color 0 and f are constant for all 4 palettes.
Standard order of color bits in a mode 0 pixel is 3-2-1-0, hence I write 3-2-1-0 to denote the standard palette. Rotating the byte by 2 bits will change the order of the color bits of pixels without repositiong the pixels (as when you rotate the pixelbyte by an odd number of bits).

Why storing the data in pre-rotated form?
The initial rotation allows us to even the drawing times for 2 of the possible palettes - the standard palette [3-2-1-0] and 2x_rlca [2-1-0-3] or 2x_rrca [0-3-2-1] - depending on the direction of the initial rotation of data. Both drawing routines need then just one additional rotation instruction. Although for sprites that wouldn't use palette changes it'd be better to store them normally and have a separate standard drawing routine that doesn't use the additional rotation...

Code for drawing one opaque pixel byte:
Code: [Select]
;; hl=^sprite_data
;; de=^screen
ld a,(hl)
ld (de),a
inc de
inc hl

Code for drawing one masked pixel byte:

Code: [Select]
;; hl=^sprite_data
;; de=^screen
;; bc=^mask_table
ld c,(hl)    ;; get pixel byte and use it as mask_table offset
ld a,(bc)    ;; get mask of the pixel byte
and (hl)    ;; mask it
or c           ;;
rlca/rrca    ;; rotate it
ld (de),a    ;; save to screen
inc de        ;; go to next screen position
inc hl        ;; go to next pixel byte

Without the preliminary rotation of data, one routine would need 2 rotations and the other none.
[Note that in the case of routine with one rotation we could also try and use self modyfying code to change all rrca to rlca or vice versa... Although I don't know if this would be worth anything...]
The other two palettes need 3 rotations of each byte, so they're are slower to obtain.

The code for drawing one pixel byte:
Code: [Select]
;; hl=^sprite_data
;; de=^screen
ld a,(hl)
ld (de),a
inc de
inc hl

In other words:
There are 4 such "palettes" in mode 0 (2 in mode 1) but only 2 can be obtained with just 1 additional instruction (rlca/rrca) in the pixel-byte drawing code. The other two would need adding three rotation instructions to the drawing code. Of course if we would have only one set of sprites (say the player character) that is unique to the game (that is no other character in the game uses his data) then we could use one separate routine that rotates each byte of the sprite data buffer by 2 bits for changing his palette permanently... Repeating this operation four times would return the sprite to its standard palette.

Such routine would run the code below for each byte of the sprite data:
Code: [Select]
;; hl=^sprite_data
ld a,(hl)    ;; get sprite data
rlca/rrca    ;; rotate 1 bit
rlca/rrca    ;; rotate 1 bit
ld (hl),a    ;; save sprite data
inc hl

Other possible usage:

This method allows "color-flashing" of a sprite. This could be achieved in three ways:
1. Adding a separate routine that would rotate every byte of the sprite data (the sprite's buffer). After four calls the sprite would return to its normal palette.
2. Similar to the above but this time we want the subroutine to rotate the screen data where the sprite was drawn. This assumes that you are not redrawing the sprite during the flashing (because you would erase the effect). Also you can't touch the bytes that where masked or skipped during drawing of the sprite because you would corrupt the background.
I think this method should be useful if you wanted to make the time or score display flashing. If the timer would be redrawn once per second then you could rotate the screen data bytes where the digits were drawn - if the digits were not masked... Although I think that it is possible to modificate the routine for masked sprites - you would have to skip rotating the transparent bytes of the sprite and for the masked bytes you would have to mask them again to obtain the part of the byte which belongs to the sprite, rotate that and combine it with the background part of the byte...
3. Having all 4 drawing subroutines and drawing the sprite using a different routine every time. 


Comparison to the other two approaches (that I could think of):
1. using lookup table
- with the presented method you don't need lookup tables so you save some memory (each table would take 256 bytes and you need at least one)
- both methods would need a separate routine for each palette, although with lookup tables you could actually get away with just one routine by changing the pointer to the color conversion table before each call
- lookup tables allow more freedom with the palette choices (only four restricted palettes for the presented method and you have to choose your initial palette wisely)
- using lookup tables is slower

2. one set of sprites for each palette
- would be the fastest approach but the memory cost would be just too expensive for heavily animated objects

Other disadvantages:
- can't use ldi for drawing opaque bytes

Programming / Packed sprites
« on: 2015.November.10. 22:05:13 »
I thought that maybe I could put here some examples for drawing "16 color mode packed sprites"  that I once wrote with cpc in mind but most should still be valid for the Enterprise too...

I don't think anyone will ever need to use the "techniques" described here, but nevertheless it was fun to do...

I'll try to put them in seperate posts for better readability...

We can divide the methods based on how many bits we will use per pixel... So for 16 color modes where each pixel is 4bits we could cut it to 3,2 or 1 bit per pixel...
Drawing will be considerably slower but we can save some memory... Although most of the time speed is the priority, so... not very useful I guess.


For the 3bpp we assume that the sprite data is stored in three byte packages.
One package contains pixel data needed for drawing four pixel bytes.
This way we save 25% of memory needed to store the sprite data.
We zero one bit pair of each pixel byte, so the number of different colors that can be used for the sprite graphics is limited to eight.

If we count how many of the three significant bit pairs of the four packed pixel bytes we store in each byte of a package, we get the following combinations:

1. |3-1|3-1|3-1|
2. |3-1|2-2|3-1|
3. |1-1-1-1|2-2|2-2|
4. |1-1-1-1|1-1-1-1|1-1-1-1|

Where, for example, 1-1-2 means that in this particular byte we store one bit pair from one pixel byte, one bit pair from one other pixel

byte and two bit pairs form yet another pixel byte.

In the package format desacription, pij means j-th pixel bit pair of the i-th pixel byte.

I present only the actual depacking-drawing code...
These are not complete sprite routines - you would have to add loops and next_line code.

Note that for the 3bpp and 1bpp packing, the sprite's width should be dividable by four and for 2bpp it should be dividable by two.

Code: [Select]
;; 3BPP - STORING METHOD: |1-1-1-1|2-2|2-2|
;; package format:
;;       1st byte           2nd byte           3rd byte
;; | p00_p02_p01_p10 || p12_p11_p32_p31 || p20_p21_p22_p30 |
;; hl=^sprite
;; de=^screen
;; b - used as an auxiliary register
;; c - preloaded with 11110000b bit mask
         ld b,(hl)    ; get first byte of the package
                        ; this byte contains all bit 0 pairs of the four pixel bytes
     inc hl            ; go to next byte of data
; extract first pixel byte
     ld a,(hl)    ; get second byte of package
            ; this byte contains bit 2 and 1 pairs of first two pixel bytes
     and c        ; mask to get only the data for the first pixel byte
     rrc b        ; now get the bit 0 pair for this pixel
                        ; from the first group byte (stored in b)
            ; and get it into it's place in the accumulator
            ; we achieve this by rotating the b register right
            ; this loads it's least significant bit into carry
     rra        ; then we use rra to load the carry flag into
            ; the most significant bit of the accumulator
     rrc b        ; we have to do this twice
     rra        ; to move the pair of bits

         ld (de),a    ; save to screen
         inc de        ; go to next screen position
; extract second pixel byte
         ld a,(hl)      ; reload the second byte of package (we need to extract from it the bit pairs of the second pixel)
         rlca           ;
         rlca           ; rotate four times to swap the nibbles
         rlca           ; and get the pairs p12_p11 into place
         rlca           ;
         and c          ; mask to isolate bits for this pixel byte
         rrc b          ;
         rra            ; extract the bit 0 pair from the first byte of package
         rrc b          ; and load it to accumulator to complete the second pixel byte
         rra            ;
     ld (de),a    ; save to screen
     inc de        ; go to next screen position
     inc hl         ; go to next data byte
; for pixels three and four we repeat all the
; operations for the first two pixel bytes
; extract third pixel byte
    ld a,(hl)
    and c
    rrc b
    rrc b
    ld (de),a
    inc de
; extract fourth pixel byte
    ld a,(hl)
    and c
    rrc b
    rrc b
    ld (de),a
    inc de
    inc hl

Programming / Some ASM code snippets/ideas
« on: 2015.November.05. 18:17:59 »
Well, I thought to open a topic where we could share some useful code examples or ideas.

1. A method for switching buffer addresses (for drawing to the correct buffer) when using double buffering.

It comes from the source code for Rigor Mortis for the CPC which is based on disassembly of Elmar Krieger's (author of "Prehistorik 2" and "Super Cauldron" for the amstrad) game engine. The Source (among many others) can be found at http://cpcrulez.fr/coding_menu-src.htm

We prepare a LUT for the two buffer addresses:
Code: [Select]
first_buffer_address dw $0000
second_buffer_address dw $4000
...and we use a 16-bit variable for choosing between the two addresses:
Code: [Select]
double_buffer_offset dw $0002
We use it to offset to the wanted address so should be $0000 or $0002.
Everytime we want to change the offset we do:
Code: [Select]
ld hl,double_buffer_offset
ld a,(hl)
xor 2
ld (hl),a
To get the correct buffer address:
Code: [Select]
ld bc,(double_buffer_offset)
ld hl,first_buffer_address
add hl,bc
Now the wanted address is stored in memory at hl, so to get the address:
Code: [Select]
ld e,(hl)
inc l
ld d,(hl)
The address is now in de.

Earlier I switched the addresses by storing additional address variables for the active and hidden buffer address and switch the two for every game frame and also have a variable that stored the number of active buffer (0 or 1), because many times you have to choose which sprite background buffer to use (for which screen).
I find the one by Elmar Krieger to be somewhat cleaner and prettier...

2. Second is something like the strategy pattern in OOP (at least reminds me of it)...

When you want to use some optional code, like for example an optional gfx effect, additional game mode mechanic, switching music or something like that then you can do:

in your mainloop:
Code: [Select]
call something_dispatcher

the called subroutine is a simple jump:
Code: [Select]
jp something

You can set the jump to what you want it to do...
For example for switching music/sfx/no sound you could set the dispatch address to the right routine...
When you don't want to do the "something" you set the jp address to a ret:
Code: [Select]
To set the dispatch address to it:
Code: [Select]
ld hl,something_dispatch+1
ld (hl),just_a_ret

Else you can do conditionals every time but the presented method is a little quicker and cleaner (at least for me)...
One disadvantage would be that it's self modyfying code...

Games / WIP: Hat Trick EP
« on: 2015.October.19. 23:26:33 »
Although the competition hasn't started yet, I wanted to present a WIP of Hat Trick port. I've started the project about a week or two ago. Hat Trick is a one-on-one (plus goalkeepers) hockey game. The game was released for c64, dos and atari7800 and arcades. The atari version even had its source code released to the public some time ago. However I don't like that version. Haven't played the dos version. We had c64 so I've played it very often with my brother. Great two player fun. We still play it from time to time on an emulator.
Unfortunately there was no z80 cpu version...

Current state:
- puck movement
- goalies movement and animation
- puck with goalie collision (although not yet calibrated... but the checking of hitboxes is implemented)
- checking for goal
...so kinda a pong clone at the moment

Graphics are currently based on the dos version - 320x200 with 4 colors.
As there won't be used any platform specific stuff (excluding the char mode for panel and title screen) this should be easy to port to the cpc...

Looks that 50fps with single buffer and no-flicker should be feasible...
Puck is a compiled sprite, goalies are compressed sprites and the players should be at least compressed sprites. The problem is that for the players one needs 8 (directions) * 4 (preshifting) = 32 sprites. However each player has to have different color so we get 64 sprites needed... I don't know how much memory is needed for that, but I want to go with 32 sprites and use a mask table for changing colors... That way, if later I would want to add additional players, I could make them also of different color (using checkerboard?).
For that I have to make some improvements to my sprite conversion tool...

On the screenshot:
white border = erasing goalies
blue border = drawing goalies
red border = erasing puck
green border = drawing puck

I'm not planning to do one player mode (I have no clue about implementing ai and it's not that fun... I think).
I have a few ideas for additional gameplay/options/features but for now I'm doing a port... I fear implementing the inertia, player momevemt and proper collision system... Maybe I will have to do some reverse engineering...Hope not...

As always - don't mind the colors...

(I hope that posting this wasn't another bad idea of mine)

Display / Ep128 display on a crt TV
« on: 2015.October.18. 19:04:35 »
On my old and small tv:
- I see only about 336 pixels in width and the screen is shifted one character to the right
- I see only about 256(?) pixels in height - starting from the 16th line (from a 288 line screen)

Is this normal or is it just my tv?

That would mean that ep has considerably bigger pixels than the c64 (on the ep I have no place for the c64's side borders), I guess...

Games / Problems with "Midnight Resistance"
« on: 2015.October.18. 19:00:27 »
I have problems with the game on my Ep128... The version from the sd card hung up on the first level boss. The version from gamebase hungs up on the second level end boss (the one shooting rockets)... Tried the gamebase version on emulator and the game didn't hang... (the hanging is repeatable on the real machine)...

Other topics / Maybe we should organize a GameDevCompo?
« on: 2015.October.10. 09:55:30 »
Looking at this years CPCGameDev, I've been thinking that maybe we could organize a similar competition for the Enterprise128... If a party like the one in May would take place in the next year then we could make that the deadline and place of announcing the results.

The key would be to raise a "decent" sum of "motivation money";p so that the participants would be rewarded for their time and effort... (I doubt we could get some "outside" sponsors...)
If we could rise some more money then we could do more categories - like democompo or a seperate one for ports of existing z80 games. Also there could be a graphics compo I guess... Because of lack of tools a musiccompo would not be a good idea (we would see more or less ay conversions only...)...

There would be some more than a half a year of time... So people could learn the characteristics of the machine and programming for it... We could invite people from spectrum, amstrad and msx communities (they could even just enter with ports of some of their productions for their main machines)...

I think that Ep128 is an especially graceful machine for demos...

I think a good "motto" for such a venture would be "Remember the fallen" (at least I like the sound of that;p) or "Don't forget the fallen" - you know what I mean...

So... what say you? Would it be worthwhile?

Programming / Non-standard graphic modes
« on: 2015.September.22. 22:59:23 »
Saw a movie about atari software-driven graphic modes. Maybe some technics that are used on the atari could be utilized on the ep... Atari seems to also use something like the lpt (display list). Although I guess that some will use sprites for coloring up...

First "software-driven" (I don't know if I can say that) modes I could list are the "square-pixel" (well don't have to be "square" - just vertically stretched) modes like I'm trying to use... (atari seems to have the 4 color variant. Game "Yoomp!" uses it https://www.youtube.com/watch?v=UqmyLKG1l-4).

Someone knows about another?
"Interlace demo" mode counts...
Zozolace demo has another one too...
Changing palette at every scanline (fix bias every two) could also count as such mode, I guess...

I think that one of such atari modes uses vbi to switch between two character sets every frame to get the illusion of more colors... Well actually wuoting the author:
"In my game "Gem Drop", I used a simple VBI to flip between two character sets (no palette changes or DLIs) to give the illusion of 13 colors in ANTIC 4 mode."

Programming / Use of character modes for games?
« on: 2015.September.21. 21:11:20 »

Just a rant I guess. Maybe someone has some experirnce with these topis and could share...

Unfortunately I don't find the modes very useful for an ingame engine for a more graphic game...

The problem for using the character modes in games is the unfortunate lack of hardware sprites... This narrows the possible uses for the modes. That's because you have to share font matrices with sprite-building blocks. This way you limit the number of different objects/animation frames that can be used...
And you would need to constantly copy another animation frame's building-block to the font memory (but good only for the main character; when more enemies and every object in a different animation frame then you run out of characters... could not true for smaller sprites I guess).

There are games like Astro Marine Corps or Invasion of Zombie monsters for other z80 computers that "emulate" a character based mode. However this "emulation" takes down the limit of possible font sets per line etc. But this is not as fast and optimal as a real character mode could be.

Programming / Has Nick got any useful bugs?
« on: 2015.September.21. 20:56:40 »
I just wanted to ask if maybe Nick has some useful bugs like c64's vic has... Maybe something to "shift" the screen by half byte or somwething like that. I know Nick is a very "elastic" video chip but maybe there's something worth mentioning.

Games / Cartridge games
« on: 2015.September.18. 20:07:51 »
Is Enterprise capable of running games from cartridge (if yes, then are there any?)? I think that I've read a long time ago that there would be problems with that... but don't remember why...

Programming / Video config that allows to draw sprites vertically
« on: 2015.August.24. 22:15:29 »
Just had an Idea...
On the Enterprise you could actually setup the lpt so that going one screen line up/down would become just a simple dec/inc of the high byte of screen address (and going one pixel left or right would be dec/inc of the lower byte). There would be some additional memory costs (as you see below - lines have to be 128 bytes long)... but you could use it for scroll buffer or just as a somewhat complicated (beacuse not linear) buffer for other things I guess.

The idea is:
- have 2 screen buffers
- have separate modeline for each screenline
- 1st buffer lines start at xx00
- 2nd buffer lines start at xx80

This way changing screen equals toggling the 7th bit of the lower byte of each line address.
If you don't do scrolling then there's quite a waste of memory...I guess...
Also the "seperate modeline" bit can be limiting, but with the 160x144 resolution it's what you need to do anyways...

Drawing sprites vertically (as opposed to standard horizontal drawing - left to right or right to left) allows simple (and quick) horizontal clipping of compiled sprites. Which I personally find problematic for non-standard sprites and horizontal cipping seems to be the more used type of clipping that you have to do in games (at least horizontal scrolling ones which are the majority I think).

Don't know what would be the other advances of this...

Input devices / Internal joystick problem
« on: 2015.May.17. 19:02:44 »
I have problems getting the joystick to connect the right direction...
Is it what I fear - a small "crack" or something on the keyboard membrane?
If so, then is there a fix for this (I don't mean buying a new membrane)?
Many years ago I remember that on the c64 you could "wire" the keyboard membrane if some keys didn't want to work (after spilling some drink on it). But I have been told that something like that isn't possible with enterprise membrane because it's "sealed".
Is there a shortcut to make the external joystick used in place of the internal as cursors and whatnot (although many programs seem to support both but basic does not)?

Programming / Double LPT action
« on: 2015.April.18. 02:35:01 »
Had an idea today and here it is...

Run the snapshot, move the crosshair, press fire and move the crosshair some more then repeat to enjoy some Enterprise dual lpt 4-color magic.

Not really any additional cost of this "effect" and can be utilized in games...

This is just a proof of concept...


Graphics taken from double dragon for gameboy (screen cut from http://www.vgmaps.com/Atlas/GB-GBC/DoubleDragon-Mission2.png).

The upper area was meant for a coordinates panel, but in the end I didn't do it...

Pages: 1 [2] 3