English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 16 December 2018, 12:24   #1
LeCaravage
Registered User
 
LeCaravage's Avatar
 
Join Date: May 2017
Location: AmigaLand
Posts: 456
Ocs clxdat & clxcon

Hey,

-Qst for Amiga 500 OCS-


I have pain in the butt understanding how works these hardware collision detections registers.
I'm trying to detect collision between sprites and bobs. The screen is dualplayfield.

I set all bits on in CLXCON once at start and then at each frame I read CLXDAT then I "AND.W" it with #%0000000111100000

It doesn't work.
Any help because the mist is deep ^^
LeCaravage is offline  
Old 16 December 2018, 13:01   #2
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,502
If you set all bits, you only get collision if all 6 planes had bit set which probably isn't what you wanted?

Perhaps this helps: http://eab.abime.net/showpost.php?p=965074&postcount=2
Toni Wilen is offline  
Old 16 December 2018, 17:19   #3
LeCaravage
Registered User
 
LeCaravage's Avatar
 
Join Date: May 2017
Location: AmigaLand
Posts: 456
When you start to input random values, that means you must pass.
Too bad because this hardware feature would have saved some raster time.
Anyway, thanks for helping.
LeCaravage is offline  
Old 20 December 2018, 09:27   #4
Asman
68k
 
Asman's Avatar
 
Join Date: Sep 2005
Location: Somewhere
Posts: 828
@LeCaravage
Please check my very simple game - there is used hardware collision.

https://github.com/asman2000/grim

If you have questions then just ask.
Asman is offline  
Old 21 December 2018, 15:45   #5
LeCaravage
Registered User
 
LeCaravage's Avatar
 
Join Date: May 2017
Location: AmigaLand
Posts: 456
@Asman
Thanks for the help. Much appreciated.
I checked your code and it seems I use a similar method than yours.
But I use a dualplayfield, may be it's what makes the pb.
It's like it only detects a certain color or so.
Anyway, as I lost too much time on this hardware method, I skipped to a cross box detection, it's not very accurate but it does the job.
LeCaravage is offline  
Old 08 February 2019, 14:35   #6
Photon
Moderator
 
Photon's Avatar
 
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,602
Dual Playfield is perfect for collision detection
Photon is offline  
Old 06 October 2021, 08:29   #7
thyslo
Registered User
 
Join Date: Apr 2018
Location: Germany
Posts: 189
I run into a similar problem as the thread opener, so I post my question here.

I've taken the RKRM SimpleSprite example as inspiration and would like to see if it is possible to detects the collision of a sprite with a colored square (pen 14, plane 4) which is drawn into an Intuition Windows RastPort.

So in initialization stage I enabled collision detection for plane 4

Code:
  // Enable collision detection for all sprites vs plane 4 (pens 12..15)
  pCustom->clxcon = 0x104f;
And then in the event loop I poll the CLXDAT and display its contents in the window title.

Code:
  char charBuf[80];
  ULONG clxDat = pCustom->clxdat;
  sprintf(charBuf, "CLXDAT = %lu", clxDat);
  SetWindowTitles(m_pWindow, charBuf, (STRPTR) ~0);
So I have my custom created sprite and the mouse pointer, which as always is another sprite. And when these two collide, the CLXDAT value in the window title changes as expected. But if mouse pointer or my custom sprite collide/overlap with the drawn square of pen 14, CLXDAt doesn't change. The collision is not recognized.

Here's a video clip of the situation I uploaded to [ Show youtube player ]

And this is the full source of my {experimantal|hacky} example:
Code:
/**
 * Tests if hardware collission detection between sprite<->bitplanes is
 * possible with Amiga operating system enabled.
 *
 */
#include <stdlib.h>
#include <stdio.h>

#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <dos/dos.h>
#include <graphics/gfxmacros.h>
#include <graphics/sprite.h>
#include <hardware/custom.h>
#include <intuition/intuition.h>
#include <intuition/screens.h>


/**
 *  Amiga chipset address
 */
extern struct Custom custom;
volatile struct Custom* pCustom = &custom;


/**
 * Function declarations
 */
