📄 galpanic.c
字号:
/******************************************************************************//* *//* GALS PANIC (c) 1990 KANEKO *//* *//******************************************************************************//* Original MAME driver by Nicola Salmoria.Converted to Raine by Anders Granlund.*/#include "gameinc.h"#include "galpanic.h"#include "taitosnd.h"#include "sasound.h"void galpanic_closest_colour_init(void);UINT16 galpanic_closest_colour(int r, int g, int b);static struct DIR_INFO GalPanic_dirs[] ={ { "galpanic", }, { "GalPanic", }, { NULL, },};static struct ROM_INFO GalPanic_roms[] ={ { "pm110.4m2", 0x080000, 0xae6b17a8, 0, 0, 0, }, { "pm109.4m1", 0x080000, 0xb85d792d, 0, 0, 0, }, { "pm112.6", 0x020000, 0x7b972b58, 0, 0, 0, }, { "pm111.5", 0x020000, 0x4eb7298d, 0, 0, 0, }, { "pm004e.8", 0x080000, 0xd3af52bc, 0, 0, 0, }, { "pm005e.7", 0x080000, 0xd7ec650c, 0, 0, 0, }, { "pm000e.15", 0x080000, 0x5d220f3f, 0, 0, 0, }, { "pm001e.14", 0x080000, 0x90433eb1, 0, 0, 0, }, { "pm002e.17", 0x080000, 0x713ee898, 0, 0, 0, }, { "pm003e.16", 0x080000, 0x6bb060fd, 0, 0, 0, }, { "pm006e.67", 0x100000, 0x57aec037, 0, 0, 0, }, { "pm008e.l", 0x080000, 0xd9379ba8, 0, 0, 0, }, { "pm007e.u", 0x080000, 0xc7ed7950, 0, 0, 0, }, { NULL, 0, 0, 0, 0, 0, },};static struct INPUT_INFO GalPanic_inputs[] ={ { KB_DEF_COIN1, MSG_COIN1, 0x080005, 0x04, BIT_ACTIVE_0 }, { KB_DEF_COIN2, MSG_COIN2, 0x080005, 0x08, BIT_ACTIVE_0 }, { KB_DEF_TILT, MSG_TILT, 0x800005, 0x20, BIT_ACTIVE_0 }, { KB_DEF_SERVICE, MSG_SERVICE, 0x800005, 0x40, BIT_ACTIVE_0 }, { KB_DEF_P1_START, MSG_P1_START, 0x080005, 0x01, BIT_ACTIVE_0 }, { KB_DEF_P1_UP, MSG_P1_UP, 0x080001, 0x01, BIT_ACTIVE_0 }, { KB_DEF_P1_DOWN, MSG_P1_DOWN, 0x080001, 0x02, BIT_ACTIVE_0 }, { KB_DEF_P1_LEFT, MSG_P1_LEFT, 0x080001, 0x04, BIT_ACTIVE_0 }, { KB_DEF_P1_RIGHT, MSG_P1_RIGHT, 0x080001, 0x08, BIT_ACTIVE_0 }, { KB_DEF_P1_B1, MSG_P1_B1, 0x080001, 0x10, BIT_ACTIVE_0 }, { KB_DEF_P1_B2, MSG_P1_B2, 0x080001, 0x20, BIT_ACTIVE_0 }, { KB_DEF_P2_START, MSG_P2_START, 0x080005, 0x02, BIT_ACTIVE_0 }, { KB_DEF_P2_UP, MSG_P2_UP, 0x080003, 0x01, BIT_ACTIVE_0 }, { KB_DEF_P2_DOWN, MSG_P2_DOWN, 0x080003, 0x02, BIT_ACTIVE_0 }, { KB_DEF_P2_LEFT, MSG_P2_LEFT, 0x080003, 0x04, BIT_ACTIVE_0 }, { KB_DEF_P2_RIGHT, MSG_P2_RIGHT, 0x080003, 0x08, BIT_ACTIVE_0 }, { KB_DEF_P2_B1, MSG_P2_B1, 0x080003, 0x10, BIT_ACTIVE_0 }, { KB_DEF_P2_B2, MSG_P2_B2, 0x080003, 0x20, BIT_ACTIVE_0 }, { 0, NULL, 0, 0, 0 },};/* Dipswitch 2 */static struct DSW_DATA dsw_data_GalPanic_0[] ={ { MSG_DIFFICULTY, 0x03, 0x04 }, { MSG_EASY, 0x02, 0x00 }, { MSG_NORMAL, 0x03, 0x00 }, { MSG_HARD, 0x01, 0x00 }, { MSG_HARDEST, 0x00, 0x00 }, { MSG_DSWA_BIT3, 0x04, 0x02 }, { MSG_OFF, 0x04, 0x00 }, { MSG_ON, 0x00, 0x00 }, { MSG_DSWA_BIT4, 0x08, 0x02 }, { MSG_OFF, 0x08, 0x00 }, { MSG_ON, 0x00, 0x00 }, { "Lives", 0x30, 0x04 }, { "2", 0x10, 0x00 }, { "3", 0x30, 0x00 }, { "4", 0x20, 0x00 }, { "5", 0x00, 0x00 }, { MSG_DSWA_BIT7, 0x40, 0x02 }, { MSG_OFF, 0x40, 0x00 }, { MSG_ON, 0x00, 0x00 }, { MSG_SERVICE, 0x80, 0x02 }, { MSG_OFF, 0x80, 0x00 }, { MSG_ON, 0x00, 0x00 }, { NULL, 0, 0, },};/* Dipswitch 1 */static struct DSW_DATA dsw_data_GalPanic_1[] ={ { MSG_DSWA_BIT1, 0x01, 0x02 }, { MSG_OFF, 0x01, 0x00 }, { MSG_ON, 0x00, 0x00 }, { MSG_DSWA_BIT2, 0x02, 0x02 }, { MSG_OFF, 0x02, 0x00 }, { MSG_ON, 0x00, 0x00 }, { MSG_DSWA_BIT3, 0x04, 0x02 }, { MSG_OFF, 0x04, 0x00 }, { MSG_ON, 0x00, 0x00 }, { MSG_DSWA_BIT4, 0x08, 0x02 }, { MSG_OFF, 0x08, 0x00 }, { MSG_ON, 0x00, 0x00 }, { "Coinage A", 0x30, 0x04 }, { MSG_1COIN_1PLAY, 0x30, 0x00 }, { MSG_2COIN_1PLAY, 0x20, 0x00 }, { MSG_3COIN_1PLAY, 0x10, 0x00 }, { MSG_4COIN_1PLAY, 0x00, 0x00 }, { "Coinage B", 0xC0, 0x04 }, { MSG_1COIN_2PLAY, 0xC0, 0x00 }, { MSG_1COIN_3PLAY, 0x80, 0x00 }, { MSG_1COIN_4PLAY, 0x40, 0x00 }, { MSG_1COIN_6PLAY, 0x00, 0x00 }, { NULL, 0, 0, },};static struct DSW_INFO GalPanic_dsw[] ={ { 0x080000, 0xF7, dsw_data_GalPanic_0 }, { 0x080002, 0xFF, dsw_data_GalPanic_1 }, { 0, 0, NULL, },};static struct VIDEO_INFO GalPanic_video ={ DrawGalPanic, 256, 224, 32, VIDEO_ROTATE_90 | VIDEO_ROTATABLE | VIDEO_NEEDS_16BPP,};static struct OKIM6295interface galpanic_m6295_interface ={ 1, /* 1 chip */ { 12000 }, /* 12000 KHz */ { 0 }, /* memory region (not yet !) */ { 100 } /* volume */};static struct SOUND_INFO GalPanic_sound[] ={ { SOUND_M6295, &galpanic_m6295_interface, }, { 0, NULL, },};static UINT8 *GFX_SOLID;static UINT8 *RAM_VIDEO_SPR;static UINT8 *RAM_VIDEO_BG;static UINT8 *RAM_VIDEO_FG;static UINT8 *RAM_VIDEO_PALETTE;static UINT8 *VIDEO_BG;static UINT8 *VIDEO_FG;static UINT8 *VIDEO_PAL;static UINT8 *VIDEO_ALPHA;static UINT8 *ADPCM;struct GAME_MAIN game_galpanic ={ GalPanic_dirs, GalPanic_roms, GalPanic_inputs, GalPanic_dsw, NULL, LoadGalPanic, ClearGalPanic, &GalPanic_video, ExecuteGalPanicFrame, "galpanic", "Gals Panic", "Gals Panic", COMPANY_ID_KANEKO, NULL, 1990, GalPanic_sound, GAME_ADULT,};void galpanic_Palette_Write( UINT32 address, UINT16 data ){ UINT16 r,g,b; UINT8 a; UINT32 offs; // Write to real game palette at address 0x600000. // This is just to fool the palette error check routine. // at the beginning of the game. offs = address-0x600000; RAM[0x40000+offs] = data>>8; RAM[0x40001+offs] = data&0xFF; // Read Transparency flag a = data & 0x0001; // decode color to 16bit "xRRRRRGGGGGBBBBB" format data >>= 1; r = (data >> 5) & 0x1F; g = (data >> 10) & 0x1F; b = (data >> 0) & 0x1F; data = ((r<<10) | (g<<5) | (b<<0)); // write palette entry RAM[0x82001+offs] = data>>8; RAM[0x82000+offs] = data&0xFF; // write alpha entry RAM[0x130000+((offs)>>1)] = a;}void galpanic_fg_write_b( UINT32 address, UINT8 data ){ UINT32 offs; // Write to real foreground data if((address&0x01)==1) offs = address-0x500001; else offs = address-0x4FFFFF; RAM[offs] = data; // // Draw foreground layer. // // The foreground layer use only the first 256 colors from // the main palette. // // We don't do much here other than to rotate the data 90 degrees. // if(offs<0x1E000){ // Rotate screen offs>>=1; offs = (((~offs)<<8)&0xFF00) | (0xFF - (offs>>8)); offs &= 0xFFFF; // Draw to foreground ram RAM[0x100000 + offs] = data; }}void galpanic_fg_write_w( UINT32 address, UINT16 data ){ UINT32 offs; // Write to real background data if((address&0x01)==1) offs = address-0x500001; else offs = address-0x500000; RAM[offs+1] = data>>8; RAM[offs] = data&0xFF; // // Draw foreground layer. // // See the function above for comments... // if(offs<0x1E000){ // rotate screen 90 degrees offs>>=1; offs = (((~offs)<<8)&0xFF00) | (0xFF-(offs>>8)); offs &= 0xFFFF; // write to foreground ram RAM[0x100000 + offs] = data&0xFF; RAM[0x100000 - 256 + offs] = data>>8; }}void galpanic_bg_write_b( UINT32 address, UINT8 data ){ UINT32 offs; // Write to real foreground data if((address&0x01)==1) offs = address-0x520001; else offs = address-0x51FFFF; RAM[0x20000+offs] = data; // // Draw background layer for 16bit video modes // (This function is probably not needed at all) // if( (offs<0x1A800) && (offs>0x17FF)){ // rotate screen 90 degrees offs>>=1; offs = (((~offs)<<8)&0xFF00) | (0xFF - (offs>>8)); offs &= 0xFFFF; // write to background ram RAM[0x110000 + offs] = data; }}void galpanic_bg_write_w( UINT32 address, UINT16 data ){ UINT32 offs; UINT16 r,g,b; // Write to real background data if((address&0x01)==1) offs = address-0x520001; else offs = address-0x520000; // // Draw background layer for 16bit video modes // // The game writes 16bit RGB data to this layer. // We only need to convert it to a better format for our PC's. // ( GGGGGRRRRRBBBBBx -> xRRRRRGGGGGBBBBB ) // RAM[0x20000+offs+1] = data>>8; RAM[0x20000+offs] = data&0xFF; if( (offs<0x1A800) && (offs>0x17FF)){ // decode color to 16bit "xRRRRRGGGGGBBBBB" format r = data & 0x07C0; g = data & 0xF800; b = data & 0x003E; data = ((r<<5) | (g>>5) | (b>>1)); // rotate screen 90 degrees offs>>=1; offs = (((~offs)<<8)&0xFF00) | (0xFF-(offs>>8)); offs &= 0xFFFF; // write to background ram RAM[0x110000 + offs] = data&0xFF; RAM[0x120000 + offs] = data>>8; }}void galpanic_bg_write_8_w( UINT32 address, UINT16 data ){ UINT32 offs; UINT16 r,g,b; // Write to real background ram (just to keep the game happy) if((address&0x01)==1) offs = address-0x520001; else offs = address-0x520000; RAM[0x20000+offs+1] = data>>8; RAM[0x20000+offs] = data&0xFF; // // Draw background layer for 8bit video modes // // The game feeds us 16bit RGB data, so we need to // make a closest colour search to find a suitable palette entry // instead. // We look for colours in the games dynamic palette of 1024 colors. // Colors 384 to 512 seem to stay static during the game so we can take // one of them. // // Needless to say this is *very* cpu intensive. Luckily the game doesn't // draw to the background layer very often // // Also, the background layer RAM is shared with the games Work-Ram so // we don't do any close-colour finding for all pixels in the background layer ram. // if( (offs<0x1A800) && (offs>0x17FF)){ // find R-G-B values r = ((data >> 6) & 0x1F); g = ((data >> 11) & 0x1F); b = ((data >> 1) & 0x1F); // find a suitable palette entry data = galpanic_closest_colour(r,g,b) - 256; // rotate screen 90 degrees offs>>=1; offs = (((~offs)<<8)&0xFF00) | (0xFF-(offs>>8)); offs &= 0xFFFF; // write to background layer RAM[0x110000 + offs] = data;// RAM[0x120000 + offs] = data>>8; }}void LoadGalPanic(void){ int ta,tb,t,tt; RAMSize = 0x140000; if(!(ROM=AllocateMem(0x400000))) return; if(!(RAM=AllocateMem(RAMSize))) return; if(!(GFX=AllocateMem(4*0x200000))) return; if(!(ADPCM=AllocateMem(2*0x140000))) return; RAM_VIDEO_FG = RAM + 0x000000; RAM_VIDEO_BG = RAM + 0x020000; RAM_VIDEO_PALETTE = RAM + 0x040000; RAM_VIDEO_SPR = RAM + 0x060000; VIDEO_PAL = RAM + 0x082000; VIDEO_FG = RAM + 0x100000; VIDEO_BG = RAM + 0x110000; VIDEO_ALPHA = RAM + 0x130000; /* 68000 ROMs */ if(!load_rom("pm110.4m2", RAM, 0x80000)) return; for(ta=0;ta<0x80000;ta++){ ROM[ta+ta]=RAM[ta]; } if(!load_rom("pm109.4m1", RAM, 0x80000)) return; for(ta=0;ta<0x80000;ta++){ ROM[ta+ta+1]=RAM[ta]; }/* The above two ROMs contain valid 68000 code, but the game doesn't *//* work. I think there might be a protection (addressed at e00000). *//* The two following ROMs replace the code with a working version. */ /* 68000 ROMs */ if(!load_rom("pm112.6", RAM, 0x20000)) return; for(ta=0;ta<0x20000;ta++){ ROM[ta+ta]=RAM[ta]; } if(!load_rom("pm111.5", RAM, 0x20000)) return; for(ta=0;ta<0x20000;ta++){ ROM[ta+ta+1]=RAM[ta]; } if(!load_rom("pm004e.8", RAM, 0x80000)) return; for(ta=0;ta<0x80000;ta++){ ROM[0x100000+ta+ta+1]=RAM[ta]; } if(!load_rom("pm005e.7", RAM, 0x80000)) return; for(ta=0;ta<0x80000;ta++){ ROM[0x100000+ta+ta]=RAM[ta]; } if(!load_rom("pm000e.15", RAM, 0x80000)) return; for(ta=0;ta<0x80000;ta++){ ROM[0x200000+ta+ta+1]=RAM[ta]; } if(!load_rom("pm001e.14", RAM, 0x80000)) return; for(ta=0;ta<0x80000;ta++){ ROM[0x200000+ta+ta]=RAM[ta]; } if(!load_rom("pm002e.17", RAM, 0x80000)) return; for(ta=0;ta<0x80000;ta++){ ROM[0x300000+ta+ta+1]=RAM[ta]; } if(!load_rom("pm003e.16", RAM, 0x80000)) return; for(ta=0;ta<0x80000;ta++){ ROM[0x300000+ta+ta]=RAM[ta]; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -