www.pudn.com > sn068s.zip > HELPER.C


/* 
 
 This contains variable and function defintions used by both ASM and C++ 
 
 Many of these will be moved to other files as soon as I figure out where 
  they belong... 
 
*/ 
 
/*#define DEBUG_KEYS*/ 
 
#include  
#include  
 
#include  
 
#include "helper.h" 
#include "sound.h" 
#include "cpu.h" 
 
/* PPU.asm */ 
extern unsigned char Layering_Mode; 
extern unsigned char Layer_Disable_Mask; 
extern unsigned char Offset_Change_Disable; 
extern void Update_Layering(void); 
extern void Toggle_Offset_Change(void); 
 
unsigned KEY_UP_1,KEY_DOWN_1,KEY_LEFT_1,KEY_RIGHT_1; 
unsigned KEY_A_1,KEY_B_1,KEY_X_1,KEY_Y_1; 
unsigned KEY_L_1,KEY_R_1,KEY_SELECT_1,KEY_START_1; 
unsigned KEY_UP_2,KEY_DOWN_2,KEY_LEFT_2,KEY_RIGHT_2; 
unsigned KEY_A_2,KEY_B_2,KEY_X_2,KEY_Y_2; 
unsigned KEY_L_2,KEY_R_2,KEY_SELECT_2,KEY_START_2; 
 
unsigned short ScreenX,ScreenY; 
signed char mouse_available; 
 
RGB SNES_Palette[256];                  /* So I can access from cc modules! */ 
colorBGR555 Real_SNES_Palette[256];     /* Updated by palette write */ 
colorRGB565 HICOLOUR_Palette[256][2];   /* values in here are plotted direct to PC! */ 
 
unsigned char BrightnessAdjust_64[16][32];  /* Used for brightness effect */ 
unsigned char BrightnessAdjust_256[16][32]; 
 
unsigned char MosaicLine[16][256];      /* Used for mosaic effect */ 
unsigned char MosaicCount[16][256]; 
 
/* 
 This sets up BrightnessAdjust to be 16 tables each with 32 elements; 
  table t, element e contains (t+1)e/2, except in table 0 where all 
  elements are 0. 
 This table is used for SNES brightness effects. 
 
 This sets up MosaicLine to be 16 tables each with 256 elements; 
  table t, element e contains e/(t+1)*(t+1). 
 This table is used for the mosaic effect. 
 
 This sets up MosaicCount to be 16 tables each with 256 elements; 
  table t, element e contains e/(t+1)*(t+1)+t+1-e. 
 This table is used for the mosaic effect. 
 
 This function may eventually be expanded to set up other tables. 
*/ 
int BGR_unpack_64[32768]; 
int BGR_unpack_256[32768]; 
 
void SetupTables(void) 
{ 
 int t; 
 int r, g, b; 
 for (b = 0; b < 32; b++) 
 { 
  for (g = 0; g < 32; g++) 
  { 
   for (r = 0; r < 32; r++) 
   { 
    BGR_unpack_64[(b << 10) + (g << 5) + r] = (b << 17) + (g << 9) + (r << 1); 
    BGR_unpack_256[(b << 10) + (g << 5) + r] = (b << 19) + (g << 11) + (r << 3); 
   } 
  } 
 } 
 
 for (t = 0; t < 256; t++) 
 { 
  BrightnessAdjust_64[0][t] = 0; 
  BrightnessAdjust_256[0][t] = 0; 
 } 
 
 for (t = 1; t < 16; t++) 
 { 
  int e; 
 
  for (e = 0; e < 32; e++) 
  { 
   BrightnessAdjust_64[t][e] = (t + 1) * e / 8; 
   BrightnessAdjust_256[t][e] = (t + 1) * e / 2; 
  } 
 
  for (e = 0; e < 256; e++) 
  { 
   MosaicLine[t][e] = e / (t + 1) * (t + 1); 
   MosaicCount[t][e] = e / (t + 1) * (t + 1) + t + 1 - e; 
  } 
 } 
} 
 