void intuiEventLoop();
void handleRawKeys(struct IntuiMessage* pMsg);
void displayCollisionState();
int createSprite(struct ViewPort* pViewPort, 
                 struct SimpleSprite* pSprite, 
                 int spriteNum);

int cleanExit(int errorCode);


/**
 * Global variables
 */ 
struct Screen* m_pScreen = NULL;
struct Window* m_pWindow = NULL;
UWORD* m_pSpriteData;
int m_SpriteNum = -1;
struct SimpleSprite m_Sprite = {0};

// Sprite data (RKRM SimpleSprite example)
UWORD spriteDataArray[ ] = 
{
    0, 0,           // position control          
    0xffff, 0x0000, // image data line 1, color 1
    0xffff, 0x0000, // image data line 2, color 1
    0x0000, 0xffff, // image data line 3, color 2
    0x0000, 0xffff, // image data line 4, color 2
    0x0000, 0x0000, // image data line 5, transparent
    0x0000, 0xffff, // image data line 6, color 2
    0x0000, 0xffff, // image data line 7, color 2
    0xffff, 0xffff, // image data line 8, color 3
    0xffff, 0xffff, // image data line 9, color 3
    0, 0            // reserved, must init to 0 0
};

ULONG m_BackgroundColors[] =
{
  0x000C0004, // 0x0010 - Load 12 colors, starting from 0x004
  0xFBFBFBFB, 0xF1F1F1F1, 0xC7C7C7C7,
  0x46464646, 0x85858585, 0x88888888,
  0x83838383, 0xA5A5A5A5, 0x98989898,
  0x68686868, 0x9D9D9D9D, 0x6A6A6A6A,
  0xAEAEAEAE, 0xC0C0C0C0, 0x7C7C7C7C,
  0x98989898, 0x97979797, 0x1A1A1A1A,
  0xB8B8B8B8, 0xBBBBBBBB, 0x24242424,
  0xD7D7D7D7, 0x99999999, 0x21212121,
  0xFAFAFAFA, 0xBDBDBDBD, 0x2F2F2F2F,
  0xD6D6D6D6, 0x5D5D5D5D, 0xE0E0E0E,
  0xCCCCCCCC, 0x24242424, 0x1D1D1D1D,
  0xFBFBFBFB, 0x49494949, 0x34343434,
  0x00000000  // Termination
};



int main(int argc, char** argv)
{
  int i;
  ULONG spriteDataSize;
  
  m_pSpriteData = NULL;

  m_pScreen = OpenScreenTags(NULL,
    SA_LikeWorkbench, TRUE,
    SA_DisplayID, PAL_MONITOR_ID|LORES_KEY,
    SA_Depth, 4,
    SA_Width, 320,
    SA_Height, 256,
    SA_Title, "Use the cursor keys to move sprite.",
    SA_Type, CUSTOMSCREEN,
    SA_Exclusive, TRUE,
    TAG_DONE);
  
  if(m_pScreen == NULL)
  {
    printf("Failed to open screen.\n");
    cleanExit(RETURN_FAIL);
  }

  m_pWindow = OpenWindowTags(NULL,
    WA_CustomScreen, m_pScreen,
    WA_Left, 0,
    WA_Top, 12,
    WA_Width, 600,
    WA_Height, 200,
    WA_Title, "",
    WA_SmartRefresh, TRUE,
    WA_NewLookMenus, TRUE,
    WA_Flags, WFLG_ACTIVATE|WFLG_CLOSEGADGET|WFLG_DRAGBAR|WFLG_GIMMEZEROZERO,
    WA_IDCMP, IDCMP_CLOSEWINDOW|IDCMP_INTUITICKS|IDCMP_RAWKEY,
    TAG_DONE);
  
  if(m_pWindow == NULL)
  {
    printf("Failed to open window.\n");
    cleanExit(RETURN_FAIL);
  }

  // Load the colors for pens 4..16 into the viewport
  LoadRGB32(&m_pScreen->ViewPort, m_BackgroundColors);

  // Move given sprite data to CHIP memory
  spriteDataSize = sizeof(spriteDataArray) / sizeof(spriteDataArray[0]);
  m_pSpriteData = AllocVec(sizeof(UWORD) * spriteDataSize, MEMF_CHIP|MEMF_CLEAR);
  for(i = 0; i < spriteDataSize; i++)
  {
    m_pSpriteData[i] = spriteDataArray[i];
  }

  // Create sprite #2
  m_SpriteNum = createSprite(&m_pScreen->ViewPort, &m_Sprite, 2);
  if(m_SpriteNum < 0)
  {
    printf("Failed to create sprite.\n");
    cleanExit(RETURN_FAIL);
  }

  // Draw a red square in the window using pen 14 (plane 4)
  SetAPen(m_pWindow->RPort, 14);
  RectFill(m_pWindow->RPort, 100, 50, 200, 150);

  // Enable collision detection for all sprites vs plane 4 (pens 12..15)
  pCustom->clxcon = 0x104f; 

  intuiEventLoop();
  cleanExit(RETURN_OK);
}


