2014-11-26 16 views
1

일부 C64 소개 아이디어 작업. 아래 코드와 부비동 테이블을 사용하여 사전 생성 된 부비동 테이블을 기반으로 스프라이트를 이동합니다.스프라이트 이동을위한 부비동 기능에 대한 대안

서브 루틴

 ldx counter 
     cmx #100 
     jmp + 

     ldx #00 
     stx counter 

+  lda sprite_sinus,x 

     inc counter 

     rts 

부비동 테이블

sprite_sinus 
    !by 25,23,21,20,18,17,15,14,12,11,10,8,7,6,5,4 
    !by 3,2,2,1,1,0,0,0,0,0,0,0,0,0,1,1 
    !by 2,3,4,5,6,7,8,9,10,12,13,14,16,17,19,21 
    !by 22,24,25,27,28,30,32,33,35,36,37,39,40,41,42,43 
    !by 44,45,46,47,48,48,49,49,49,49,49,49,49,49,49,48 
    !by 48,47,47,46,45,44,43,42,41,39,38,37,35,34,32,31 
    !by 29,28,26,25 

그러나 나는 다른 무언가가 필요합니다. 반복 경로에서 x와 y 방향으로 스프라이트를 이동합니다. 내가 사용할 수있는 다른 기능은 무엇입니까?

+0

다른 방법은? 좀 더 다양한 파형을 만들기 위해 [여러 개의 사인파 결합] (http://www.pouet.net/prod.php?which=14754)을 가지고 놀 수 있습니다. 또 다른 가능성은 화면에 "무작위로"점을 배치하고 스플라인 함수를 실행하여 이들 사이를 보간하는 것입니다. 얼마나 많은 계산 능력을 절약 할 수 있는가에 달려 있습니다. – Michael

+0

다른 말로하면, [Lissajous Curves] (http://en.wikipedia.org/wiki/Lissajous_curve)와 같은 의미입니다. – wizofwor

+3

이 질문은 6502, 6510, 어셈블리 또는 (텍스트 참조 제외) C64 중 하나가 아닙니다. 또한 '추천'질문이므로 SO에 대한 주제는 아닙니다. 아마도 MathOverflow 또는 Programmers가 파형 보간법에 대한 조언을 구할 수있는 가능성이 있습니까? –

답변

3

이 질문과 관련하여 나는 한 때 너무 놀랍다 고 생각했던 모든 데모에서 이것이 어떻게 달성 될 수 있었는지 생각하면서 추억의 길을 걸어가는 것을 거부 할 수 없었다. 여기에 내가 생각해 낸 점이있다 :

복잡한 사인 - 테이블 기반 2D 모션을 얻고 자하는 것이 여러 사인파를 결합하여 각 좌표를 만드는 것입니다. 최소한 하나의 사인파를 x 좌표로, 다른 하나를 y 좌표로 사용하고 싶을 것입니다. 각각의 반복 과정에서 테이블 인덱스를 하나씩 증가시키는 사소한 알고리즘을 사용하면 두 개의 사인파가 동일한 빈도로 루프를 통과하도록 제한됩니다. 결과는 대각선을 따라 이동하거나, 두 사인 사이에 적절한 위상 이동이있을 때 원 또는 타원을 따라 이동합니다. 그건 그렇고, 이미 적절한 리사 주 (Lissajous) 인물입니다. 단지 가장 흥미롭지는 않습니다.

더 재미있는보고를 만들기 위해서는 다른 주파수로 다른 사인파를 반복해야합니다. 간단한 테스트로, 두 좌표 중 하나에서 반복 당 하나가 아닌 테이블 색인을 두 개씩 늘리면 어떤 일이 일어나는지 관찰하십시오. 좀 더 일반적인 솔루션을 위해서는 각 테이블 인덱스에 대해 "오실레이터"를 구현해야합니다.이 변수는 다른 변수에 저장된 "빈도"값에 따라 증가하는 변수 (이 경우에는 16 비트 너비 일 것입니다. 매 반복마다 후자를 추가하고, 오실레이터가 오버 플로우하여 루프를 돌리게한다). 그런 다음 오실레이터의 상위 비트 중 일부만 테이블 인덱스로 사용할 수 있습니다. 일을 단순하게하기 위해 테이블의 크기는 2의 2입니다.

더 복잡한 수치를 얻으려면 서로 다른 주파수로 진동하는 두 개 (또는 그 이상)의 사인파를 추가하여 각 좌표 구성 요소를 작성해보십시오. 예를 들어 추가하기 전에 값을 2로 나눈 것과 같이 사인파의 크기를 다르게 조정할 수 있습니다. Lissajous 스프라이트 모션을 기반으로 한 데모를 마지막으로 본 이후로 (20 년이 넘는) 오래되었습니다.하지만 내 기억이 정확하다면 이것은 정확히 사용 된 조합이었습니다.

다음은 일부 코드 단편입니다. 아직 작성하지 않았지만 아직 테스트하지 않았습니다. 그럼에도 불구하고, 그들의 분석은이 연구에서 내가 표현하려고했던 것을 명확하게 밝혀야한다.

; Routine for advancing a 16-bit oscillator depending on a 16-bit frequency 
; 
; Upon entry, x must hold offset to oscillator data. (So that this 
; routine can be reused with multiple oscillators. x not preserved) 
; Returns sine-table value for next oscillator step in a. 
advance_osc: 
    clc   ; increment 16-bit oscillator by 16-bit frequency 
    lda osc_lo,x 
    adc frq_lo,x 
    sta osc_lo,x 
    lda osc_hi,x 
    adc frq_hi,x 
    sta osc_hi,x 
        ; get table index (osc_hi still in a) 
    and #$3f  ; mask for 6-bit table size 
    tax   ; x now holds 6-bit table index 
    lda table,x ; a holds value from table 
    rts 

; Snippet for building sprite coordinate from multiple sine-table values 

; Step 1: use one sine wave to start building x coordinate 
    ldx #osc_offset 
    jsr advance_osc ; returns next table value for that osc 
    sta x_coord 
; Step 2: add another sine wave to x coordinate 
    ldx #next_osc_offset 
    jsr advance_osc 
    lsr    ; optional: scale down result by two 
    clc 
    adc x_coord  ; add sine-waves 
         ; (may want to rework this to handle 9-bit x_coord) 
    sta x_coord 
; Step 3..4: now, repeat the above steps for y_coord 
    ... 
; Step 5: once done, copy coordinates into VIC registers... 
    ... 
; repeat for next sprite (may be reworked into a loop)