void Reset_CGRAM(void) 
{ 
 int i; 
 for (i = 0; i < 256; i++) 
 { 
  Real_SNES_Palette[i].red = 0; 
  Real_SNES_Palette[i].green = 0; 
  Real_SNES_Palette[i].blue = 0; 
 } 
} 
 
#ifdef DEBUG 
unsigned Frames; 
#endif 
 
/* Mode 0 = 320x200x256 VGA     : Mode 1 = 320x200x256 VGA  FIT */ 
/* Mode 2 = 320x240x256 MODE-X  : Mode 3 = 256x256x256 MODE-X   */ 
/* Mode 4 = 320x200x16b SVGA    : Mode 5 = 320x240x16b SVGA     */ 
/* Mode 6 = 640x480x16b SVGA    : Mode 7 = 640x480x16b SVGA FIT */ 
unsigned char SCREEN_MODE; 
 
DISPLAY_PROCESS display_process; 
 
unsigned char stretch_x, stretch_y; 
 
/* This flag is set when palette recomputation is necessary */ 
signed char PaletteChanged; 
 
unsigned char *SNES_Screen; 
unsigned char *SNES_Screen8; 
 
BITMAP *Allegro_Bitmap=0;   /* Renamed (I'm using mostly allegro now so what the hell!) */ 
BITMAP *Internal_Bitmap=0; 
BITMAP *Internal_Bitmap_blitsrc=0; 
 
unsigned FRAME_SKIP_MIN;    /* Min frames waited until refresh */ 
unsigned FRAME_SKIP_MAX;    /* Max frames waited until refresh */ 
unsigned char SNES_COUNTRY; /* Used for PAL/NTSC protection checks */ 
unsigned char JOYSTICK_ENABLED=0; 
unsigned char JOYSTICK_ENABLED2=0; 
unsigned char SPC_ENABLED=0; 
 
void OutputScreen() 
{ 
 static int ScreenCount = 0;    /* Used to determine screen filename */ 
 char filename[13]; 
 
 while (ScreenCount <= 999) 
 { 
  sprintf(filename, "PICCY%03u.PCX", ScreenCount++); 
  if (access(filename, F_OK)) break; 
 } 
 if (ScreenCount > 999){ ScreenCount = 0; return; } 
 
 if (SCREEN_MODE < 4 || SCREEN_MODE == 8) 
 { 
  save_pcx(filename, Internal_Bitmap_blitsrc, SNES_Palette); 
 } else { 
  save_pcx(filename, Allegro_Bitmap, SNES_Palette); 
 } 
} 
 
volatile char key_released[KEY_MAX]; 
 
static void key_release_callback(int scancode) 
{ 
 key_released[scancode & ~0x80] |= (scancode & 0x80); 
} 
END_OF_STATIC_FUNCTION(key_release_callback); 
 
void install_key_release_callback() 
{ 
 int i; 
 static int key_release_callback_installed = (0 != 0); 
 
 if (key_release_callback_installed) return; 
 
 LOCK_FUNCTION(key_release_callback); 
 LOCK_VARIABLE(key_released); 
 
 for (i = 0; i < KEY_MAX; i++) key_released[i] = -1; 
 
 keyboard_lowlevel_callback = key_release_callback; 
 key_release_callback_installed = (0 == 0); 
} 
 
#ifdef DEBUG_KEYS 
extern unsigned char SNES_W2118_NORM, SNES_W2118_NORM_First; 
extern unsigned char SNES_W2118_FULL, SNES_W2118_FULL_First; 
extern unsigned char SNES_W2119_NORM, SNES_W2119_NORM_First; 
extern unsigned char SNES_W2119_FULL, SNES_W2119_FULL_First; 
extern unsigned char SNES_W420B asm("SNES_W420B"); 
extern unsigned char do_HDMA asm("do_HDMA"); 
#endif 
 