void intuiEventLoop()
{
  struct IntuiMessage* pMsg;
  BOOL isExitRequested = FALSE;

  do
  {
    Wait(1L << m_pWindow->UserPort->mp_SigBit);
    while (NULL != (pMsg = (struct IntuiMessage*)GetMsg(m_pWindow->UserPort)))
    {
      switch(pMsg->Class)
      {
        case CLOSEWINDOW:
        {
          isExitRequested = TRUE;
          break;
        }
        case RAWKEY:
        {
          handleRawKeys(pMsg);
          break;
        }
        case INTUITICKS:
        {
          displayCollisionState();
          break;
        }
      }

      ReplyMsg((struct Message*)pMsg);
    }
  }
  while(isExitRequested == FALSE);
}


void handleRawKeys(struct IntuiMessage* pMsg)
{
  struct SimpleSprite* pSprite = &m_Sprite;

  switch (pMsg->Code)
  {
  case CURSORLEFT:
    MoveSprite(NULL, pSprite, pSprite->x - 1, pSprite->y);
    break;
  case CURSORRIGHT:
    MoveSprite(NULL, pSprite, pSprite->x + 1, pSprite->y);
    break;
  case CURSORUP:
    MoveSprite(NULL, pSprite, pSprite->x, pSprite->y - 1);
    break;
  case CURSORDOWN:
    MoveSprite(NULL, pSprite, pSprite->x, pSprite->y + 1);
    break;
  default:
    return;
  }

  // One move per video frame
  WaitTOF();
}


void displayCollisionState()
{
  char charBuf[80];
  ULONG clxDat = pCustom->clxdat;
  sprintf(charBuf, "CLXDAT = %lu", clxDat);
  SetWindowTitles(m_pWindow, charBuf, (STRPTR) ~0);
}


int createSprite(struct ViewPort* pViewPort, 
                 struct SimpleSprite* pSprite, 
                 int spriteNum)
{
  WORD sprite_num;
  SHORT color_reg;

  // Trying to get sprite
  sprite_num = GetSprite(pSprite, spriteNum);
  if(sprite_num < 0)
  {
    return -1;
  }

  // Calculate the correct base color register number, set up the color
  // registers.
  color_reg = 16 + ((sprite_num & 0x06) << 1);
  SetRGB4(pViewPort, color_reg + 1, 12,  3,  8);
  SetRGB4(pViewPort, color_reg + 2, 13, 13, 13);
  SetRGB4(pViewPort, color_reg + 3,  4,  4, 15);

  //  Initialize position and size info to match that shown in
  //  spriteDataArray so system knows layout of data later
  pSprite->x = 0;
  pSprite->y = 0;
  pSprite->height = 9;

  // Install sprite data and move sprite to start position.
  ChangeSprite(NULL, pSprite, m_pSpriteData);
  MoveSprite(NULL, pSprite, 30, 30);

  return sprite_num;
}


