|
Post by fury on Mar 19, 2012 14:49:36 GMT -5
I would use the other method if I were doing a BattleZone-like game, in which case I would be pushing Kokovec to finish his adapter because resources are very limited. His adapter eliminates the resource problem. I would also use the other method if needed for a 3D object that was a small aspect of the game, in which case Kokovec's adapter wouldn't be necessary.
|
|
|
Post by gliptitude on Mar 19, 2012 16:08:46 GMT -5
I would use the other method if I were doing a BattleZone-like game, in which case I would be pushing Kokovec to finish his adapter because resources are very limited. His adapter eliminates the resource problem. I would also use the other method if needed for a 3D object that was a small aspect of the game, in which case Kokovec's adapter wouldn't be necessary. What do you mean by "resources"? ... Also, eh heads up, i have been writing lengthy private message for the past 20 minutes, RE: Am I understanding correctly that you're looking to have someone program something for you? If that's the case, send me a private message and I'll let you know what I can do. Please do not feel obligated to work through it all if you are pressed.
|
|
|
Post by fury on Mar 19, 2012 17:47:10 GMT -5
I haven't received any messages.
By "resources", I just mean that the Vectrex can only handle so much before flicker becomes an issue, the game speed starts to slow down, etc. There are tricks to stretch this, but it's still an issue.
|
|
|
Post by gliptitude on Mar 19, 2012 18:44:14 GMT -5
I haven't received any messages. Just now sent. Yes it took me that long to write. The "heads up" was meant as a warning that it is a lengthy message.
|
|
|
Post by celtroniclabs on Mar 20, 2012 16:31:18 GMT -5
Cool, you going to make any games or anything? Yes. I am working on a vector style game app for iOS devices. It will actually draw the lines in a similar manner to how the old vector arcade games produced theirs. Most of the current "vector" style iOS games (of which their aren't many) draw aliased (stair-stepped) lines. The lines in my game are completely smooth. They have a glow to them as well, but not as exaggerated of a glow as the game "Space Junk", for example. Creating the vector line drawing engine, was the most time consuming part of the process. Unlike the old games, I have to draw ALL visible lines, for all objects on the screen in one call per frame, to achieve the maximum 59 to 60fps the iOS devices are capable of. This is because the techniques used to make the lines smooth and create the glow effects utilize extra CPU power. I don't currently have a release date set. Nor have I decided on specifically what the first game will be at this time. The app will be available when the first game is ready, whenever that may be.. Right now it is not a high priority project. The plan, ultimately, is to make a series of these vector games for iOS, but that of course depends on how popular the first one becomes..
|
|
|
Post by VectorX on Mar 20, 2012 17:15:41 GMT -5
That's great! Make sure and put up posts in the Mobile vector games board to announce and give out info about them once they're out and available, eh? ;D
|
|
|
Post by vectrexrc on Jun 28, 2014 18:36:02 GMT -5
imagine the vectrex screen being a page in a book and watch this... www.youtube.com/watch?v=8D0kG4URfxseverytime a new page is "flicked" (usually every 50th of a second) you need to program the vectors to display the next frame of the animation. each page does not have to have the same number of vectors. to give a program best performance the "next frame" may not be based on a calculation, the data might be hardcoded instead.
|
|
|
Post by christophertumber on Jun 28, 2014 22:01:11 GMT -5
So my question is, are animated game sprites ever done this way? No. Or at least not by anyone I am aware of. In Web Wars, for example, the winged player looks to be two or three "key frames" that morph from one to the next. I have no idea what Web Warp is actually doing. It's possible they are using a counter to progressively adjust the wing points relative to the body. Given the simplicity of the animation that kind of procedural animation shouldn't introduce all that much overhead. However, for something with as complex animation as WoW I would except the overhead would be considerable. What you're missing here is that the limiting factor on game design for "legacy consoles" for the Vectrex is not the developer's time or the artists time. It's really not even ROM size since what causes ROM size to bloat are bitmap graphics, FMV, sampled audio, text. None of which are an issue on the Vectrex. The limiting factor is the CPU clock speed of the console. This is true of the Vectrex. This is true of the Atari 2600. This is true of basically every console of the era. It can be well worth spending hours to optimize away a handful of cycles. And when it comes to drawing images on the Vectrex, by far the most efficient structure is pre-calculated vector sets. The Vectrex BIOS includes routines for handling rotation of vector sets. I doubt anyone is using them. They're slow. It's far more efficient to pre-calculate 4, 8, 16 or 32 views of a ship and just display the appropriate one rather than do the rotation calculations in real time. Even for something visually as simple as the player's ship in Omega Chase, the savings from precalculating the rotated views is significant. On the Vectrex you will always run out of cycles. On the Atari 2600, you will spend about 75% of each frame drawing the screen, manually, in real time. On the Vectrex it's going to be even more. That is why there aren't any true 3D engines (yet?). It is extremely difficult just maintain a reliable image. When it comes to game calculations/AI/maintenance, doing anything more than the absolute minimum require to achieve your objectives takes away directly from what you are able to display onscreen.
|
|
|
Post by mikiex on Jun 29, 2014 12:39:50 GMT -5
Just to add some more info, the animation master (I've not actually used it), but from what I have seen it morphs. An early example of morph based animation en.wikipedia.org/wiki/Hunger_%281974_film%29Also the game "Another World" comes to mind as using the process in 2D. A way to do this is lerp (linear interpolate) each point. I'm sure Chris S did some experimenting with this for the frogger title screen?
|
|
|
Post by Malban on Jun 29, 2014 13:21:43 GMT -5
Hi there
I copy pasted some of the morph routines from VFrogger.
Will not work out of the box... you got to edit the code in some places to make it compile allright:
; this file is part of vectrex frogger, written by Christopher Salomon ; in March-April 1998 ; all stuff contained here is public domain ; ; MAKROS ;*************************************************************************** MY_DIV_D_16_UNSIGNED macro LSLA LSLA LSLA LSLA LSRB LSRB LSRB LSRB STA divide_tmp ORB divide_tmp endm ;***************************************************************************
; morphing stati... MORPHING_DONE EQU (lo(10)) ; this morphing structure finnished MORPHING_WORKING EQU (lo(11)) ; is morphing MORPHING_COMPLETE EQU (lo(0)) ; no more morphing
; and general morphing constants MAX_VECTOR_MORPH EQU (lo(63)) ; this uses 128*3 bytes of RAM, maximum number of vectors for a morph MORPH_STARTUP_DELAY EQU (lo(80)) ; constants used in init morph MORPH_STEPS_INTRO EQU (lo(15)) MORPH_DELAY_INIT EQU (lo(2)) MORPH_STEPS_Z EQU (lo(15)) ;
; they allways appear somewhere... truth values :-) FALSE EQU (lo(0)) TRUE EQU (lo(1))
; RAM ; $c880 user_ram EQU $c880 ; well start of our ram space user_ram_start EQU user_ram
; following are some variable used only when something is 'morphing' morph_status EQU user_ram ; status--- morph_tmp EQU morph_status + 1 ; saves a few cycles... for the step counter only in one_morph_step morph_sign EQU morph_tmp + 1 ; number of steps between 'from' and 'to' variable morph_counter EQU morph_sign + 1 ; number of steps between 'from' and 'to' variable morph_steps EQU morph_counter + 1 ; number of steps between 'from' and 'to' constant morph_delay EQU morph_steps + 1 ; delay between one step and another (variable) morph_structure EQU morph_delay + 2 ; pointer to morphstructure of current morphing morph_div_jsr EQU morph_structure + 2; pointer to indirectly JSR to a divide routine (for optimization) divide_tmp EQU morph_div_jsr +2 ; divide tmp variable
; morphing uses ram occupied by the game, therefor only be used ; as start, end or in between sequences current_morph_vectorlist_org EQU (divide_tmp+2) current_morph_vectorlist EQU (current_morph_vectorlist_org+2*MAX_VECTOR_MORPH+1) current_morph_vector_diffs EQU (current_morph_vectorlist+2*MAX_VECTOR_MORPH+1) end_of_my_ram EQU current_morph_vector_diffs+2*MAX_VECTOR_MORPH ; end by current_morph_vector_diffs + 2*MAX_VECTOR_MORPH
;*************************************************************************** ORG some ROM SPACE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; morphing subroutines ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ;*************************************************************************** ; below are all subroutines for morphing ; (only two) set_up_morphing(), do_one_morph_step() ;*************************************************************************** ; this sets up a morph ; in U a pointer to a morph structure is expected, ;structure: ; DW ; morph from vector list ; DW ; morph to vector list ; DB ; morph steps ; DB ; delay between one morph step ; DW ; optional (0 or structure) ; ; pointer to next morph structure ; DB ; startup delay ; ; vector list must have (as usual with my routines) the following style ; count, rel y, rel x, rel y, rel x, ... ; ; maximal vectors for morphing is now 63 (127/2) ; if more are needed than something below cries for a 16 bit change... ; vector list don't need to have the same length anymore ; for optimal performance use a power of two step counter (-1) ; (8, 16, 32, 64 are supported with fast DIV routines) FIXED at 16 steps NOW! ; ; this routine sets up three vector lists (sort of) in RAM ; current_morph_vectorlist_org ; current_morph_vectorlist ; current_morph_vector_diffs ; ; current_morph_vectorlist_org ; is the original startlist, but possibly lengthened to the ; max vectorlist length of the two passed vectors (filled with 0,0 coordinates) ; ; current_morph_vectorlist ; is the storage area for the next to be drawn vectorlist ; is set to the original vector list (not max length) ; ; current_morph_vector_diffs ; not a real vector list, this contains the difference between the ; points of the two passed vector lists ; used in 'do_one_morph_step' to calculate the next vector ; ; further some variables are set, like delay, div routine, and morph_structure... ; ; set_up_morphing: JSR DP_to_C8 direct $c8 STU morph_structure ; remember current morph structure ; first clear all current stuff, since we ; don't know how long all vectors will be ; could be optimized to a later fill ; with only the fills we need, ; but at this point vectrex should be fast enough ; so it doesn't matter to waste a bit time here... ; ; since current_morph_vectorlist_org, current_morph_vectorlist and current_morph_vector_diffs ; are neighbours one Clear_x_d should be enough... LDX #current_morph_vectorlist_org ; address to clear LDD #((3*(2*MAX_VECTOR_MORPH+1))-1); number of bytes - 1 to clear JSR Clear_x_d ; clear sub routine in ROM LDX ,U ; X = pointer to 'from' LDY 2,U ; Y = pointer to 'to' LDA ,X ; load number of vectors CMPA ,Y ; compare number of vectors BHS A_is_high_vector_counter ; which vector list is longer ? LDA ,Y ; load number of vectors 'to', the second... A_is_high_vector_counter: ; in A is the higher vector count STA current_morph_vectorlist_org ; set high value in vector lists INCA ; add 1 ASLA ; multiply by two, since every vector has two coordinates STA tmp2 ; remember in tmp2 ; copy 'from' to original LDX #(current_morph_vectorlist_org+1) ; destination pointer LDU ,U ; source pointer LDA ,U+ ; load length and step over length byte INCA ; increase 1, since one is missing ASLA ; times two, since there are two coordinates JSR Move_Mem_a ; and copy it
LDU morph_structure ; load current morph structure ; copy 'from' to current LDX #(current_morph_vectorlist) ; destination pointer LDU ,U ; source pointer LDA ,U ; load length INCA ; increase 1, since one is missing ASLA ; times two, since there are two coordinates INCA ; add 1 since counter is also copied JSR Move_Mem_a ; and copy it LDU morph_structure ; load current morph structure ; copy 'to' to 'buffer' (buffer is now 'current_morph_vector_diffs') ; destination pointer LDX #current_morph_vector_diffs ; no +1 here, since in diffs only the offsets are relevant anyway LDU 2,U ; source pointer LDA ,U+ ; load length and step over length byte INCA ; increase 1, since one is missing ASLA ; times two, since there are two coordinates JSR Move_Mem_a ; and copy it LDU morph_structure ; load current morph structure LDA 4,U ; load morph steps to A INCA ; plus one STA morph_counter ; and save it this is variable STA morph_steps ; and again not variable LDA 8,U ; load morph delay A STA morph_delay ; and save it LDA #MORPHING_WORKING ; and mark the whole thing as active STA morph_status ; and store it ; now we must calculate the current_morph_vector_diffs ; we must determine the difference between the two sets of coordinates ; use tmp2 as loop counter ; number of vectors to process * 2 LDX #(current_morph_vectorlist_org+1) LDY #current_morph_vector_diffs ; Y = pointer to 'to' (buffer) ; and Y = pointer to vector diffs set_up_morphing_loop2: LDB ,Y ; load the second's vector coordinate NEGB ; neg it, since we actually want a 'a=a-b' style ; what we do is ; invert b and do a b=-b+a ADDB ,X+ ; and add the source coordinate STB ,Y+ ; store is (back) to vector diffs DEC tmp2 ; decrease vector counter by 1 BNE set_up_morphing_loop2 ; and continue with next vector if not done JSR DP_to_D0 direct $d0 RTS ; all done now, return ;*************************************************************************** ; uses tmp1 and tmp2 ; destroys everything ; ; what it does: ; current_morph_vectorlist is set to a (possibly) newly calculated vector ; ; but hardcoded ; 16 steps, ; not using JSR for DIV ; saves 1000 cycles on intro screen!!! do_one_morph_step_16: direct $d0 LDA morph_status ; load the status CMPA #MORPHING_WORKING ; and look what there is to do BEQ morphing_now_16 ; morphing now? CMPA #MORPHING_COMPLETE ; or complete? BEQ no_new_morph_structure; should a new morph be initialized? ; here we come with MORPHING_DONE LDX morph_structure ; load the current morph structure LDU 6,X ; look if there is a next structure BEQ no_new_morph_structure ; no? than go out JSR set_up_morphing ; yes? than initialize it RTS ; go back no_new_morph_structure: LDA #MORPHING_COMPLETE ; load completeness flag to A STA morph_status ; and store it RTS ; go back morphing_now_16: DEC morph_delay ; decrease delay value BEQ delay_done_16 ; only morph when zero RTS ; otherise go back delay_done_16: LDU morph_structure ; in the current morph structure LDA 5,U ; look for the next delay value STA morph_delay ; and set it LDA morph_counter ; load counter of morph steps BEQ no_morphing_is_last ; are we done ? SUBA morph_steps ; no, than calculate offset to number of steps BEQ no_morphing_is_first; is it the beginning? ; no, than we go on LDX #current_morph_vectorlist_org; pointer to original vectorlist ; (RAM), but the (maybe) longer version LDA ,X+ ; load length of vectorlist and increment X STA current_morph_vectorlist ; only needed the first time we are in here... ; A current number of vectors in (RAM) vectorlist INCA ; since it misses allways one, add one ASLA ; multiply by two, since every vector has ; start and end point STA tmp2 ; use tmp2 as loop counter see below LDU #current_morph_vector_diffs ; U = pointer to vector diffs (RAM) LDY #(current_morph_vectorlist+1) ; target memory pointer (RAM) ; plus one, since we don't need the vector counter LDB morph_steps ; load number of steps to B SUBB morph_counter ; invert the morph counter STB morph_tmp ; store..., so we don't have to calculate in the loop CLR morph_sign ; clear signess... (that's positiv) do_morph_loop2_16: ; loop through all vector coordinates of list LDA ,U+ ; load the difference between the 'to' coordinates to A BPL no_minus_morph_16 ; check if negative sign INC morph_sign ; mark as negative NEGA ; and make positiv no_minus_morph_16: LDB morph_tmp ; initiated above..., this is the ; 'morph step' of number of morph_steps we are makeing MUL ; multiply, B should be smaller ; than A (B is cycle relevant) MY_DIV_D_16_UNSIGNED TST morph_sign ; is it signed? BEQ no_minus_morph2_16 ; no, than go on NEGB ; otherwise restore the 'minus' DEC morph_sign ; and reset sign memory no_minus_morph2_16: NEGB ; negate the div value ; ; this is again a formal a=a-b ; what we do is ; invert b and do a b=-b+a ADDB ,X+ ; add the resulting difference to original coordinate STB ,Y+ ; and store it to the current vectorlist DEC tmp2 ; decrement the vectorlist loop counter by one BNE do_morph_loop2_16 ; and if not done,.. repeat ; on first entry vectorlist is allready set no_morphing_is_first: DEC morph_counter ; decrement morph step counter RTS ; and go back no_morphing_is_last: LDU morph_structure ; load current morph structure ; copy 'to' to current_morph_vectorlist LDX #(current_morph_vectorlist) ; destination pointer LDU 2,U ; source pointer LDA ,U ; load length INCA ; increase 1, since one is missing ASLA ; times two, since there are two coordinates INCA ; increase 1, since now we also copy the counter JSR Move_Mem_a ; and copy it LDA #MORPHING_DONE ; no we are done with morphing... STA morph_status ; and store it RTS ; go back... ;*************************************************************************** ; end of morph routine section ;***************************************************************************
Regards
Chris
|
|
|
Post by vectrexrc on Jun 29, 2014 16:49:50 GMT -5
if you need tweening (aka morphing) what would be good is a windows tool to allow design of vector shapes and then let it calculate the intermediate frames generating appropriate vector list data for inclusion in asm. Then the animation through the frames would be trivial task in asm code and a lot more cycle efficient. of course you could do this by hand...but a tool to do this would be good idea. there is the v_model utility but being dos based its a bit of a pain to use on windows...maybe a new java alternative would be a nice project
|
|