int UPDATE_KEYS(void) 
{ 
 if (key[KEY_G] && key_released[KEY_G] != 0) 
 { 
extern void save_debug_dumps(void); 
  save_debug_dumps(); 
 } 
#ifdef DEBUG_KEYS 
 if (key[KEY_T] && key_released[KEY_T] != 0) 
 { 
  SNES_W2118_NORM = SNES_W2118_NORM_First = 0xC3; 
  SNES_W2118_FULL = SNES_W2118_FULL_First = 0xC3; 
  SNES_W2119_NORM = SNES_W2119_NORM_First = 0xC3; 
  SNES_W2119_FULL = SNES_W2119_FULL_First = 0xC3; 
 } 
 if (key[KEY_R] && key_released[KEY_R] != 0) 
 { 
  SNES_W420B = 0xC3; 
 } 
 if (key[KEY_Y] && key_released[KEY_Y] != 0) 
 { 
  do_HDMA = 0xC3; 
 } 
#endif 
 if (key[KEY_F1] && key_released[KEY_F1] != 0) 
 { 
  key_released[KEY_F1] = 0; SPC_MASK ^= 1; 
 } 
 while (key[KEY_F1]); 
 
 if (key[KEY_F2] && key_released[KEY_F2] != 0) 
 { 
  key_released[KEY_F2] = 0; SPC_MASK ^= 2; 
 } 
 
 if (key[KEY_F3] && key_released[KEY_F3] != 0) 
 { 
  key_released[KEY_F3] = 0; SPC_MASK ^= 4; 
 } 
 
 if (key[KEY_F4] && key_released[KEY_F4] != 0) 
 { 
  key_released[KEY_F4] = 0; SPC_MASK ^= 8; 
 } 
 
 if (key[KEY_F5] && key_released[KEY_F5] != 0) 
 { 
  key_released[KEY_F5] = 0; SPC_MASK ^= 0x10; 
 } 
 
 if (key[KEY_F6] && key_released[KEY_F6] != 0) 
 { 
  key_released[KEY_F6] = 0; SPC_MASK ^= 0x20; 
 } 
 
 if (key[KEY_F7] && key_released[KEY_F7] != 0) 
 { 
  key_released[KEY_F7] = 0; SPC_MASK ^= 0x40; 
 } 
 
 if (key[KEY_F8] && key_released[KEY_F8] != 0) 
 { 
  key_released[KEY_F8] = 0; SPC_MASK ^= 0x80; 
 } 
 
 if (key[KEY_F11] && key_released[KEY_F11] != 0) 
 { 
  key_released[KEY_F11] = 0; FPS_ENABLED ^= (0 - 1); 
 } 
 
 if (key[KEY_F12] && key_released[KEY_F12] != 0) 
 { 
  key_released[KEY_F12] = 0; BREAKS_ENABLED ^= (0 - 1); 
 } 
 
 if (key[KEY_1] && key_released[KEY_1] != 0) 
 { 
  key_released[KEY_1] = 0; Layer_Disable_Mask ^= 1; 
 } 
 
 if (key[KEY_2] && key_released[KEY_2] != 0) 
 { 
  key_released[KEY_2] = 0; Layer_Disable_Mask ^= 2; 
 } 
 
 if (key[KEY_3] && key_released[KEY_3] != 0) 
 { 
  key_released[KEY_3] = 0; Layer_Disable_Mask ^= 4; 
 } 
 
 if (key[KEY_4] && key_released[KEY_4] != 0) 
 { 
  key_released[KEY_4] = 0; Layer_Disable_Mask ^= 8; 
 } 
 
 if (key[KEY_5] && key_released[KEY_5] != 0) 
 { 
  key_released[KEY_5] = 0; Layer_Disable_Mask ^= 0x10; 
 } 
 
 if (key[KEY_7] && key_released[KEY_7] != 0) 
 { 
  key_released[KEY_7] = 0; Toggle_Offset_Change(); 
 } 
 
 if (key[KEY_6] && key_released[KEY_6] != 0) 
 { 
  key_released[KEY_6] = 0; 
  if (Offset_Change_Disable != 0) Toggle_Offset_Change(); 
  Layering_Mode = 0; 
  Layer_Disable_Mask = 0xFF; 
  SPC_MASK = 0xFF; 
 } 
 
 if (key[KEY_8] && key_released[KEY_8] != 0) 
 { 
  key_released[KEY_8] = 0; 
  if (Layering_Mode++ >= 2) Layering_Mode = 0; 
 } 
 
 Update_Layering(); 
 
 if (key[KEY_0] && key_released[KEY_0] != 0) 
 { 
  key_released[KEY_0] = 0; 
  OutputScreen(); 
 } 
 
 if (key[KEY_ESC] && key_released[KEY_ESC] != 0) 
 { 
  key_released[KEY_ESC] = 0; 
  return (0 == 0); 
 } 
 
 while (key[KEY_F9]); 
 
 return (0 != 0); 
} 
 