int cleanExit(int errorCode)
{
  if(m_SpriteNum > -1)
  {
    // If you turn off the sprite at the wrong time (when it is being
    // displayed), the sprite will appear as a vertical bar on the
    // screen.  To really get rid of the sprite, you must OFF_SPRITE
    // while it is not displayed.  This is hard in a multi-tasking
    // system (the solution is not addressed in this program).
    ON_SPRITE ; // Just to be sure
    FreeSprite(m_SpriteNum);
  }

  if(m_pSpriteData != NULL)
  {
    FreeVec(m_pSpriteData);
    m_pSpriteData = NULL;
  }

  if(m_pWindow != NULL)
  {
    CloseWindow(m_pWindow);
    m_pWindow = NULL;
  }

  if(m_pScreen != NULL)
  {
    CloseScreen(m_pScreen);
    m_pScreen = NULL;
  }

  exit(errorCode);
}
I've the nagging feel that I misunderstood how hardware collision detection between sprites and bitplanes really works.

So maybe anyone can help and spot my failure in CLXCON / CLXDAT handling?
thyslo is offline  
Old 06 October 2021, 10:29   #8
sparhawk
Registered User
 
sparhawk's Avatar
 
Join Date: Sep 2019
Location: Essen/Germany
Age: 55
Posts: 463
Are you sure that the OS didn't read the collision before you? According to the docs, the register is cleared after a read operation, so if the OS does it before you, you wouldn't see it IMO.

http://amigadev.elowar.com/read/ADCD.../node015C.html
sparhawk is offline  
Old 06 October 2021, 10:47   #9
thyslo
Registered User
 
Join Date: Apr 2018
Location: Germany
Posts: 189
Yeah that is also a point I was unsure about. But for sprite-to-sprite collisions it works in my example.
thyslo is offline  
Old 06 October 2021, 11:29   #10
ross
Defendit numerus
 
ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
Quote:
Originally Posted by thyslo View Post
Code:
  // Enable collision detection for all sprites vs plane 4 (pens 12..15)
  pCustom->clxcon = 0x104f;
This value seems wrong.. Did you reversed the bits?
ross is offline  
Old 06 October 2021, 11:45   #11
thyslo
Registered User
 
Join Date: Apr 2018
Location: Germany
Posts: 189
I inteded to map/set it like this (see the 'Set' column)

Code:
CLXCON:

Bit | Set    | Collission
-------------| ------------------------------------
 15 | 1      | ENSP7  Enable Sprite 7 (ORed with Sprite 6)
 14 | 1      | ENSP5  Enable Sprite 5 (ORed with Sprite 4)
 13 | 1      | ENSP3  Enable Sprite 3 (ORed with Sprite 2)
 12 | 1      | ENSP1  Enable Sprite 1 (ORed with Sprite 0)
 11 | 0      | ENBP6  Enable bit plane 6 (match reqd. for collision)
 10 | 0      | ENBP5  Enable bit plane 5 (match reqd. for collision)
 09 | 1      | ENBP4  Enable bit plane 4 (match reqd. for collision)
 08 | 0      | ENBP3  Enable bit plane 3 (match reqd. for collision)
 07 | 0      | ENBP2  Enable bit plane 2 (match reqd. for collision)
 06 | 0      | ENBP1  Enable bit plane 1 (match reqd. for collision)
 05 | 0      | MVBP6  Match value for bit plane 6 collision
 04 | 0      | MVBP5  Match value for bit plane 5 collision
 03 | 1      | MVBP4  Match value for bit plane 4 collision
 02 | 0      | MVBP3  Match value for bit plane 3 collision
 01 | 0      | MVBP2  Match value for bit plane 2 collision
 00 | 0      | MVBP1  Match value for bit plane 1 collision

So I thought, %0001000001001111 = 0x104f is the right value. Is this reversed?

(Sorry if this might be a totally trivial question)

Edit: If I think about it, it really looks reversed. This afternoon I'll try it the other way around:-)

Last edited by thyslo; 06 October 2023 at 09:23. Reason: Fixed bit names
thyslo is offline  
Old 06 October 2021, 11:53   #12
sparhawk
Registered User
 
sparhawk's Avatar
 
Join Date: Sep 2019
Location: Essen/Germany
Age: 55
Posts: 463
Yeah it's reversed and also wrong. AFAIK it should be $f204 according to your list.

Code:
15 .............. 0
1111 0010 0000 1000 
   f    2    0    4
sparhawk is offline  
Old 06 October 2021, 12:16   #13
thyslo
Registered User
 
Join Date: Apr 2018
Location: Germany
Posts: 189
Yeah Bit 15 is the one with the highest significance, of course:-)

So I'll try it with $f204 this afternoon. Thank you!

Last edited by thyslo; 06 October 2021 at 12:27.
thyslo is offline  
Old 06 October 2021, 20:13   #14
thyslo
Registered User
 
Join Date: Apr 2018
Location: Germany
Posts: 189
So I tested it and can confirm that with CLXCON set to $2F4 the collision between sprites<->sprites and also between sprites<->bitplane4 works

I haven't evaluated CLXDAT yet, but I see that it changes in the collision moment.

The only thing odd about it is that sprite collision is detected as soon as the bounding boxes overlap, what seem right. But the collision with bitplane 4 is not detected until a sprite is completely in the colored area, see the video [ Show youtube player ].

Maybe I first should evaluate the CLXDAT value to see whats going on..
thyslo is offline  
Old 07 October 2021, 21:06   #15
thyslo
Registered User
 
Join Date: Apr 2018
Location: Germany
Posts: 189
Finally it works for my purposes.

Changing the CLXDAT display in window border to bits and some thinking revealed that CLXCON=0xf20f is more what I'm after.

Here's an updated video: [ Show youtube player ]

The final code of my test program in case anyone wants to experiment with collision detection themselves:

Code:
/**
 * Tests if hardware collission detection between sprite<->bitplanes is
 * possible with Amiga operating system enabled.
 *
 */
#include <stdlib.h>
#include <stdio.h>

#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <dos/dos.h>
#include <graphics/gfxmacros.h>
#include <graphics/sprite.h>
#include <hardware/custom.h>
#include <intuition/intuition.h>
#include <intuition/screens.h>


/**
 *  Amiga chipset address
 */
extern struct Custom custom;
volatile struct Custom* pCustom = &custom;


/**
 * Function declarations
 */
void intuiEventLoop();
void handleRawKeys(struct IntuiMessage* pMsg);
void displayCollisionState();
void convertNumberToBits(char* pDstBuf, size_t const size, void const* const pNumber);
int createSprite(struct ViewPort* pViewPort,
                 struct SimpleSprite* pSprite,
                 int spriteNum);

int cleanExit(int errorCode);


/**
 * Global variables
 */
struct Screen* m_pScreen = NULL;
struct Window* m_pWindow = NULL;
UWORD* m_pSpriteData;
int m_SpriteNum = -1;
struct SimpleSprite m_Sprite = {0};

// Sprite data (RKRM SimpleSprite example)
UWORD spriteDataArray[ ] =
{
    0, 0,           // position control
    0xffff, 0x0000, // image data line 1, color 1
    0xffff, 0x0000, // image data line 2, color 1
    0x0000, 0xffff, // image data line 3, color 2
    0x0000, 0xffff, // image data line 4, color 2
    0x0000, 0x0000, // image data line 5, transparent
    0x0000, 0xffff, // image data line 6, color 2
    0x0000, 0xffff, // image data line 7, color 2
    0xffff, 0xffff, // image data line 8, color 3
    0xffff, 0xffff, // image data line 9, color 3
    0, 0            // reserved, must init to 0 0
};

ULONG m_BackgroundColors[] =
{
  0x000C0004, // 0x0010 - Load 12 colors, starting from 0x004
  0xFBFBFBFB, 0xF1F1F1F1, 0xC7C7C7C7,
  0x46464646, 0x85858585, 0x88888888,
  0x83838383, 0xA5A5A5A5, 0x98989898,
  0x68686868, 0x9D9D9D9D, 0x6A6A6A6A,
  0xAEAEAEAE, 0xC0C0C0C0, 0x7C7C7C7C,
  0x98989898, 0x97979797, 0x1A1A1A1A,
  0xB8B8B8B8, 0xBBBBBBBB, 0x24242424,
  0xD7D7D7D7, 0x99999999, 0x21212121,
  0xFAFAFAFA, 0xBDBDBDBD, 0x2F2F2F2F,
  0xD6D6D6D6, 0x5D5D5D5D, 0xE0E0E0E,
  0xCCCCCCCC, 0x24242424, 0x1D1D1D1D,
  0xFBFBFBFB, 0x49494949, 0x34343434,
  0x00000000  // Termination
};


