Jump to content

8bit-Dude

Members
  • Content Count

    181
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by 8bit-Dude

  1. Thanks a lot for going through this pain Xuel, really kind of you!!
  2. Yeah, that's what I have for now. But I am writing a kind of Game Dev Kit for cc65 (c64/a8), and SAP support would make things easier in many respects.
  3. Hey DJMIPS, Did you ever get round to implementing that faster atan2 method?
  4. Thanks Xuel! By the way, to you know a way to relocate SAP files? I would like to have the entire code located at 0xF000.
  5. Hey Xuel, Would you mind working your magic on the attached SAP file? I can find the load addresses, but no idea where to find the init and frame addresses... Thx in advance! speednik.zip
  6. Hey Schlortt I will try to figure out the tire issue based on your remarks. The OS stuff is much more problematic for me. I do not want to disable it, but the CIN code I obtained from Atari Interlaced Studio seems to require setting the OS off. By looking at the ASM code, could you tell me why CIN needs it, and if there is a way to avoid switching off the OS.
  7. So, back with more questions! I have integrated my sprites animation with a CIN background image as shown here: I still have a couple of issues: (1) I set the colour of P4 (tires) with: POKE(53273, PMColor[4]); // Set Player colors However, the colour flickers based on P0-P3... (2) I have an issue with this line of code in the asm file: mva #$fe portb This functions is used by CIN to disable to ROM, or something like that, but the functions clock() and cgect() in cc65 stop working. If I comment this line I can use clock() and cget(), but then the CIN gfx do not appear. Could you guyz give me again some advice?? Thx a lot in advance!!!! Tony sources.zip freeway.xex
  8. Hey Guyz, I have another question: when exporting ASM code from Atari Interlace Studio, I can compile it with MADS and call from CC65 with a JSR. I have created some background GFX in mode G11, with no raster, no DLI, really simple case. However, after initialzing the G11 graphics, the sprites don't show up properly. Would you mind having a quick look at the ASM and C code, and let me know what I am doing wrong? Cheers!!! // Atari Interlaced Studio buf0 = $6010 gtictl = $d01b skctl = $d20f portb = $d301 dmactl = $d400 dlptr = $d402 wsync = $d40a vcount = $d40b nmien = $d40e nmist = $d40f /*-------------------------------------------------------------------------------------------------*/ org $80 regA .ds 1 regX .ds 1 regY .ds 1 cnt .ds 1 /*-------------------------------------------------------------------------------------------------*/ .get 'g11.dat',-9 ; palette org buf0 ins 'g11.dat',0,8000 /*-------------------------------------------------------------------------------------------------*/ .align $100 dlist0: dta d'ppp' dta $4f,a(buf0) :101 dta $f dta $4f,0,h(buf0+$1000) :89 dta $f dta $41,a(dlist0) /*-------------------------------------------------------------------------------------------------*/ .proc StartG11 lda:cmp:req 20 mva #$00 nmien mva #$fe portb mwa #dlist0 dlptr mwa #NMI $fffa mva #$c0 nmien lda:rne vcount rts ; exit .endp .proc StopG11 lda:rne vcount mva #$ff portb mva #$40 nmien rts .endp /*-------------------------------------------------------------------------------------------------*/ NMI bit nmist bpl vbl vdli equ *-2 vbl sta nmist phr ;mva #$22 dmactl mva #62 dmactl ;mva #$c0 gtictl ; graphics 11 mva #241 gtictl ; graphics 11 plr rti #include <cc65.h> #include <conio.h> #include <peekpoke.h> #include <stdio.h> #include <string.h> #include <time.h> #define PLAYERS (4) #define FRAMES (16) #define HEIGHT (13) #define PMGMem (0x4000) // sprites data unsigned int PMGBase[5] = {PMGMem+1024, PMGMem+1280, PMGMem+1536, PMGMem+1792, PMGMem+768}; unsigned int PMGAddr[5] = {PMGMem+1024, PMGMem+1280, PMGMem+1536, PMGMem+1792, PMGMem+768}; unsigned char PMColor[5] = {0x72, 0x22, 0xb6, 0xec, 0x00}; unsigned char xpos[4]; unsigned char ypos[4]; unsigned char frame[4]; #define FRAMES (16) #define HEIGHT (13) const unsigned char BODY[FRAMES][HEIGHT] = { { 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3e, 0x32, 0x32, 0x3e, 0x3c, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x04, 0x1e, 0x3a, 0x32, 0x36, 0x3e, 0x18, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x04, 0x0e, 0x1a, 0x34, 0x38, 0x38, 0x30, 0x10, 0x00, 0x00 }, { 0x00, 0x00, 0x18, 0x1c, 0x14, 0x28, 0x38, 0x38, 0x38, 0x30, 0x10, 0x00, 0x00 }, { 0x00, 0x00, 0x10, 0x38, 0x28, 0x28, 0x38, 0x38, 0x38, 0x38, 0x38, 0x00, 0x00 }, { 0x00, 0x00, 0x30, 0x70, 0x50, 0x28, 0x38, 0x38, 0x38, 0x18, 0x10, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x20, 0x70, 0x58, 0x2c, 0x1c, 0x1c, 0x0c, 0x08, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x20, 0x78, 0x5c, 0x4c, 0x6c, 0x7c, 0x18, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7c, 0x4c, 0x4c, 0x7c, 0x3c, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x18, 0x7c, 0x6c, 0x4c, 0x5c, 0x78, 0x20, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x08, 0x0c, 0x1c, 0x1c, 0x2c, 0x58, 0x70, 0x20, 0x00, 0x00 }, { 0x00, 0x00, 0x08, 0x0c, 0x1c, 0x1c, 0x1c, 0x14, 0x28, 0x38, 0x18, 0x00, 0x00 }, { 0x00, 0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x14, 0x14, 0x1c, 0x08, 0x00, 0x00 }, { 0x00, 0x00, 0x08, 0x18, 0x1c, 0x1c, 0x1c, 0x14, 0x0a, 0x0e, 0x0c, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x10, 0x30, 0x38, 0x38, 0x34, 0x1a, 0x0e, 0x04, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x18, 0x3e, 0x36, 0x32, 0x3a, 0x1e, 0x04, 0x00, 0x00, 0x00 } }; const unsigned char TIRES[FRAMES][HEIGHT] = { { 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x28, 0x28, 0x00 }, { 0x00, 0x00, 0x08, 0x28, 0x20, 0x04, 0x0c, 0x08, 0x00, 0x04, 0x14, 0x10, 0x00 }, { 0x00, 0x00, 0x00, 0x18, 0x10, 0x04, 0x4a, 0x46, 0x00, 0x08, 0x08, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x20, 0x28, 0x14, 0x44, 0x40, 0x00, 0x08, 0x08, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x08, 0x28, 0x50, 0x44, 0x04, 0x00, 0x20, 0x20, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x18, 0x08, 0x20, 0x52, 0x62, 0x00, 0x10, 0x10, 0x00, 0x00 }, { 0x00, 0x00, 0x10, 0x14, 0x04, 0x20, 0x30, 0x10, 0x00, 0x20, 0x28, 0x08, 0x00 }, { 0x00, 0x00, 0x14, 0x14, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x14, 0x14, 0x00 }, { 0x00, 0x00, 0x08, 0x28, 0x20, 0x00, 0x10, 0x30, 0x20, 0x04, 0x14, 0x10, 0x00 }, { 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x62, 0x52, 0x20, 0x08, 0x18, 0x00, 0x00 }, { 0x00, 0x00, 0x10, 0x10, 0x00, 0x02, 0x22, 0x28, 0x14, 0x04, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x2a, 0x2a, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x04, 0x04, 0x00, 0x20, 0x22, 0x0a, 0x14, 0x10, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x46, 0x4a, 0x04, 0x10, 0x18, 0x00, 0x00 }, { 0x00, 0x10, 0x14, 0x04, 0x00, 0x08, 0x0c, 0x04, 0x20, 0x28, 0x08, 0x00, 0x00 } }; clock_t tFPS; unsigned long f; void DrawFPS() { // Calculate stats unsigned int fps; tFPS = clock() - tFPS; fps = (f*CLK_TCK)/tFPS; tFPS = clock(); // Output stats gotoxy(0,0); printf("FPS: %u", fps); } unsigned char i; void InitSprites(void) { POKE(54279, PMGMem>>; // Tell ANTIC where the PM data is located POKE(53277, 2+1); // Tell GTIA to enable players + missile POKE(623, 32+16+1); // Tricolor players + enable fifth player + priority POKE(559, 32+16+8+4+2); // DMA Screen + Enable P/M + DMA Players + DMA Missiles + Single resolution for (i=0; i<4; i++) { bzero(PMGAddr[i],0x100); // Clear Player memory POKE(704+i, PMColor[i]); // Set Player colors } bzero(PMGAddr[4],0x100); // Clear Missile memory POKE(711, PMColor[4]); // Set Player color } void ShowSprites(void) { clock_t timer = clock(); unsigned int angle = 0; tFPS = clock(); while (!kbhit()) { // Update body position //if (clock()>timer) { // timer = clock(); angle++; for (i=0; i<PLAYERS; i++) { xpos[i] = 128+cc65_cos((angle+i*90)%360)/6; ypos[i] = 128+cc65_sin((angle+i*90)%360)/4; frame[i] = ((12-(angle+(i+1)*90))%360)/23; POKE(53248+i, xpos[i]); bzero(PMGAddr[i], HEIGHT); PMGAddr[i] = PMGBase[i]+ypos[i]; memcpy(PMGAddr[i], BODY[frame[i]], HEIGHT); } //} // Flicker TIRES i = f%PLAYERS; bzero(PMGAddr[4], HEIGHT); PMGAddr[4] = PMGBase[4]+ypos[i]; POKE(53252, xpos[i]+6); POKE(53253, xpos[i]+4); POKE(53254, xpos[i]+2); POKE(53255, xpos[i]+0); memcpy(PMGAddr[4], TIRES[frame[i]], HEIGHT); // Next Frame if (f > 60) { DrawFPS(); f=0; } f++; } } /* ** Hello world program using cc65. */ #include <stdlib.h> #include <string.h> #include <stdio.h> #include <conio.h> #include <unistd.h> #include "sprites1.h" /*****************************************************************************/ /* Code */ /*****************************************************************************/ int main (void) { // Start CIN __asm__("jsr $80CA"); // Start Sprites InitSprites(); ShowSprites(); // Stop G11 __asm__("jsr $80F9"); // Done return EXIT_SUCCESS; } freeway.xex sources.zip
  9. Shlortt, Irgend, I have implemented a sorting algorithm that allows me to set DLIs in the right order, as I fill the sprites memory for the tires. When refreshing, I move all the sprites to hpos zero, then clear the memory and reset the DLIs. Some extras include flicekring between two players when they line up horizontally. The animation is 99% correct, I am very very close, but there is a residual "jumping" of sprites that I cannot get rid of. Could you please check the attached video/xex, and have another look through my sources to see if you spot something strange? I would really deeply appreciate it! sprites.zip sprites.xex sprites.mp4
  10. Thanks for the clarification. Hope something may be worked out in future with Npcap!
  11. Alright guyz, I am almost there!!! Now my tires follow each car nicely, and I only get a bit of flicker due to the fact that the background is a character based screen (8 rows per DLI). I would like to start using Graphic Mode 15, to refine the DLI, but there is precious little information on how it works in CC65. I tried writing _graphics(15); and the screen just went black (PMG also completely disappeared). Would you have some tips and advice to help me get setup? Here is the current version of code by the way: .include "atari.inc" .export _SetupVBIandDLI .export _DLIData .data _DLIData: .res 4 DLIIndex: .res 1 .code .proc _SetupVBIandDLI lda #$00 sta DLIIndex lda #$06 ; deferred ldx #(>VBI) ; install VBI routine ldy #(<VBI) jsr SETVBV ldx #(<DLI) ; install DLI routine ldy #(>DLI) stx VDSLST sty VDSLST+1 lda #$C0 sta NMIEN ; enable both VBI and DLI rts .endproc DLI: pha ; save registers tya pha ldy DLIIndex lda _DLIData,y sta $D003 ; set hpos of PM3 iny sty DLIIndex pla ; restore registers tay pla rti VBI: lda _DLIData sta $D003 ; set hpos of PM3 lda #$01 sta DLIIndex jmp SYSVBV #include <cc65.h> #include <conio.h> #include <peekpoke.h> #include <stdio.h> #include <string.h> #include <time.h> #define PLAYERS (4) #define FRAMES (16) #define HEIGHT (13) #define PMMem (0x6000) // sprites data unsigned int PMBase[5] = {PMMem+768, PMMem+1024, PMMem+1280, PMMem+1536, PMMem+1792}; unsigned char PMColor[5] = {0x72, 0x22, 0xb6, 0xec, 0x00}; unsigned char PMXpos[4], PMYpos[4], PMFrame[4]; unsigned int PMBody[4], PMTires[4]; #define FRAMES (16) #define HEIGHT (13) #define GAP (0) const unsigned char BODY[FRAMES][HEIGHT] = { { 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3e, 0x3e, 0x3e, 0x3e, 0x3c, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x04, 0x1e, 0x3e, 0x3e, 0x3e, 0x3e, 0x18, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x04, 0x0e, 0x1e, 0x3c, 0x38, 0x38, 0x30, 0x10, 0x00, 0x00 }, { 0x00, 0x00, 0x18, 0x1c, 0x1c, 0x38, 0x38, 0x38, 0x38, 0x30, 0x10, 0x00, 0x00 }, { 0x00, 0x00, 0x10, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x00, 0x00 }, { 0x00, 0x00, 0x30, 0x70, 0x70, 0x38, 0x38, 0x38, 0x38, 0x18, 0x10, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x20, 0x70, 0x78, 0x3c, 0x1c, 0x1c, 0x0c, 0x08, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x20, 0x78, 0x7c, 0x7c, 0x7c, 0x7c, 0x18, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x3c, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x18, 0x7c, 0x7c, 0x7c, 0x7c, 0x78, 0x20, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x08, 0x0c, 0x1c, 0x1c, 0x3c, 0x78, 0x70, 0x20, 0x00, 0x00 }, { 0x00, 0x00, 0x08, 0x0c, 0x1c, 0x1c, 0x1c, 0x1c, 0x38, 0x38, 0x18, 0x00, 0x00 }, { 0x00, 0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x08, 0x00, 0x00 }, { 0x00, 0x00, 0x08, 0x18, 0x1c, 0x1c, 0x1c, 0x1c, 0x0e, 0x0e, 0x0c, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x10, 0x30, 0x38, 0x38, 0x3c, 0x1e, 0x0e, 0x04, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x18, 0x3e, 0x3e, 0x3e, 0x3e, 0x1e, 0x04, 0x00, 0x00, 0x00 } }; const unsigned char TIRES[FRAMES][HEIGHT] = { { 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x28, 0x28, 0x00 }, { 0x00, 0x00, 0x08, 0x28, 0x20, 0x04, 0x0c, 0x08, 0x00, 0x04, 0x14, 0x10, 0x00 }, { 0x00, 0x00, 0x00, 0x18, 0x10, 0x0c, 0x4a, 0x46, 0x00, 0x08, 0x08, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x20, 0x28, 0x1c, 0x44, 0x40, 0x00, 0x08, 0x08, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x08, 0x28, 0x70, 0x44, 0x04, 0x00, 0x20, 0x20, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x18, 0x08, 0x30, 0x52, 0x62, 0x00, 0x10, 0x10, 0x00, 0x00 }, { 0x00, 0x00, 0x10, 0x14, 0x04, 0x20, 0x30, 0x10, 0x00, 0x20, 0x28, 0x08, 0x00 }, { 0x00, 0x00, 0x14, 0x14, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x14, 0x14, 0x00 }, { 0x00, 0x00, 0x08, 0x28, 0x20, 0x00, 0x10, 0x30, 0x20, 0x04, 0x14, 0x10, 0x00 }, { 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x62, 0x52, 0x30, 0x08, 0x18, 0x00, 0x00 }, { 0x00, 0x00, 0x10, 0x10, 0x00, 0x02, 0x22, 0x38, 0x14, 0x04, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x2a, 0x2a, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x04, 0x04, 0x00, 0x20, 0x22, 0x0e, 0x14, 0x10, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x46, 0x4a, 0x0c, 0x10, 0x18, 0x00, 0x00 }, { 0x00, 0x10, 0x14, 0x04, 0x00, 0x08, 0x0c, 0x04, 0x20, 0x28, 0x08, 0x00, 0x00 } }; clock_t tFPS; unsigned long f; void DrawFPS() { // Calculate stats unsigned int fps; tFPS = clock() - tFPS; fps = (f*CLK_TCK)/tFPS; tFPS = clock(); // Output stats gotoxy(0,0); printf("FPS: %u", fps); } unsigned int DLIBase; unsigned int DLIAddr[4]; extern char DLIData[4]; void SetupVBIandDLI(void); unsigned char i,j,k; void InitSprites(void) { // Setup PMG for Body for (i=0; i<5; i++) { bzero(PMBase[i],0x100); // Clear Player memory if (i==0) { POKE(711, PMColor[i]); } else { POKE(703+i, PMColor[i]); } // Set Player colors } POKE(54279, PMMem>>; // Tell ANTIC where the PM data is located POKE(53277, 2+1); // Tell GTIA to enable players + missile POKE(623, 32+16+1); // Tricolor players + enable fifth player + priority POKE(559, 32+16+8+4+2); // DMA Screen + Enable P/M + DMA Players + DMA Missiles + Single resolution // Setup DLI for Tires DLIBase = PEEK(560) + 256*PEEK(561); SetupVBIandDLI(); } void ShowSprites(void) { unsigned int DLI = PEEK(560) + 256*PEEK(561); clock_t timer = clock(); unsigned int angle = 0; tFPS = clock(); while (!kbhit()) { // Update body position if (clock()>timer+1) { timer = clock(); angle++; // Re-compute positions and angles for (i=0; i<PLAYERS; i++) { PMXpos[i] = 128+cc65_cos((angle+i*90)%360)/6; PMYpos[i] = 128+cc65_sin((angle+i*90)%360)/4; PMFrame[i] = ((12-(angle+(i+1)*90))%360)/23; } // Refresh PM data for (i=0; i<PLAYERS; i++) { // Set horizontal position if (i==0) { POKE(53255, PMXpos[i]); POKE(53254, PMXpos[i]+2); POKE(53253, PMXpos[i]+4); POKE(53252, PMXpos[i]+6); } else { POKE(53247+i, PMXpos[i]); } // Set body data bzero(PMBody[i], HEIGHT); PMBody[i] = PMBase[i]+PMYpos[i]; memcpy(PMBody[i], BODY[PMFrame[i]], HEIGHT); // Set tire data bzero(PMTires[i], HEIGHT); PMTires[i] = PMBase[4]+PMYpos[i]; memcpy(PMTires[i], TIRES[PMFrame[i]], HEIGHT); } // Reassign DLIs (used to shift tires) for (i=0; i<PLAYERS; i++) { // Find index of transition (k from 0 to 3) k = 0; for (j=0; j<PLAYERS; j++) { if (PMYpos[i] > PMYpos[j]) { k++; } } // Remove previous DLI DLIData[k] = PMXpos[i]; if (DLIAddr[i]) { *(unsigned char*)(DLIAddr[i]) &= ~(1 << 7); } // Set new DLI (except for first index) if (k > 0) { DLIAddr[i] = DLIBase+PMYpos[i]/8; *(unsigned char*)(DLIAddr[i]) |= (1 << 7); } else { DLIAddr[i] = 0; } } } // Count Frames if (f > 60) { DrawFPS(); f=0; } f++; } } sprites.xex
  12. Thanks for the quick answer buddy! By the way, WinVICE support ICMP, it is very helpful for networked games (to know the latency). I am developping a cross-platform (C64/A8/AppleII) top-down racing game.
  13. Good idea about using VBI for setting first position. I have added a sorting algorithm which fixes most of the out-of-sync. There are still some flickers though... mind having again a look? sources.zip sprites.xex
  14. Amazing, that was exactly the issue. The memory corruption has been fixed. There is still a problem with the code though, see attached xex and sources. sprites.xex sources.zip
  15. Hey Phaeron, Thanks so much for your continued development of Altirra, amazing work! I am using Altirra to develop an online game, and ran over a strange issue while using IP65. Most demos (including GETURL) work perfectly fine. But the PING example (see attached xex) returns an error code 82 in Altirra (2.8.1 and 2.9.0) I tested on my actual 130XE with DragonCart, and the program runs just fine. Could you kindly investigate the root cause of this problem? Thanks in advance! ping.xex geturl.xex ping.s
  16. Hey guyz, So I have written a VBI / DLI combo to shift the HPOS at various scanline. My code is *almost* working, in that I can show the tires 4 times, and shift them with the DLI routine. However, something is not right in my routine DLI:, it corrupts memory and crashes the prog after few seconds... Would you mind taking a quick look: .include "atari.inc" .export _SetupVBIandDLI .export _DLIData .data _DLIData: .res 4 DLIIndex: .res 1 .code .proc _SetupVBIandDLI lda #$00 sta DLIIndex lda #$07 ; deferred ldx #(>VBI) ; install VBI routine ldy #(<VBI) jsr SETVBV ldx #(<DLI) ; install DLI routine ldy #(>DLI) stx VDSLST sty VDSLST+1 lda #$C0 sta NMIEN ; enable both VBI and DLI rts .endproc DLI: pha ; save registers ldy DLIIndex lda _DLIData,y sta $D003 ; set hpos of PM3 iny sty DLIIndex pla ; restore registers rti VBI: lda #$00 sta DLIIndex jmp XITVBV #include <cc65.h> #include <conio.h> #include <peekpoke.h> #include <stdio.h> #include <string.h> #include <time.h> #define PLAYERS (4) #define FRAMES (16) #define HEIGHT (13) #define PMMem (0x6000) // sprites data unsigned int PMBase[5] = {PMMem+768, PMMem+1024, PMMem+1280, PMMem+1536, PMMem+1792}; unsigned char PMColor[5] = {0x72, 0x22, 0xb6, 0xec, 0x00}; unsigned char PMXpos[4], PMYpos[4], PMFrame[4]; unsigned int PMBody[4], PMTires[4]; #define FRAMES (16) #define HEIGHT (13) #define GAP (0) const unsigned char BODY[FRAMES][HEIGHT] = { { 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3e, 0x3e, 0x3e, 0x3e, 0x3c, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x04, 0x1e, 0x3e, 0x3e, 0x3e, 0x3e, 0x18, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x04, 0x0e, 0x1e, 0x3c, 0x38, 0x38, 0x30, 0x10, 0x00, 0x00 }, { 0x00, 0x00, 0x18, 0x1c, 0x1c, 0x38, 0x38, 0x38, 0x38, 0x30, 0x10, 0x00, 0x00 }, { 0x00, 0x00, 0x10, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x00, 0x00 }, { 0x00, 0x00, 0x30, 0x70, 0x70, 0x38, 0x38, 0x38, 0x38, 0x18, 0x10, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x20, 0x70, 0x78, 0x3c, 0x1c, 0x1c, 0x0c, 0x08, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x20, 0x78, 0x7c, 0x7c, 0x7c, 0x7c, 0x18, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x3c, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x18, 0x7c, 0x7c, 0x7c, 0x7c, 0x78, 0x20, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x08, 0x0c, 0x1c, 0x1c, 0x3c, 0x78, 0x70, 0x20, 0x00, 0x00 }, { 0x00, 0x00, 0x08, 0x0c, 0x1c, 0x1c, 0x1c, 0x1c, 0x38, 0x38, 0x18, 0x00, 0x00 }, { 0x00, 0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x08, 0x00, 0x00 }, { 0x00, 0x00, 0x08, 0x18, 0x1c, 0x1c, 0x1c, 0x1c, 0x0e, 0x0e, 0x0c, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x10, 0x30, 0x38, 0x38, 0x3c, 0x1e, 0x0e, 0x04, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x18, 0x3e, 0x3e, 0x3e, 0x3e, 0x1e, 0x04, 0x00, 0x00, 0x00 } }; const unsigned char TIRES[FRAMES][HEIGHT] = { { 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x28, 0x28, 0x00 }, { 0x00, 0x00, 0x08, 0x28, 0x20, 0x04, 0x0c, 0x08, 0x00, 0x04, 0x14, 0x10, 0x00 }, { 0x00, 0x00, 0x00, 0x18, 0x10, 0x0c, 0x4a, 0x46, 0x00, 0x08, 0x08, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x20, 0x28, 0x1c, 0x44, 0x40, 0x00, 0x08, 0x08, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x08, 0x28, 0x70, 0x44, 0x04, 0x00, 0x20, 0x20, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x18, 0x08, 0x30, 0x52, 0x62, 0x00, 0x10, 0x10, 0x00, 0x00 }, { 0x00, 0x00, 0x10, 0x14, 0x04, 0x20, 0x30, 0x10, 0x00, 0x20, 0x28, 0x08, 0x00 }, { 0x00, 0x00, 0x14, 0x14, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x14, 0x14, 0x00 }, { 0x00, 0x00, 0x08, 0x28, 0x20, 0x00, 0x10, 0x30, 0x20, 0x04, 0x14, 0x10, 0x00 }, { 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x62, 0x52, 0x30, 0x08, 0x18, 0x00, 0x00 }, { 0x00, 0x00, 0x10, 0x10, 0x00, 0x02, 0x22, 0x38, 0x14, 0x04, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x2a, 0x2a, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x04, 0x04, 0x00, 0x20, 0x22, 0x0e, 0x14, 0x10, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x46, 0x4a, 0x0c, 0x10, 0x18, 0x00, 0x00 }, { 0x00, 0x10, 0x14, 0x04, 0x00, 0x08, 0x0c, 0x04, 0x20, 0x28, 0x08, 0x00, 0x00 } }; clock_t tFPS; unsigned long f; void DrawFPS() { // Calculate stats unsigned int fps; tFPS = clock() - tFPS; fps = (f*CLK_TCK)/tFPS; tFPS = clock(); // Output stats gotoxy(0,0); printf("FPS: %u", fps); } unsigned int DLIAddr; extern char DLIData[4]; void SetupVBIandDLI(void); unsigned char i; void InitSprites(void) { // Setup PMG for Body for (i=0; i<5; i++) { bzero(PMBase[i],0x100); // Clear Player memory if (i==0) { POKE(711, PMColor[i]); } else { POKE(703+i, PMColor[i]); } // Set Player colors } POKE(54279, PMMem>>; // Tell ANTIC where the PM data is located POKE(53277, 2+1); // Tell GTIA to enable players + missile POKE(623, 32+16+1); // Tricolor players + enable fifth player + priority POKE(559, 32+16+8+4+2); // DMA Screen + Enable P/M + DMA Players + DMA Missiles + Single resolution // Setup DLI for Tires DLIAddr = PEEK(560) + 256*PEEK(561); SetupVBIandDLI(); } void ShowSprites(void) { unsigned int DLI = PEEK(560) + 256*PEEK(561); clock_t timer = clock(); unsigned int angle = 0; tFPS = clock(); while (!kbhit()) { // Update body position if (clock()>timer) { timer = clock(); angle++; for (i=0; i<PLAYERS; i++) { // Compute current position frame POKE(DLIAddr+3+PMYpos[i]/8, PEEK(DLIAddr+3+PMYpos[i]/8) % 128); // Remove DLI PMXpos[i] = 128+cc65_cos((angle+i*90)%360)/6; PMYpos[i] = 128+cc65_sin((angle+i*90)%360)/4; PMFrame[i] = ((12-(angle+(i+1)*90))%360)/23; POKE(DLIAddr+3+PMYpos[i]/8, PEEK(DLIAddr+3+PMYpos[i]/8) % 128 + 128); // Restore DLI DLIData[i] = PMXpos[i]; // Set horizontal position if (i==0) { POKE(53255, PMXpos[i]); POKE(53254, PMXpos[i]+2); POKE(53253, PMXpos[i]+4); POKE(53252, PMXpos[i]+6); } else { POKE(53247+i, PMXpos[i]); } // Set body data bzero(PMBody[i], HEIGHT); PMBody[i] = PMBase[i]+PMYpos[i]; memcpy(PMBody[i], BODY[PMFrame[i]], HEIGHT); // Set tire data bzero(PMTires[i], HEIGHT); PMTires[i] = PMBase[4]+PMYpos[i]; memcpy(PMTires[i], TIRES[PMFrame[i]], HEIGHT); } } // Next Frame if (f > 60) { DrawFPS(); f=0; } f++; } }
  17. I think that I can do something pretty efficient with DLI... working on it now.
  18. So Irgend, I am back with some progress. I decided to use P0 to P3 for the vehicle body, and flicker P4 (Missiles) for the tires. My first version flickers the tires one vehicle at-a-time, between 4 vehicles, so it looks very shaky (see attached xex and video). For my second version, I would like to setup a list of scanlines for which I change the P4 horizontal pos. This way I can show the tires as many times as possible within one frame (i.e: whenever two vehicles do not line up horizontally). Would it be possible to share with me a couple of ASM codelines showing how I can trigger code for specific scanlines? P.S: my current code is shown below: #include <cc65.h> #include <conio.h> #include <peekpoke.h> #include <stdio.h> #include <string.h> #include <time.h> #define PLAYERS (4) #define FRAMES (16) #define HEIGHT (13) #define PMGMem (0xA000) // sprites data unsigned int PMGBase[5] = {PMGMem+1024, PMGMem+1280, PMGMem+1536, PMGMem+1792, PMGMem+768}; unsigned int PMGAddr[5] = {PMGMem+1024, PMGMem+1280, PMGMem+1536, PMGMem+1792, PMGMem+768}; unsigned char PMColor[5] = {0x72, 0x22, 0xb6, 0xec, 0x00}; unsigned char xpos[4]; unsigned char ypos[4]; unsigned char frame[4]; #define FRAMES (16) #define HEIGHT (13) #define GAP (0) const unsigned char BODY[FRAMES][HEIGHT] = { { 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3e, 0x3e, 0x3e, 0x3e, 0x3c, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x04, 0x1e, 0x3e, 0x3e, 0x3e, 0x3e, 0x18, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x04, 0x0e, 0x1e, 0x3c, 0x38, 0x38, 0x30, 0x10, 0x00, 0x00 }, { 0x00, 0x00, 0x18, 0x1c, 0x1c, 0x38, 0x38, 0x38, 0x38, 0x30, 0x10, 0x00, 0x00 }, { 0x00, 0x00, 0x10, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x00, 0x00 }, { 0x00, 0x00, 0x30, 0x70, 0x70, 0x38, 0x38, 0x38, 0x38, 0x18, 0x10, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x20, 0x70, 0x78, 0x3c, 0x1c, 0x1c, 0x0c, 0x08, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x20, 0x78, 0x7c, 0x7c, 0x7c, 0x7c, 0x18, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7c, 0x7c, 0x7c, 0x7c, 0x3c, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x18, 0x7c, 0x7c, 0x7c, 0x7c, 0x78, 0x20, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x08, 0x0c, 0x1c, 0x1c, 0x3c, 0x78, 0x70, 0x20, 0x00, 0x00 }, { 0x00, 0x00, 0x08, 0x0c, 0x1c, 0x1c, 0x1c, 0x1c, 0x38, 0x38, 0x18, 0x00, 0x00 }, { 0x00, 0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x08, 0x00, 0x00 }, { 0x00, 0x00, 0x08, 0x18, 0x1c, 0x1c, 0x1c, 0x1c, 0x0e, 0x0e, 0x0c, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x10, 0x30, 0x38, 0x38, 0x3c, 0x1e, 0x0e, 0x04, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x18, 0x3e, 0x3e, 0x3e, 0x3e, 0x1e, 0x04, 0x00, 0x00, 0x00 } }; const unsigned char TYRES[FRAMES][HEIGHT] = { { 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x28, 0x28, 0x00 }, { 0x00, 0x00, 0x08, 0x28, 0x20, 0x04, 0x0c, 0x08, 0x00, 0x04, 0x14, 0x10, 0x00 }, { 0x00, 0x00, 0x00, 0x18, 0x10, 0x0c, 0x4a, 0x46, 0x00, 0x08, 0x08, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x20, 0x28, 0x1c, 0x44, 0x40, 0x00, 0x08, 0x08, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x08, 0x28, 0x70, 0x44, 0x04, 0x00, 0x20, 0x20, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x18, 0x08, 0x30, 0x52, 0x62, 0x00, 0x10, 0x10, 0x00, 0x00 }, { 0x00, 0x00, 0x10, 0x14, 0x04, 0x20, 0x30, 0x10, 0x00, 0x20, 0x28, 0x08, 0x00 }, { 0x00, 0x00, 0x14, 0x14, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x14, 0x14, 0x00 }, { 0x00, 0x00, 0x08, 0x28, 0x20, 0x00, 0x10, 0x30, 0x20, 0x04, 0x14, 0x10, 0x00 }, { 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x62, 0x52, 0x30, 0x08, 0x18, 0x00, 0x00 }, { 0x00, 0x00, 0x10, 0x10, 0x00, 0x02, 0x22, 0x38, 0x14, 0x04, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x2a, 0x2a, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x04, 0x04, 0x00, 0x20, 0x22, 0x0e, 0x14, 0x10, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x46, 0x4a, 0x0c, 0x10, 0x18, 0x00, 0x00 }, { 0x00, 0x10, 0x14, 0x04, 0x00, 0x08, 0x0c, 0x04, 0x20, 0x28, 0x08, 0x00, 0x00 } }; clock_t tFPS; unsigned long f; void DrawFPS() { // Calculate stats unsigned int fps; tFPS = clock() - tFPS; fps = (f*CLK_TCK)/tFPS; tFPS = clock(); // Output stats gotoxy(0,0); printf("FPS: %u", fps); } unsigned char i; void InitSprites(void) { POKE(54279, PMGMem>>; // Tell ANTIC where the PM data is located POKE(53277, 2+1); // Tell GTIA to enable players + missile POKE(623, 32+16+1); // Tricolor players + enable fifth player + priority POKE(559, 32+16+8+4+2); // DMA Screen + Enable P/M + DMA Players + DMA Missiles + Single resolution for (i=0; i<4; i++) { bzero(PMGAddr[i],0x100); // Clear Player memory POKE(704+i, PMColor[i]); // Set Player colors } bzero(PMGAddr[4],0x100); // Clear Missile memory POKE(711, PMColor[4]); // Set Player color } void ShowSprites(void) { clock_t timer = clock(); unsigned int angle = 0; tFPS = clock(); while (!kbhit()) { // Update body position if (clock()>timer) { timer = clock(); angle++; for (i=0; i<PLAYERS; i++) { xpos[i] = 128+cc65_cos((angle+i*90)%360)/6; ypos[i] = 128+cc65_sin((angle+i*90)%360)/4; frame[i] = ((12-(angle+(i+1)*90))%360)/23; POKE(53248+i, xpos[i]); bzero(PMGAddr[i], HEIGHT); PMGAddr[i] = PMGBase[i]+ypos[i]; memcpy(PMGAddr[i], BODY[frame[i]], HEIGHT); } } // Flicker tyres i = f%PLAYERS; bzero(PMGAddr[4], HEIGHT); PMGAddr[4] = PMGBase[4]+ypos[i]; POKE(53252, xpos[i]+6); POKE(53253, xpos[i]+4); POKE(53254, xpos[i]+2); POKE(53255, xpos[i]+0); memcpy(PMGAddr[4], TYRES[frame[i]], HEIGHT); // Next Frame if (f > 60) { DrawFPS(); f=0; } f++; } } sprites.mp4 sprites.xex
  19. Thanks for the further help Irgend! I am talking with Popmilo and Schlortt in order to figure out the best strategy for displaying the Map and PMs with best colours possible. I should perhaps start a new thread....
  20. Irgend, Thanks for providing the example, it looks like what I imagined. In most cases my sprites will not line up horizontally, however, they will sometime do (I am programming a top-down racing game). For instance, on a straight horizontal piece of track, the 4 sprites may all line up horizontally. So I guess I am left only with using the missiles, perhaps by mixing colors (P0/M1, P1/M2, P2/M3, P3/M0)... But that is too bad, because my sprites ideally need to share 2 colors (black for tires, cyan for cockpit) as shown in the attachements below. Cheers, Tony
  21. Thanks Popmilo, I have just sent you a PM now.
  22. Irgend, for the game I am developping I need to show a multicolor map in 160x192 (JAG ok), with 4 Players on top. However, JAG seems to hack into the PM code to cover-up the left/right sides of the screen, which means they are not available for player drawing. Is there any way round this?
×
×
  • Create New...