unsigned short MickeyRead;  /* MSB = Yyyyyyyy  LSB = Xxxxxxxx */ 
unsigned char MouseButts; 
 
void MickeyMouse() 
{ 
 int mx,my; 
 
 get_mouse_mickeys(&mx, &my); 
 
 MouseButts=mouse_b << 6;   /* save button state at time of read */ 
 
 MickeyRead = 0; 
 if (mx < 0) 
 { 
  MickeyRead |= 0x80; 
  mx = -mx; 
 } 
 MickeyRead |= (mx >> 1) & 0x7F; 
 if (my < 0) 
 { 
  MickeyRead |= 0x8000; 
  my = -my; 
 } 
 MickeyRead |= ((my >> 1) & 0x7F) << 8; 
} 
 
unsigned char BrightnessLevel;  /* SNES Brightness level, set up in PPU.asm */ 
 
char fixedpalettecheck=0; 
 
/* v0.15, we do palette conversion here */ 
/* v0.20, support for brightness effects in 16-bit modes */ 
void SetPalette() 
{ 
 /* NB - CGRamAddress[256*2] contains 256 palette entries as follows: 
         CGRamAddress[0*2+0] contains GGGRRRRR  R = Red component 
         CGRamAddress[0*2+1] contains 0BBBBBGG  G = Green component 
                                                B = Blue component 
 
    So each 2 addresses contains 1 palette entry. 
 */ 
  
 colorBGR555 color; 
 colorRGB565 Hi; 
 unsigned char Red,Green,Blue; 
 int Count; 
 
 if (SCREEN_MODE >= 4 && SCREEN_MODE <= 7) 
 /* Hi colour mode so do different palette set up */ 
 { 
  for (Count = 0; Count < 256; Count++) 
  { 
   color=Real_SNES_Palette[Count]; 
 
   Red = BrightnessAdjust_256[BrightnessLevel][color.red]; 
   Green = BrightnessAdjust_256[BrightnessLevel][color.green]; 
   Blue = BrightnessAdjust_256[BrightnessLevel][color.blue]; 
 
   Hi.red = Red >> 3; 
   Hi.green = Green >> 2; 
   Hi.blue = Blue >> 3; 
   HICOLOUR_Palette[Count][0] = Hi; 
   HICOLOUR_Palette[Count][1] = Hi; 
 
   /* We still have to do this or screenshot will fail */ 
   SNES_Palette[Count].r = Red >> 2; 
   SNES_Palette[Count].g = Green >> 2; 
   SNES_Palette[Count].b = Blue >> 2; 
  } 
 } else { 
  for(Count = 0; Count < 256; Count++) 
  { 
   color = Real_SNES_Palette[Count]; 
 
   Red = BrightnessAdjust_64[BrightnessLevel][color.red]; 
   Green = BrightnessAdjust_64[BrightnessLevel][color.green]; 
   Blue = BrightnessAdjust_64[BrightnessLevel][color.blue]; 
 
   SNES_Palette[Count].r = Red; 
   SNES_Palette[Count].g = Green; 
   SNES_Palette[Count].b = Blue; 
 
  } 
  set_palette_range((RGB *)SNES_Palette, 0, 255, FALSE); 
 } 
} 
 
extern unsigned Current_Line_Render; 
 