int main(int argc, char** argv)
{
  int i;
  ULONG spriteDataSize;

  m_pSpriteData = NULL;

  m_pScreen = OpenScreenTags(NULL,
    SA_LikeWorkbench, TRUE,
    SA_DisplayID, PAL_MONITOR_ID|LORES_KEY,
    SA_Depth, 4,
    SA_Width, 320,
    SA_Height, 256,
    SA_Title, "Use the cursor keys to move sprite.",
    SA_Type, CUSTOMSCREEN,
    SA_Exclusive, TRUE,
    TAG_DONE);

  if(m_pScreen == NULL)
  {
    printf("Failed to open screen.\n");
    cleanExit(RETURN_FAIL);
  }

  m_pWindow = OpenWindowTags(NULL,
    WA_CustomScreen, m_pScreen,
    WA_Left, 0,
    WA_Top, 12,
    WA_Width, 600,
    WA_Height, 200,
    WA_Title, "",
    WA_SmartRefresh, TRUE,
    WA_NewLookMenus, TRUE,
    WA_Flags, WFLG_ACTIVATE|WFLG_CLOSEGADGET|WFLG_DRAGBAR|WFLG_GIMMEZEROZERO,
    WA_IDCMP, IDCMP_CLOSEWINDOW|IDCMP_INTUITICKS|IDCMP_RAWKEY,
    TAG_DONE);

  if(m_pWindow == NULL)
  {
    printf("Failed to open window.\n");
    cleanExit(RETURN_FAIL);
  }

  // Load the colors for pens 4..16 into the viewport
  LoadRGB32(&m_pScreen->ViewPort, m_BackgroundColors);

  // Move given sprite data to CHIP memory
  spriteDataSize = sizeof(spriteDataArray) / sizeof(spriteDataArray[0]);
  m_pSpriteData = AllocVec(sizeof(UWORD) * spriteDataSize, MEMF_CHIP|MEMF_CLEAR);
  for(i = 0; i < spriteDataSize; i++)
  {
    m_pSpriteData[i] = spriteDataArray[i];
  }

  // Create sprite #2
  m_SpriteNum = createSprite(&m_pScreen->ViewPort, &m_Sprite, 2);
  if(m_SpriteNum < 0)
  {
    printf("Failed to create sprite.\n");
    cleanExit(RETURN_FAIL);
  }

  // Draw a red square in the window using pen 14 (plane 4)
  SetAPen(m_pWindow->RPort, 14);
  RectFill(m_pWindow->RPort, 100, 50, 200, 150);

  // Enable collision detection for all sprites vs plane 4 (pens 12..15)
  pCustom->clxcon = 0xf20f;

  intuiEventLoop();
  cleanExit(RETURN_OK);
}


void intuiEventLoop()
{
  struct IntuiMessage* pMsg;
  BOOL isExitRequested = FALSE;

  do
  {
    Wait(1L << m_pWindow->UserPort->mp_SigBit);
    while (NULL != (pMsg = (struct IntuiMessage*)GetMsg(m_pWindow->UserPort)))
    {
      switch(pMsg->Class)
      {
        case CLOSEWINDOW:
        {
          isExitRequested = TRUE;
          break;
        }
        case RAWKEY:
        {
          handleRawKeys(pMsg);
          break;
        }
        case INTUITICKS:
        {
          displayCollisionState();
          break;
        }
      }

      ReplyMsg((struct Message*)pMsg);
    }
  }
  while(isExitRequested == FALSE);
}


void handleRawKeys(struct IntuiMessage* pMsg)
{
  struct SimpleSprite* pSprite = &m_Sprite;

  switch (pMsg->Code)
  {
  case CURSORLEFT:
    MoveSprite(NULL, pSprite, pSprite->x - 1, pSprite->y);
    break;
  case CURSORRIGHT:
    MoveSprite(NULL, pSprite, pSprite->x + 1, pSprite->y);
    break;
  case CURSORUP:
    MoveSprite(NULL, pSprite, pSprite->x, pSprite->y - 1);
    break;
  case CURSORDOWN:
    MoveSprite(NULL, pSprite, pSprite->x, pSprite->y + 1);
    break;
  default:
    return;
  }

  // One move per video frame
  WaitTOF();
}


