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); } }