/* to do: treat stretch=1 as full stretch, 2+ as pixel-repetition count */ 
void Copy_Screen() 
{ 
 int out_x, out_y, size_x, size_y; 
 int ox, oy; 
 
 if (PaletteChanged) 
 { 
  SetPalette(); 
  PaletteChanged = 0; 
 } 
 
 switch (SCREEN_MODE) 
 { 
  case 0:   /* VGA mode 13h - linear 320x200 */ 
  case 2:   /* VGA mode-x - planar 320x240 */ 
  case 3:   /* VGA - linear 256x239 */ 
  case 8:   /* VESA2 - linear 320x240 */ 
   if (stretch_x) 
   { 
    out_x = 0; 
    size_x = ScreenX; 
   } 
   else 
   { 
    out_x = (ScreenX > 256) ? (ScreenX - 256) / 2 : 0; 
    size_x = (ScreenX < 256) ? ScreenX : 256; 
   } 
 
   if (stretch_y) 
   { 
    out_y = 0; 
    size_y = ScreenY; 
   } 
   else 
   { 
    out_y = (ScreenY > 239) ? (ScreenY - 239) / 2 : 0; 
    size_y = (ScreenY < Current_Line_Render) ? ScreenY : Current_Line_Render; 
   } 
 
   if (stretch_x || stretch_y) 
   { 
    if (Current_Line_Render < 239) 
    { 
     /* fill unrendered area with black */ 
     rectfill(Internal_Bitmap_blitsrc, 0, Current_Line_Render, 255, 238, 0); 
    } 
 
    stretch_blit(Internal_Bitmap_blitsrc, screen, 
     0, 0, stretch_x ? 256 : size_x, stretch_y ? 239 : size_y, 
     out_x, out_y, stretch_x ? ScreenX : size_x, stretch_y ? ScreenY : size_y); 
   } 
   else 
   { 
    blit(Internal_Bitmap_blitsrc, screen, 0, 0, out_x, out_y, size_x, size_y); 
 
    if (Current_Line_Render < 239 && ScreenY > Current_Line_Render) 
    { 
     size_y = (ScreenY <= 239) ? ScreenY : 239; 
 
     /* fill unrendered area with black */ 
     rectfill(screen, out_x, out_y + Current_Line_Render, 
      out_x + size_x - 1, out_y + size_y - 1, 0); 
    } 
   } 
 
   break; 
 
  case 1:   /* VGA mode 13h - linear 320x200 squash */ 
 
   if (Current_Line_Render < 239) 
   { 
    /* fill unrendered area with black */ 
    rectfill(Internal_Bitmap_blitsrc, 0, Current_Line_Render, 255, 238, 0); 
   } 
 
   stretch_blit(Internal_Bitmap_blitsrc, screen, 
    0, 0, 256, 239, 
    (320 - 256) / 2, 0, 256, ScreenY); 
 
   break; 
 
  case 4:   /* VESA 2 16-bit - 320x200 */ 
  case 5:   /* VESA 2 16-bit - 320x240 */ 
  case 6:   /* VESA 2 16-bit - 640x480 */ 
   out_x = (ScreenX > 256) ? (ScreenX - 256) / 2 : 0; 
   size_x = (ScreenX < 256) ? ScreenX : 256; 
   out_y = (ScreenY > 239) ? (ScreenY - 239) / 2 : 0; 
   size_y = (ScreenY < Current_Line_Render) ? ScreenY : Current_Line_Render; 
 
   for (oy = 0; oy < size_y; oy++) 
   { 
    for (ox = 0; ox < size_x; ox++) 
    { 
     int color = _getpixel(Internal_Bitmap_blitsrc, ox, oy); 
 
     color = ((unsigned short *)HICOLOUR_Palette)[color*2]; 
 
     _putpixel16(screen, out_x + ox, out_y + oy, color); 
    } 
   } 
 
   if (Current_Line_Render < 239 && ScreenY > Current_Line_Render) 
   { 
    size_y = (ScreenY < 239) ? ScreenY : 239; 
 
    /* fill unrendered area with black */ 
    rectfill(Internal_Bitmap_blitsrc, out_x, out_y + Current_Line_Render, 255, out_y + size_y - 1, 0); 
   } 
 
   break; 
 
  case 7:   /* VESA 2 16-bit - 640x480 stretch */ 
   break; 
 
  default: 
   blit(Allegro_Bitmap, screen, 0, 0, 0, 0, ScreenX, ScreenY); 
 } 
}