void displayCollisionState()
{
  char charBuf[80];
  UWORD clxDat = pCustom->clxdat;
  sprintf(charBuf, "CLXDAT = ");

  // Note: The Length of the text above is 9. This is text is skipped
  // in next line.
  convertNumberToBits(charBuf + 9, 2, &clxDat);
  SetWindowTitles(m_pWindow, charBuf, (STRPTR) ~0);
}

/**
 * Prints the bit representation of a number into a buffer
 *
 * @param pDstBuf Buffer to write bytes into
 * @param size Number of bytes to print
 * @param pNumber Pointer to the Number to print
 */
void convertNumberToBits(char* pDstBuf, size_t const size, void const* const pNumber)
{
  unsigned char* p = (unsigned char*)pNumber;
  unsigned char byte;
  size_t i;
  int j;

  // Converted stackoverflow answer to BIG ENDIAN
  // https://stackoverflow.com/questions/111928/is-there-a-printf-converter-to-print-in-binary-format
  for (i = 0; i < size; i++)
  {
    for (j = 7; j >= 0; j--)
    {
      byte = (p[i] >> j) & 1;
      sprintf(pDstBuf++, "%u", byte);
    }
    sprintf(pDstBuf++, " ");
  }
}


int createSprite(struct ViewPort* pViewPort,
                 struct SimpleSprite* pSprite,
                 int spriteNum)
{
  WORD sprite_num;
  SHORT color_reg;

  // Trying to get sprite
  sprite_num = GetSprite(pSprite, spriteNum);
  if(sprite_num < 0)
  {
    return -1;
  }

  // Calculate the correct base color register number, set up the color
  // registers.
  color_reg = 16 + ((sprite_num & 0x06) << 1);
  SetRGB4(pViewPort, color_reg + 1, 12,  3,  8);
  SetRGB4(pViewPort, color_reg + 2, 13, 13, 13);
  SetRGB4(pViewPort, color_reg + 3,  4,  4, 15);

  //  Initialize position and size info to match that shown in
  //  spriteDataArray so system knows layout of data later
  pSprite->x = 0;
  pSprite->y = 0;
  pSprite->height = 9;

  // Install sprite data and move sprite to start position.
  ChangeSprite(NULL, pSprite, m_pSpriteData);
  MoveSprite(NULL, pSprite, 30, 30);

  return sprite_num;
}


int cleanExit(int errorCode)
{
  if(m_SpriteNum > -1)
  {
    // If you turn off the sprite at the wrong time (when it is being
    // displayed), the sprite will appear as a vertical bar on the
    // screen.  To really get rid of the sprite, you must OFF_SPRITE
    // while it is not displayed.  This is hard in a multi-tasking
    // system (the solution is not addressed in this program).
    ON_SPRITE ; // Just to be sure
    FreeSprite(m_SpriteNum);
  }

  if(m_pSpriteData != NULL)
  {
    FreeVec(m_pSpriteData);
    m_pSpriteData = NULL;
  }

  if(m_pWindow != NULL)
  {
    CloseWindow(m_pWindow);
    m_pWindow = NULL;
  }

  if(m_pScreen != NULL)
  {
    CloseScreen(m_pScreen);
    m_pScreen = NULL;
  }

  exit(errorCode);
}
thyslo is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Monkey Island 1 & 2 - Remastered for OCS / ECS HAM6_Video Amiga scene 22 07 April 2017 16:10
Morton Strikes Back & Trog [OCS & AGA] - Trained Versions DamienD support.Games 7 13 October 2016 09:53
Alterego (+3) Trainer & Zerosphere (+5) OCS warfalcon Amiga scene 8 12 January 2016 15:43
Pinball Dreams & Pinball Fantasies - Special Edition (OCS/ECS) teh HOL contributions 3 23 March 2012 14:39
aminet & amiga Plus cds - floppy & cd software/games - hardware & magazines for SALE! bastibs MarketPlace 1 07 May 2008 11:33

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 15:26.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.08804 seconds with 15 queries