/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * * Rockbox port of InfoNES * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include "plugin.h" PLUGIN_HEADER #include "InfoNES.h" #include "InfoNES_System.h" #include "InfoNES_pAPU.h" #include "keymaps.h" int start_application(char *filename); void poll_event(void); int LoadSRAM(void); int SaveSRAM(void); void get_more(unsigned char **start, size_t *size); void save(void); void load(void); void menu(void); void sound_onoff(void); void video_menu(void); void set_display_mode(void); void set_frameskip(void); char szRomName[ 256 ]; char szSaveName[ 256 ]; int nSRAM_SaveFlag; extern struct ApuEvent_t *ApuEventQueue; bool quit = false; bool sound_on; BYTE final_wave[2048 * 2]; int waveptr; int wavflag; int wavdone; WORD *wfx; DWORD dwPad1; DWORD dwPad2; DWORD dwSystem; WORD NesPalette[ 64 ] = { LCD_RGBPACK(117, 117, 117) , LCD_RGBPACK(39, 27, 143) , LCD_RGBPACK(0, 0, 171) , LCD_RGBPACK(71, 0, 159) , LCD_RGBPACK(143, 0, 119) , LCD_RGBPACK(171, 0, 19) , LCD_RGBPACK(167, 0, 0) , LCD_RGBPACK(127, 11, 0) , LCD_RGBPACK(67, 47, 0) , LCD_RGBPACK(0, 71, 0) , LCD_RGBPACK(0, 81, 0) , LCD_RGBPACK(0, 63, 23) , LCD_RGBPACK(27, 63, 95) , LCD_RGBPACK(0, 0, 0) , LCD_RGBPACK(0, 0, 0) , LCD_RGBPACK(0, 0, 0) , LCD_RGBPACK(188, 188, 188) , LCD_RGBPACK(0, 115, 239) , LCD_RGBPACK(35, 59, 239) , LCD_RGBPACK(131, 0, 243) , LCD_RGBPACK(191, 0, 191) , LCD_RGBPACK(231, 0, 91) , LCD_RGBPACK(219, 43, 0) , LCD_RGBPACK(203, 79, 15) , LCD_RGBPACK(139, 115, 0) , LCD_RGBPACK(0, 151, 0) , LCD_RGBPACK(0, 171, 0) , LCD_RGBPACK(0, 147, 59) , LCD_RGBPACK(0, 131, 139) , LCD_RGBPACK(0, 0, 0) , LCD_RGBPACK(0, 0, 0) , LCD_RGBPACK(0, 0, 0) , LCD_RGBPACK(255, 255, 255) , LCD_RGBPACK(63, 191, 255) , LCD_RGBPACK(95, 151, 255) , LCD_RGBPACK(167, 139, 253) , LCD_RGBPACK(247, 123, 255) , LCD_RGBPACK(255, 119, 183) , LCD_RGBPACK(255, 119, 99) , LCD_RGBPACK(255, 155, 59) , LCD_RGBPACK(243, 191, 63) , LCD_RGBPACK(131, 211, 19) , LCD_RGBPACK(79, 223, 75) , LCD_RGBPACK(88, 248, 152) , LCD_RGBPACK(0, 235, 219) , LCD_RGBPACK(0, 0, 0) , LCD_RGBPACK(0, 0, 0) , LCD_RGBPACK(0, 0, 0) , LCD_RGBPACK(255, 255, 255) , LCD_RGBPACK(171, 231, 255) , LCD_RGBPACK(199, 215, 255) , LCD_RGBPACK(215, 203, 255) , LCD_RGBPACK(255, 199, 255) , LCD_RGBPACK(255, 199, 219) , LCD_RGBPACK(255, 191, 179) , LCD_RGBPACK(255, 219, 171) , LCD_RGBPACK(255, 231, 163) , LCD_RGBPACK(227, 255, 163) , LCD_RGBPACK(171, 243, 191) , LCD_RGBPACK(179, 255, 207) , LCD_RGBPACK(159, 255, 243) , LCD_RGBPACK(0, 0, 0) , LCD_RGBPACK(0, 0, 0) , LCD_RGBPACK(0, 0, 0) }; BYTE NesPaletteRGB[64][3] = { { 112, 112, 112, },{ 32, 24, 136, },{ 0, 0, 168, },{ 64, 0, 152,}, { 136, 0, 112, },{168, 0, 16, },{160, 0, 0, },{120, 8, 0,}, { 64, 40, 0, },{ 0, 64, 0, },{ 0, 80, 0, },{ 0, 56, 16,}, { 24, 56, 88, },{ 0, 0, 0, },{ 0, 0, 0, },{ 0, 0, 0,}, { 184, 184, 184, },{ 0, 112, 232, },{ 32, 56, 232, },{128, 0, 240,}, { 184, 0, 184, },{224, 0, 88, },{216, 40, 0, },{200, 72, 8,}, { 136, 112, 0, },{ 0, 144, 0, },{ 0, 168, 0, },{ 0, 144, 56,}, { 0, 128, 136, },{ 0, 0, 0, },{ 0, 0, 0, },{ 0, 0, 0,}, { 248, 248, 248, },{ 56, 184, 248, },{ 88, 144, 248, },{ 64, 136, 248,}, { 240, 120, 248, },{248, 112, 176, },{248, 112, 96, },{248, 152, 56,}, { 240, 184, 56, },{128, 208, 16, },{ 72, 216, 72, },{ 88, 248, 152,}, { 0, 232, 216, },{ 0, 0, 0, },{ 0, 0, 0, },{ 0, 0, 0,}, { 248, 248, 248, },{168, 224, 248, },{192, 208, 248, },{208, 200, 248,}, { 248, 192, 248, },{248, 192, 216, },{248, 184, 176, },{248, 216, 168,}, { 248, 224, 160, },{224, 248, 160, },{168, 240, 184, },{176, 248, 200,}, { 152, 248, 240, },{ 0, 0, 0, },{ 0, 0, 0, },{ 0, 0, 0 } }; /* main plugin entry point */ enum plugin_status plugin_start(const void* parameter) { size_t size = 0xffff; sound_on = false; #ifdef HAVE_ADJUSTABLE_CPU_FREQ rb->cpu_boost(true); #endif rb->backlight_on(); rb->lcd_clear_display(); VROM = (BYTE*)rb->plugin_get_audio_buffer(&size); ROM = (BYTE*) VROM + 0xffff * 8; wfx = (WORD*)(ROM + 0xffff * 16); ApuEventQueue = (struct ApuEvent_t*)(wfx + LCD_HEIGHT * NES_DISP_WIDTH); /* Start ROM file if specified */ if (parameter) { if (start_application((char*) parameter)) { /* MainLoop */ InfoNES_Main(); /* End */ SaveSRAM(); } else { rb->splash(HZ, "Not a valid NES ROM!!"); return PLUGIN_OK; } } else { rb->splash(HZ*3/2, "Play NES ROM file!"); return PLUGIN_OK; } return PLUGIN_OK; } /* Start application */ int start_application(char *filename) { rb->strcpy( szRomName, filename ); if(InfoNES_Load(szRomName)==0) { LoadSRAM(); return 1; } return 0; } /* Load SRAM */ int LoadSRAM(void) { int fp; unsigned char pSrcBuf[ SRAM_SIZE ]; unsigned char chData; unsigned char chTag; int nRunLen; int nDecoded; int nDecLen; int nIdx; nSRAM_SaveFlag = 0; if ( !ROM_SRAM ) return 0; nSRAM_SaveFlag = 1; rb->strcpy( szSaveName, szRomName ); rb->strcpy( rb->strrchr( szSaveName, '.' ) + 1, "srm" ); fp = rb->open( szSaveName, O_RDWR | O_CREAT); if ( !fp ) return -1; rb->read(fp, pSrcBuf, SRAM_SIZE); rb->close( fp ); nDecoded = 0; nDecLen = 0; chTag = pSrcBuf[ nDecoded++ ]; while ( nDecLen < 8192 ) { chData = pSrcBuf[ nDecoded++ ]; if ( chData == chTag ) { chData = pSrcBuf[ nDecoded++ ]; nRunLen = pSrcBuf[ nDecoded++ ]; for ( nIdx = 0; nIdx < nRunLen + 1; ++nIdx ) { SRAM[ nDecLen++ ] = chData; } } else { SRAM[ nDecLen++ ] = chData; } } return 0; } int SaveSRAM(void) { int fp; int nUsedTable[ 256 ]; unsigned char chData; unsigned char chPrevData; unsigned char chTag; int nIdx; int nEncoded; int nEncLen; int nRunLen; unsigned char pDstBuf[ SRAM_SIZE ]; if ( !nSRAM_SaveFlag ) return 0; rb->memset( nUsedTable, 0, sizeof nUsedTable ); for ( nIdx = 0; nIdx < SRAM_SIZE; ++nIdx ) { ++nUsedTable[ SRAM[ nIdx++ ] ]; } for ( nIdx = 1, chTag = 0; nIdx < 256; ++nIdx ) { if ( nUsedTable[ nIdx ] < nUsedTable[ chTag ] ) chTag = nIdx; } nEncoded = 0; nEncLen = 0; nRunLen = 1; pDstBuf[ nEncLen++ ] = chTag; chPrevData = SRAM[ nEncoded++ ]; while ( nEncoded < SRAM_SIZE && nEncLen < SRAM_SIZE - 133 ) { chData = SRAM[ nEncoded++ ]; if ( chPrevData == chData && nRunLen < 256 ) ++nRunLen; else { if ( nRunLen >= 4 || chPrevData == chTag ) { pDstBuf[ nEncLen++ ] = chTag; pDstBuf[ nEncLen++ ] = chPrevData; pDstBuf[ nEncLen++ ] = nRunLen - 1; } else { for ( nIdx = 0; nIdx < nRunLen; ++nIdx ) pDstBuf[ nEncLen++ ] = chPrevData; } chPrevData = chData; nRunLen = 1; } } if ( nRunLen >= 4 || chPrevData == chTag ) { pDstBuf[ nEncLen++ ] = chTag; pDstBuf[ nEncLen++ ] = chPrevData; pDstBuf[ nEncLen++ ] = nRunLen - 1; } else { for ( nIdx = 0; nIdx < nRunLen; ++nIdx ) pDstBuf[ nEncLen++ ] = chPrevData; } fp = rb->open( szSaveName, O_CREAT | O_TRUNC | O_WRONLY ); if ( !fp ) return -1; rb->write(fp, pDstBuf, nEncLen); rb->close( fp ); return 0; } /* Menu Screen */ int InfoNES_Menu(void){ if(quit) return -1; return 0; } /* Read ROM image file */ int InfoNES_ReadRom( const char *pszFileName ){ int fp; fp=rb->open(pszFileName, O_RDONLY); if(!fp) return -1; rb->read( fp, &NesHeader, sizeof NesHeader); if( rb->memcmp( NesHeader.byID, "NES\x1a", 4 )!=0){ rb->close( fp ); return -1; } rb->memset( SRAM, 0, SRAM_SIZE ); if(NesHeader.byInfo1 & 4){ rb->read(fp, &SRAM[ 0x1000 ], 512); } rb->read(fp, ROM, 0x4000 * NesHeader.byRomSize); if(NesHeader.byVRomSize>0){ rb->read(fp, VROM, 0x2000 * NesHeader.byVRomSize); } rb->close( fp ); return 0; } /* Release memory for ROM */ void InfoNES_ReleaseRom(void){ return; } /* Screen scale, shrink, and resolution change defines */ int DisplaySize = 0; #define scale 0 #define center 1 #define half 2 /* Transfer work frame contents to screen */ void InfoNES_LoadFrame(void){ int x, y; switch ( DisplaySize ) { case scale: /* Scaled to fit display */ for(y = 0; y < LCD_HEIGHT; y++) { for(x = 0; x < LCD_WIDTH; x++) { rb->lcd_framebuffer[y * LCD_WIDTH + x] = WorkFrame[x * NES_DISP_WIDTH / LCD_WIDTH + y * NES_DISP_HEIGHT / LCD_HEIGHT * NES_DISP_WIDTH]; }} break; case center: /* Actual NES screen resolution */ for(y = 0; y < NES_DISP_HEIGHT; y++) { for(x = 0; x < NES_DISP_WIDTH; x++) { rb->lcd_set_foreground(WorkFrame[x + y * NES_DISP_WIDTH]); rb->lcd_drawpixel(x, y); }} break; case half: /* Half NES screen resolution */ for(y = 0; y < NES_DISP_HEIGHT; y += 2) { for(x = 0; x < NES_DISP_WIDTH; x += 2) { rb->lcd_set_foreground(WorkFrame[x + y * NES_DISP_WIDTH]); rb->lcd_drawpixel(x/2, y/2); }} break; } rb->lcd_update(); } #ifndef CPUFREQ_MAX #define CPUFREQ_MAX 80000000l #endif /* Get a joypad state */ void InfoNES_PadState( DWORD *pdwPad1, DWORD *pdwPad2, DWORD *pdwSystem ) { poll_event(); *pdwPad1 = dwPad1; *pdwPad2 = dwPad2; *pdwSystem = dwSystem; } static const int joy_commit_range = 3276; #ifdef E200_SCROLLWHEEL /* Scrollwheel events are posted directly and not polled by the button driver - synthesize polling */ static inline unsigned int read_scroll_wheel(void) { unsigned int buttons = BUTTON_NONE; unsigned int btn; /* Empty out the button queue and see if any scrollwheel events were posted */ do { btn = rb->button_get_w_tmo(0); buttons |= btn; } while (btn != BUTTON_NONE); return buttons & (SCROLL_CC | SCROLL_CW); } #endif void poll_event(void) { int bs; bs = rb->button_status(); #ifdef E200_SCROLLWHEEL bs |= read_scroll_wheel(); #endif if(bs & NES_BUTTON_UP) dwPad1 |= 1 << 4; else dwPad1 &= ~(1 << 4); if(bs & NES_BUTTON_DOWN) dwPad1 |= 1 << 5; else dwPad1 &= ~(1 << 5); if(bs & NES_BUTTON_LEFT) dwPad1 |= 1 << 6; else dwPad1 &= ~(1 << 6); if(bs & NES_BUTTON_RIGHT) dwPad1 |= 1 << 7; else dwPad1 &= ~(1 << 7); if(bs & NES_BUTTON_A) dwPad1 |= 1 << 0; else dwPad1 &= ~(1 << 0); if(bs & NES_BUTTON_B) dwPad1 |= 1 << 1; else dwPad1 &= ~(1 << 1); if(bs & NES_BUTTON_SELECT) dwPad1 |= 1 << 2; else dwPad1 &= ~(1 << 2); if(bs & NES_BUTTON_START) dwPad1 |= 1 << 3; else dwPad1 &= ~(1 << 3); rb->yield(); if(bs & NES_BUTTON_MENU) menu(); return; } /* memcpy */ void *InfoNES_MemoryCopy( void *dest, const void *src, int count ){ rb->memcpy( dest, src, count ); return dest; } /* memset */ void *InfoNES_MemorySet( void *dest, int c, int count ) { rb->memset( dest, c, count); return dest; } /* Print debug message */ void InfoNES_DebugPrint( char *pszMsg ) { rb->splashf(HZ*3/2, "%s\n", pszMsg); } /* Wait */ void InfoNES_Wait(void) { } /* Sound Initialize */ void InfoNES_SoundInit( void ) { } void waveout(void *udat,BYTE *stream,int len) { (void)stream; (void)udat; if(!wavdone) { rb->pcm_play_data(NULL, &final_wave[(wavflag -1) << 10], len); wavflag = 0; wavdone= 1; } } void get_more(unsigned char **start, size_t *size) { static unsigned char buf[4048]; int i; if ( wavflag ) { for(i = 0; i < 4048; i++) buf[i] = (&final_wave[(wavflag - 1) << 10])[i/4]; *start = buf; *size = 4048; wavdone = 1; } return; } /* Sound Open */ int InfoNES_SoundOpen( int samples_per_sync, int sample_rate ) { (void)samples_per_sync; rb->pcm_set_frequency(11025); sample_rate=11025; return 1; } /* Sound Close */ void InfoNES_SoundClose( void ) { } void InfoNES_SoundOutput( int samples, BYTE *wave1, BYTE *wave2, BYTE *wave3, BYTE *wave4, BYTE *wave5 ) { int i; { for (i = 0; i < samples; i++) { #if 1 final_wave[ waveptr ] = ( wave1[i] + wave2[i] + wave3[i] + wave4[i] + wave5[i] ) / 5; #else final_wave[ waveptr ] = wave4[i]; #endif waveptr++; if ( waveptr == 2048 ) { waveptr = 0; wavflag = 2; } else if ( waveptr == 1024 ) { wavflag = 1; } } if ( wavflag ) { if(sound_on) { rb->pcm_play_data(&get_more, NULL, 0); rb->yield(); } wavflag = 0; } } } /* Print system message */ void InfoNES_MessageBox(char *pszMsg, ...) { (void)pszMsg; } void menu(void) { MENUITEM_STRINGLIST(menu, "Menu", NULL, "Load", "Save", "Video", "Sound", "Quit"); switch (rb->do_menu(&menu, NULL, NULL, false)) { case 0: load(); break; case 1: save(); break; case 2: video_menu(); break; case 3: sound_onoff(); break; case 4: dwSystem|=PAD_SYS_QUIT; quit=1; break; default: break; } return; } void sound_onoff(void) { MENUITEM_STRINGLIST(smenu, "Sound", NULL, "On", "Off"); switch(rb->do_menu(&smenu, NULL, NULL, false)) { case 0: sound_on = true; return; case 1: sound_on = false; return; default: return; } } void video_menu(void) { MENUITEM_STRINGLIST(smenu, "Video", NULL, "Display Size", "Frameskip"); switch(rb->do_menu(&smenu, NULL, NULL, false)) { case 0: set_display_mode(); break; case 1: set_frameskip(); break; default: break; } } void set_display_mode(void) { MENUITEM_STRINGLIST(smenu, "Display Size", NULL, "Stretch", "Centered", "Half Size"); switch(rb->do_menu(&smenu, NULL, NULL, false)) { case 0: DisplaySize = scale; return; case 1: DisplaySize = center; return; case 2: DisplaySize = half; return; default: return; } } void set_frameskip(void) { MENUITEM_STRINGLIST(smenu, "Frameskip", NULL, "0", "1", "2", "3", "4", "5"); switch(rb->do_menu(&smenu, NULL, NULL, false)) { case 0: FrameSkip = 0; return; case 1: FrameSkip = 1; return; case 2: FrameSkip = 2; return; case 3: FrameSkip = 3; return; case 4: FrameSkip = 4; return; case 5: FrameSkip = 5; return; default: return; } } #include "InfoNES.h" #include "InfoNES_Mapper.h" extern WORD PC; extern BYTE SP; extern BYTE F; extern BYTE A; extern BYTE X; extern BYTE Y; extern BYTE RAM[ RAM_SIZE ]; extern BYTE SRAM[ SRAM_SIZE ]; extern BYTE PPURAM[ PPURAM_SIZE ]; extern BYTE SPRRAM[ SPRRAM_SIZE ]; extern BYTE ChrBuf[ 256 * 2 * 8 * 8 ]; extern BYTE *ROMBANK0; extern BYTE *ROMBANK1; extern BYTE *ROMBANK2; extern BYTE *ROMBANK3; extern BYTE IRQ_State; extern BYTE IRQ_Wiring; extern BYTE NMI_State; extern BYTE NMI_Wiring; extern WORD g_wPassedClocks; extern BYTE g_byTestTable[ 256 ]; extern int SpriteJustHit; extern struct value_table_tag g_ASLTable[ 256 ]; extern struct value_table_tag g_LSRTable[ 256 ]; extern struct value_table_tag g_ROLTable[ 2 ][ 256 ]; extern struct value_table_tag g_RORTable[ 2 ][ 256 ]; extern DWORD Map1_bank1; extern DWORD Map1_bank2; extern DWORD Map1_bank3; extern DWORD Map1_bank4; extern BYTE Map1_Regs[ 4 ]; extern DWORD Map1_Cnt; extern BYTE Map1_Latch; extern WORD Map1_Last_Write_Addr; extern DWORD Map1_HI1; extern DWORD Map1_HI2; extern enum Map1_Size_t Map1_Size; extern DWORD Map1_256K_base; extern DWORD Map1_swap; extern BYTE *SRAMBANK; extern BYTE PPU_R0; extern BYTE PPU_R1; extern BYTE PPU_R2; extern BYTE PPU_R3; extern BYTE PPU_R7; extern BYTE Map4_Regs[ 8 ]; extern DWORD Map4_Rom_Bank; extern DWORD Map4_Prg0, Map4_Prg1; extern DWORD Map4_Chr01, Map4_Chr23; extern DWORD Map4_Chr4, Map4_Chr5, Map4_Chr6, Map4_Chr7; extern BYTE Map4_IRQ_Enable; extern BYTE Map4_IRQ_Cnt; extern BYTE Map4_IRQ_Latch; extern BYTE Map4_IRQ_Request; extern BYTE Map4_IRQ_Present; extern BYTE Map4_IRQ_Present_Vbl; void save(void) { int fd; char fname[256]; rb->strcpy(fname, szRomName); rb->strcpy( rb->strrchr( fname, '.' ) + 1, "sav" ); fd = rb->open(fname, O_WRONLY | O_CREAT | O_TRUNC); rb->write(fd, &PC, 2); rb->write(fd, &SP, 1); rb->write(fd, &F, 1); rb->write(fd, &A, 1); rb->write(fd, &X, 1); rb->write(fd, &Y, 1); rb->write(fd, RAM, RAM_SIZE); rb->write(fd, SRAM, SRAM_SIZE); rb->write(fd, PPURAM, PPURAM_SIZE); rb->write(fd, SPRRAM, SPRRAM_SIZE); rb->write(fd, *PPUBANK, 16 * sizeof(*PPUBANK)); rb->write(fd, ChrBuf, 256 * 2 * 8 * 8 ); rb->write(fd, &ROMBANK0, 4); rb->write(fd, &ROMBANK1, 4); rb->write(fd, &ROMBANK2, 4); rb->write(fd, &ROMBANK3, 4); rb->write(fd, &IRQ_Wiring, 1); rb->write(fd, &NMI_Wiring, 1); rb->write(fd, &g_wPassedClocks, 2); rb->write(fd, g_byTestTable, 256); rb->write(fd, g_ASLTable, 256 * 2); rb->write(fd, g_LSRTable, 256 * 2); rb->write(fd, g_ROLTable, 256 * 2 * 2); rb->write(fd, g_RORTable, 256 * 2 * 2); rb->write(fd, &PPU_R1, 1); rb->write(fd, &PPU_R2, 1); rb->write(fd, &PPU_R3, 1); rb->write(fd, &PPU_R7, 1); rb->write(fd, &PPU_Addr, 2); rb->write(fd, &PPU_Temp, 2); rb->write(fd, &PPU_Increment, 2); rb->write(fd, PalTable, 32 * 2); rb->write(fd, &PPU_Scr_V, 1); rb->write(fd, &PPU_Scr_V_Next, 1); rb->write(fd, &PPU_Scr_V_Byte, 1); rb->write(fd, &PPU_Scr_V_Byte_Next, 1); rb->write(fd, &PPU_Scr_V_Bit, 1); rb->write(fd, &PPU_Scr_V_Bit_Next, 1); rb->write(fd, &PPU_Scr_H, 1); rb->write(fd, &PPU_Scr_H_Next, 1); rb->write(fd, &PPU_Scr_H_Byte, 1); rb->write(fd, &PPU_Scr_H_Byte_Next, 1); rb->write(fd, &PPU_Scr_H_Bit, 1); rb->write(fd, &PPU_Scr_H_Bit_Next, 1); rb->write(fd, PPU_ScanTable, 263); rb->write(fd, &PPU_NameTableBank, 1); rb->write(fd, &PPU_Latch_Flag, 1); rb->write(fd, &IRQ_State, 1); rb->write(fd, &IRQ_Wiring, 1); rb->write(fd, &NMI_State, 1); rb->write(fd, &NMI_Wiring, 1); rb->write(fd, APU_Reg, 0x18); rb->write(fd, &ChrBufUpdate, 1); rb->write(fd, &PPU_UpDown_Clip, 1); rb->write(fd, &FrameIRQ_Enable, 1); rb->write(fd, &FrameStep, 2); rb->write(fd, &byVramWriteEnable, 1); rb->write(fd, &SpriteJustHit, 4); rb->write(fd, &FrameCnt, 2); if(MapperNo == 1) { rb->write(fd, &Map1_bank1, 4); rb->write(fd, &Map1_bank2, 4); rb->write(fd, &Map1_bank3, 4); rb->write(fd, &Map1_bank4, 4); rb->write(fd, Map1_Regs, 4); rb->write(fd, &Map1_Cnt, 4); rb->write(fd, &Map1_Latch, 1); rb->write(fd, &Map1_Last_Write_Addr, 2); rb->write(fd, &Map1_HI1, 4); rb->write(fd, &Map1_HI2, 4); rb->write(fd, &Map1_256K_base, 4); rb->write(fd, &Map1_swap, 4); } if(MapperNo == 4) { rb->write(fd, Map4_Regs, 8); rb->write(fd, &Map4_Rom_Bank, 4); rb->write(fd, &Map4_Prg0, 4); rb->write(fd, &Map4_Prg1, 4); rb->write(fd, &Map4_Chr01, 4); rb->write(fd, &Map4_Chr23, 4); rb->write(fd, &Map4_Chr4, 4); rb->write(fd, &Map4_Chr5, 4); rb->write(fd, &Map4_Chr6, 4); rb->write(fd, &Map4_Chr7, 4); rb->write(fd, &Map4_IRQ_Enable, 1); rb->write(fd, &Map4_IRQ_Cnt, 1); rb->write(fd, &Map4_IRQ_Latch, 1); rb->write(fd, &Map4_IRQ_Request, 1); rb->write(fd, &Map4_IRQ_Present, 1); rb->write(fd, &Map4_IRQ_Present_Vbl, 1); } rb->close(fd); return; } void load(void) { int fd; char fname[256]; rb->strcpy(fname, szRomName); rb->strcpy( rb->strrchr( fname, '.' ) + 1, "sav" ); fd = rb->open(fname, O_RDONLY); if(!fd) return; rb->read(fd, &PC, 2); rb->read(fd, &SP, 1); rb->read(fd, &F, 1); rb->read(fd, &A, 1); rb->read(fd, &X, 1); rb->read(fd, &Y, 1); rb->read(fd, RAM, RAM_SIZE); rb->read(fd, SRAM, SRAM_SIZE); rb->read(fd, PPURAM, PPURAM_SIZE); rb->read(fd, SPRRAM, SPRRAM_SIZE); rb->read(fd, *PPUBANK, 16 * sizeof(*PPUBANK)); rb->read(fd, ChrBuf, 256 * 2 * 8 * 8 ); rb->read(fd, &ROMBANK0, 4); rb->read(fd, &ROMBANK1, 4); rb->read(fd, &ROMBANK2, 4); rb->read(fd, &ROMBANK3, 4); rb->read(fd, &IRQ_Wiring, 1); rb->read(fd, &NMI_Wiring, 1); rb->read(fd, &g_wPassedClocks, 2); rb->read(fd, g_byTestTable, 256); rb->read(fd, g_ASLTable, 256 * 2); rb->read(fd, g_LSRTable, 256 * 2); rb->read(fd, g_ROLTable, 256 * 2 * 2); rb->read(fd, g_RORTable, 256 * 2 * 2); rb->read(fd, &PPU_R1, 1); rb->read(fd, &PPU_R2, 1); rb->read(fd, &PPU_R3, 1); rb->read(fd, &PPU_R7, 1); rb->read(fd, &PPU_Addr, 2); rb->read(fd, &PPU_Temp, 2); rb->read(fd, &PPU_Increment, 2); rb->read(fd, PalTable, 32 * 2); rb->read(fd, &PPU_Scr_V, 1); rb->read(fd, &PPU_Scr_V_Next, 1); rb->read(fd, &PPU_Scr_V_Byte, 1); rb->read(fd, &PPU_Scr_V_Byte_Next, 1); rb->read(fd, &PPU_Scr_V_Bit, 1); rb->read(fd, &PPU_Scr_V_Bit_Next, 1); rb->read(fd, &PPU_Scr_H, 1); rb->read(fd, &PPU_Scr_H_Next, 1); rb->read(fd, &PPU_Scr_H_Byte, 1); rb->read(fd, &PPU_Scr_H_Byte_Next, 1); rb->read(fd, &PPU_Scr_H_Bit, 1); rb->read(fd, &PPU_Scr_H_Bit_Next, 1); rb->read(fd, PPU_ScanTable, 263); rb->read(fd, &PPU_NameTableBank, 1); rb->read(fd, &PPU_Latch_Flag, 1); rb->read(fd, &IRQ_State, 1); rb->read(fd, &IRQ_Wiring, 1); rb->read(fd, &NMI_State, 1); rb->read(fd, &NMI_Wiring, 1); rb->read(fd, APU_Reg, 0x18); rb->read(fd, &ChrBufUpdate, 1); rb->read(fd, &PPU_UpDown_Clip, 1); rb->read(fd, &FrameIRQ_Enable, 1); rb->read(fd, &FrameStep, 2); rb->read(fd, &byVramWriteEnable, 1); rb->read(fd, &SpriteJustHit, 4); rb->read(fd, &FrameCnt, 2); if(MapperNo == 1) { rb->read(fd, &Map1_bank1, 4); rb->read(fd, &Map1_bank2, 4); rb->read(fd, &Map1_bank3, 4); rb->read(fd, &Map1_bank4, 4); rb->read(fd, Map1_Regs, 4); rb->read(fd, &Map1_Cnt, 4); rb->read(fd, &Map1_Latch, 1); rb->read(fd, &Map1_Last_Write_Addr, 2); rb->read(fd, &Map1_HI1, 4); rb->read(fd, &Map1_HI2, 4); rb->read(fd, &Map1_256K_base, 4); rb->read(fd, &Map1_swap, 4); } if(MapperNo == 4) { rb->read(fd, Map4_Regs, 8); rb->read(fd, &Map4_Rom_Bank, 4); rb->read(fd, &Map4_Prg0, 4); rb->read(fd, &Map4_Prg1, 4); rb->read(fd, &Map4_Chr01, 4); rb->read(fd, &Map4_Chr23, 4); rb->read(fd, &Map4_Chr4, 4); rb->read(fd, &Map4_Chr5, 4); rb->read(fd, &Map4_Chr6, 4); rb->read(fd, &Map4_Chr7, 4); rb->read(fd, &Map4_IRQ_Enable, 1); rb->read(fd, &Map4_IRQ_Cnt, 1); rb->read(fd, &Map4_IRQ_Latch, 1); rb->read(fd, &Map4_IRQ_Request, 1); rb->read(fd, &Map4_IRQ_Present, 1); rb->read(fd, &Map4_IRQ_Present_Vbl, 1); } rb->close(fd); return; } /* * InfoNES * h10 ports by 03/04/19 * Modified by Jay 06/02/25 * * Start Date: 2003.04.19 */ #include "plugin.h" PLUGIN_HEADER struct plugin_api *rb; #define stime 1500 #include "InfoNES.h" #include "InfoNES_System.h" /* #include "InfoNES_pAPU.h" */ /*-------------------------------------------------------------------*/ /* ROM image file information */ /*-------------------------------------------------------------------*/ char szRomName[ 256 ]; char szSaveName[ 256 ]; int nSRAM_SaveFlag; /*-------------------------------------------------------------------*/ /* Constants ( Linux specific ) */ /*-------------------------------------------------------------------*/ #define VBOX_SIZE 7 //static const char * VERSION = "InfoNES v0.97J RC1"; //why doesnt this line compile? /*-------------------------------------------------------------------*/ /* Global Variables ( SDL specific ) */ /*-------------------------------------------------------------------*/ extern struct ApuEvent_t *ApuEventQueue; bool quit = false; /* for video */ #define SDL_Surface int SDL_Surface *screen; WORD *wfx; /* For Sound Emulation */ /* SDL_AudioSpec audio_spec; BYTE final_wave[2048]; int waveptr; int wavflag; int wavdone; */ /* Pad state */ DWORD dwPad1; DWORD dwPad2; DWORD dwSystem; int start_menu; /*-------------------------------------------------------------------*/ /* Function prototypes ( SDL specific ) */ /*-------------------------------------------------------------------*/ int start_application(char *filename); void poll_event(void); int LoadSRAM(); int SaveSRAM(); void menu(void); /* Palette data */ #if 1 unsigned int COLOR_SPACE [] [3] = {{0x75,0x75,0x75}, {0x27, 0x1b, 0x8f}, {0x00, 0x00, 0xab}, {0x47, 0x00, 0x9f}, {0x8f, 0x00, 0x77}, {0xab, 0x00, 0x13}, {0xa7, 0x00, 0x00}, {0x7f, 0x0b, 0x00}, {0x43, 0x2f, 0x00}, {0x00, 0x47, 0x00}, {0x00, 0x51, 0x00}, {0x00, 0x3f, 0x17}, {0x1b, 0x3f, 0x5f}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0xbc, 0xbc, 0xbc}, {0x00, 0x73, 0xef}, {0x23, 0x3b, 0xef}, {0x83, 0x00, 0xf3}, {0xbf, 0x00, 0xbf}, {0xe7, 0x00, 0x5b}, {0xdb, 0x2b, 0x00}, {0xcb, 0x4f, 0x0f}, {0x8b, 0x73, 0x00}, {0x00, 0x97, 0x00}, {0x00, 0xab, 0x00}, {0x00, 0x93, 0x3b}, {0x00, 0x83, 0x8b}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0xff, 0xff, 0xff}, {0x3f, 0xbf, 0xff}, {0x5f, 0x97, 0xff}, {0xa7, 0x8b, 0xfd}, {0xf7, 0x7b, 0xff}, {0xff, 0x77, 0xb7}, {0xff, 0x77, 0x63}, {0xff, 0x9b, 0x3b}, {0xf3, 0xbf, 0x3f}, {0x83, 0xd3, 0x13}, {0x4f, 0xdf, 0x4b}, {0x58, 0xf8, 0x98}, {0x00, 0xeb, 0xdb}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0xff, 0xff, 0xff}, {0xab, 0xe7, 0xff}, {0xc7, 0xd7, 0xff}, {0xd7, 0xcb, 0xff}, {0xff, 0xc7, 0xff}, {0xff, 0xc7, 0xdb}, {0xff, 0xbf, 0xb3}, {0xff, 0xdb, 0xab}, {0xff, 0xe7, 0xa3}, {0xe3, 0xff, 0xa3}, {0xab, 0xf3, 0xbf}, {0xb3, 0xff, 0xcf}, {0x9f, 0xff, 0xf3}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}}; #endif #if 1 WORD NesPalette[ 64 ] = { (0xe << 11) + (0xe << 6) + (0xe << 0) , (0x4 << 11) + (0x3 << 6) + (0x11 << 0) , (0x0 << 11) + (0x0 << 6) + (0x15 << 0) , (0x8 << 11) + (0x0 << 6) + (0x13 << 0) , (0x11 << 11) + (0x0 << 6) + (0xe << 0) , (0x15 << 11) + (0x0 << 6) + (0x2 << 0) , (0x14 << 11) + (0x0 << 6) + (0x0 << 0) , (0xf << 11) + (0x1 << 6) + (0x0 << 0) , (0x8 << 11) + (0x5 << 6) + (0x0 << 0) , (0x0 << 11) + (0x8 << 6) + (0x0 << 0) , (0x0 << 11) + (0xa << 6) + (0x0 << 0) , (0x0 << 11) + (0x7 << 6) + (0x2 << 0) , (0x3 << 11) + (0x7 << 6) + (0xb << 0) , (0x0 << 11) + (0x0 << 6) + (0x0 << 0) , (0x0 << 11) + (0x0 << 6) + (0x0 << 0) , (0x0 << 11) + (0x0 << 6) + (0x0 << 0) , (0x17 << 11) + (0x17 << 6) + (0x17 << 0) , (0x0 << 11) + (0xe << 6) + (0x1d << 0) , (0x4 << 11) + (0x7 << 6) + (0x1d << 0) , (0x10 << 11) + (0x0 << 6) + (0x1e << 0) , (0x17 << 11) + (0x0 << 6) + (0x17 << 0) , (0x1c << 11) + (0x0 << 6) + (0xb << 0) , (0x1b << 11) + (0x5 << 6) + (0x0 << 0) , (0x19 << 11) + (0x9 << 6) + (0x1 << 0) , (0x11 << 11) + (0xe << 6) + (0x0 << 0) , (0x0 << 11) + (0x12 << 6) + (0x0 << 0) , (0x0 << 11) + (0x15 << 6) + (0x0 << 0) , (0x0 << 11) + (0x12 << 6) + (0x7 << 0) , (0x0 << 11) + (0x10 << 6) + (0x11 << 0) , (0x0 << 11) + (0x0 << 6) + (0x0 << 0) , (0x0 << 11) + (0x0 << 6) + (0x0 << 0) , (0x0 << 11) + (0x0 << 6) + (0x0 << 0) , (0x1f << 11) + (0x1f << 6) + (0x1f << 0) , (0x7 << 11) + (0x17 << 6) + (0x1f << 0) , (0xb << 11) + (0x12 << 6) + (0x1f << 0) , (0x14 << 11) + (0x11 << 6) + (0x1f << 0) , (0x1e << 11) + (0xf << 6) + (0x1f << 0) , (0x1f << 11) + (0xe << 6) + (0x16 << 0) , (0x1f << 11) + (0xe << 6) + (0xc << 0) , (0x1f << 11) + (0x13 << 6) + (0x7 << 0) , (0x1e << 11) + (0x17 << 6) + (0x7 << 0) , (0x10 << 11) + (0x1a << 6) + (0x2 << 0) , (0x9 << 11) + (0x1b << 6) + (0x9 << 0) , (0xb << 11) + (0x1f << 6) + (0x13 << 0) , (0x0 << 11) + (0x1d << 6) + (0x1b << 0) , (0x0 << 11) + (0x0 << 6) + (0x0 << 0) , (0x0 << 11) + (0x0 << 6) + (0x0 << 0) , (0x0 << 11) + (0x0 << 6) + (0x0 << 0) , (0x1f << 11) + (0x1f << 6) + (0x1f << 0) , (0x15 << 11) + (0x1c << 6) + (0x1f << 0) , (0x18 << 11) + (0x1a << 6) + (0x1f << 0) , (0x1a << 11) + (0x19 << 6) + (0x1f << 0) , (0x1f << 11) + (0x18 << 6) + (0x1f << 0) , (0x1f << 11) + (0x18 << 6) + (0x1b << 0) , (0x1f << 11) + (0x17 << 6) + (0x16 << 0) , (0x1f << 11) + (0x1b << 6) + (0x15 << 0) , (0x1f << 11) + (0x1c << 6) + (0x14 << 0) , (0x1c << 11) + (0x1f << 6) + (0x14 << 0) , (0x15 << 11) + (0x1e << 6) + (0x17 << 0) , (0x16 << 11) + (0x1f << 6) + (0x19 << 0) , (0x13 << 11) + (0x1f << 6) + (0x1e << 0) , (0x0 << 11) + (0x0 << 6) + (0x0 << 0) , (0x0 << 11) + (0x0 << 6) + (0x0 << 0) , (0x0 << 11) + (0x0 << 6) + (0x0 << 0) }; /*WORD NesPalette[ 64 ] = { 0x39ce, 0x1071, 0x0015, 0x2013, 0x440e, 0x5402, 0x5000, 0x3c20, 0x20a0, 0x0100, 0x0140, 0x00e2, 0x0ceb, 0x0000, 0x0000, 0x0000, 0x5ef7, 0x01dd, 0x10fd, 0x401e, 0x5c17, 0x700b, 0x6ca0, 0x6521, 0x45c0, 0x0240, 0x02a0, 0x0247, 0x0211, 0x0000, 0x0000, 0x0000, 0x7fff, 0x1eff, 0x2e5f, 0x223f, 0x79ff, 0x7dd6, 0x7dcc, 0x7e67, 0x7ae7, 0x4342, 0x2769, 0x2ff3, 0x03bb, 0x0000, 0x0000, 0x0000, 0x7fff, 0x579f, 0x635f, 0x6b3f, 0x7f1f, 0x7f1b, 0x7ef6, 0x7f75, 0x7f94, 0x73f4, 0x57d7, 0x5bf9, 0x4ffe, 0x0000, 0x0000, 0x0000 };*/ #else WORD NesPalette[ 64 ]; #endif BYTE NesPaletteRGB[64][3] = { 112, 112, 112, 32, 24, 136, 0, 0, 168, 64, 0, 152, 136, 0, 112, 168, 0, 16, 160, 0, 0, 120, 8, 0, 64, 40, 0, 0, 64, 0, 0, 80, 0, 0, 56, 16, 24, 56, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 184, 184, 184, 0, 112, 232, 32, 56, 232, 128, 0, 240, 184, 0, 184, 224, 0, 88, 216, 40, 0, 200, 72, 8, 136, 112, 0, 0, 144, 0, 0, 168, 0, 0, 144, 56, 0, 128, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 248, 248, 56, 184, 248, 88, 144, 248, 64, 136, 248, 240, 120, 248, 248, 112, 176, 248, 112, 96, 248, 152, 56, 240, 184, 56, 128, 208, 16, 72, 216, 72, 88, 248, 152, 0, 232, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 248, 248, 168, 224, 248, 192, 208, 248, 208, 200, 248, 248, 192, 248, 248, 192, 216, 248, 184, 176, 248, 216, 168, 248, 224, 160, 224, 248, 160, 168, 240, 184, 176, 248, 200, 152, 248, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; /*===================================================================*/ /* */ /* plugin_start() : Application main */ /* */ /*===================================================================*/ /* Application main */ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) { char *argv[2]; int argc; size_t size = 0xffff; unsigned int i,vmode; rb = api; start_menu = 0; rb->cpu_boost(true); //ROM = 0x28000000; //ApuEventQueue = rb->plugin_get_audio_buffer(&size); VROM = (BYTE*)rb->plugin_get_audio_buffer(&size); ROM = (BYTE*) VROM + 0xffff * 8; wfx = ROM + 0xffff * 16; ApuEventQueue = wfx + LCD_HEIGHT * NES_DISP_WIDTH; //ROM = audiobuf; //rb->splash(90000000, "size: %x", size); argc = 2; argv[1] = parameter; //rb->strcpy(temp, "/.rockbox/rocks/test.nes"); //argv[1] = temp; /* for(i=0; i<64; ++i) { NesPalette[i] = SDL_MapRGB(screen->format, NesPaletteRGB[i][0], NesPaletteRGB[i][1], NesPaletteRGB[i][2]); }*/ /* If a rom name specified, start it */ if (argc>=2) { if ( start_application(argv[1]) ) { /* MainLoop */ InfoNES_Main(); /* End */ SaveSRAM(); } else { /* Not a NES format file */ rb->splash(1, "%s isn't a NES format file.\n", argv[1] ); } } else { /* Help Message */ rb->splash(stime, "Copyright (C) 1998-2006 Jay's Factory, "); rb->splash(stime, "SDL Ports by mata.\n"); rb->splash(stime, "%s. Usage: %s [NES format file]\n", VERSION, argv[0] ); } return 0; } /* Start application */ int start_application(char *filename) { /* Set a ROM image name */ rb->strcpy( szRomName, filename ); /* Load cassette */ if(InfoNES_Load(szRomName)==0) { /* Load SRAM */ LoadSRAM(); /* Success */ return 1; } /* Failure */ return 0; } /*===================================================================*/ /* */ /* LoadSRAM() : Load a SRAM */ /* */ /*===================================================================*/ int LoadSRAM() { /* * Load a SRAM * * Return values * 0 : Normally * -1 : SRAM data couldn't be read */ int fp; unsigned char pSrcBuf[ SRAM_SIZE ]; unsigned char chData; unsigned char chTag; int nRunLen; int nDecoded; int nDecLen; int nIdx; // It doesn't need to save it nSRAM_SaveFlag = 0; // It is finished if the ROM doesn't have SRAM if ( !ROM_SRAM ) return 0; // There is necessity to save it nSRAM_SaveFlag = 1; // The preparation of the SRAM file name rb->strcpy( szSaveName, szRomName ); rb->strcpy( rb->strrchr( szSaveName, '.' ) + 1, "srm" ); /*-------------------------------------------------------------------*/ /* Read a SRAM data */ /*-------------------------------------------------------------------*/ // Open SRAM file fp = rb->open( szSaveName, O_RDWR | O_CREAT ); //are flags correct? if ( fp == NULL ) return -1; // Read SRAM data //fread( pSrcBuf, SRAM_SIZE, 1, fp ); rb->read(fp, pSrcBuf, SRAM_SIZE); // Close SRAM file rb->close( fp ); /*-------------------------------------------------------------------*/ /* Extract a SRAM data */ /*-------------------------------------------------------------------*/ nDecoded = 0; nDecLen = 0; chTag = pSrcBuf[ nDecoded++ ]; while ( nDecLen < 8192 ) { chData = pSrcBuf[ nDecoded++ ]; if ( chData == chTag ) { chData = pSrcBuf[ nDecoded++ ]; nRunLen = pSrcBuf[ nDecoded++ ]; for ( nIdx = 0; nIdx < nRunLen + 1; ++nIdx ) { SRAM[ nDecLen++ ] = chData; } } else { SRAM[ nDecLen++ ] = chData; } } // Successful return 0; } /*===================================================================*/ /* */ /* SaveSRAM() : Save a SRAM */ /* */ /*===================================================================*/ int SaveSRAM() { /* * Save a SRAM * * Return values * 0 : Normally * -1 : SRAM data couldn't be written */ int fp; int nUsedTable[ 256 ]; unsigned char chData; unsigned char chPrevData; unsigned char chTag; int nIdx; int nEncoded; int nEncLen; int nRunLen; unsigned char pDstBuf[ SRAM_SIZE ]; if ( !nSRAM_SaveFlag ) return 0; // It doesn't need to save it /*-------------------------------------------------------------------*/ /* Compress a SRAM data */ /*-------------------------------------------------------------------*/ rb->memset( nUsedTable, 0, sizeof nUsedTable ); for ( nIdx = 0; nIdx < SRAM_SIZE; ++nIdx ) { ++nUsedTable[ SRAM[ nIdx++ ] ]; } for ( nIdx = 1, chTag = 0; nIdx < 256; ++nIdx ) { if ( nUsedTable[ nIdx ] < nUsedTable[ chTag ] ) chTag = nIdx; } nEncoded = 0; nEncLen = 0; nRunLen = 1; pDstBuf[ nEncLen++ ] = chTag; chPrevData = SRAM[ nEncoded++ ]; while ( nEncoded < SRAM_SIZE && nEncLen < SRAM_SIZE - 133 ) { chData = SRAM[ nEncoded++ ]; if ( chPrevData == chData && nRunLen < 256 ) ++nRunLen; else { if ( nRunLen >= 4 || chPrevData == chTag ) { pDstBuf[ nEncLen++ ] = chTag; pDstBuf[ nEncLen++ ] = chPrevData; pDstBuf[ nEncLen++ ] = nRunLen - 1; } else { for ( nIdx = 0; nIdx < nRunLen; ++nIdx ) pDstBuf[ nEncLen++ ] = chPrevData; } chPrevData = chData; nRunLen = 1; } } if ( nRunLen >= 4 || chPrevData == chTag ) { pDstBuf[ nEncLen++ ] = chTag; pDstBuf[ nEncLen++ ] = chPrevData; pDstBuf[ nEncLen++ ] = nRunLen - 1; } else { for ( nIdx = 0; nIdx < nRunLen; ++nIdx ) pDstBuf[ nEncLen++ ] = chPrevData; } /*-------------------------------------------------------------------*/ /* Write a SRAM data */ /*-------------------------------------------------------------------*/ // Open SRAM file fp = rb->open( szSaveName, O_CREAT | O_TRUNC | O_WRONLY ); if ( fp == NULL ) return -1; // Write SRAM data rb->write(fp, pDstBuf, nEncLen); // Close SRAM file rb->close( fp ); // Successful return 0; } /*===================================================================*/ /* */ /* InfoNES_Menu() : Menu screen */ /* */ /*===================================================================*/ int InfoNES_Menu(){ if(quit) return -1; return 0; } /* Read ROM image file */ int InfoNES_ReadRom( const char *pszFileName ){ int fp; /* Open ROM file */ fp=rb->open(pszFileName, O_RDONLY); if(fp==NULL) return -1; /* Read ROM Header */ rb->read( fp, &NesHeader, sizeof NesHeader); if( rb->memcmp( NesHeader.byID, "NES\x1a", 4 )!=0){ /* not .nes file */ rb->close( fp ); return -1; } /* Clear SRAM */ rb->memset( SRAM, 0, SRAM_SIZE ); /* If trainer presents Read Triner at 0x7000-0x71ff */ if(NesHeader.byInfo1 & 4){ rb->read(fp, &SRAM[ 0x1000 ], 512); } /* Allocate Memory for ROM Image */ //ROM = (BYTE *)buffer_alloc( NesHeader.byRomSize * 0x4000 ); /* Read ROM Image */ rb->read(fp, ROM, 0x4000 * NesHeader.byRomSize); if(NesHeader.byVRomSize>0){ /* Allocate Memory for VROM Image */ //VROM = (BYTE *)malloc( NesHeader.byVRomSize * 0x2000 ); /* Read VROM Image */ rb->read(fp, VROM, 0x2000 * NesHeader.byVRomSize); } /* File close */ rb->close( fp ); /* Successful */ return 0; } /* Release a memory for ROM */ void InfoNES_ReleaseRom(){ /* if(ROM){ free(ROM); ROM=NULL; } if(VROM){ free(VROM); VROM=NULL; }*/ return; } /* Transfer the contents of work frame on the screen */ void InfoNES_LoadFrame(){ int x, y, i, j; BYTE *p,*pl; WORD *pw; #if 0 //actual size of NES screan for(y = 0; y < NES_DISP_HEIGHT; y++) { for(x = 0; x < NES_DISP_WIDTH; x++){ rb->lcd_set_foreground(WorkFrame[x + y * NES_DISP_WIDTH]); rb->lcd_drawpixel(x, y); } } #endif #if 0 //1/2 size of NES screan for(y = 0; y < NES_DISP_HEIGHT; y += 2) { for(x = 0; x < NES_DISP_WIDTH; x += 2){ rb->lcd_set_foreground(WorkFrame[x + y * NES_DISP_WIDTH]); rb->lcd_drawpixel(x/2, y/2); } } #endif #if 0 //old scale ver j = 0; i = 0; for(y = 0; y < LCD_HEIGHT * 2; y += 2) { i = 0; for(x = 0; x < LCD_WIDTH; x += 1) { if(x + i > NES_DISP_WIDTH) break; //if(!((x - i) * LCD_WIDTH % NES_DISP_WIDTH)) if(x%2) rb->lcd_set_foreground(WorkFrame[x + i + y * NES_DISP_WIDTH]); else { rb->lcd_set_foreground((WorkFrame[x + i + y * NES_DISP_WIDTH] + WorkFrame[1 + i + x + y * NES_DISP_WIDTH])/2); ++i; } rb->lcd_drawpixel(x, y/2); } } #endif #if 1 //scaled to fit screan. no interpolation. for(y = 0; y < LCD_HEIGHT; y++) { for(x = 0; x < LCD_WIDTH; x++) { rb->lcd_set_foreground(WorkFrame[x * NES_DISP_WIDTH / LCD_WIDTH + y * NES_DISP_HEIGHT / LCD_HEIGHT * NES_DISP_WIDTH]); rb->lcd_drawpixel(x, y); } } #endif #if 0 //scaled to fit screan with interpolation. should be redone //WORD wf[LCD_HEIGHT * LCD_WIDTH]; for(y = 0; y < NES_DISP_HEIGHT; y++) { for(x = 0; x < LCD_WIDTH; x++) { if(x * NES_DISP_WIDTH % LCD_WIDTH == 0) wfx[x + y * LCD_WIDTH] = WorkFrame[x * NES_DISP_WIDTH / LCD_WIDTH + y * NES_DISP_WIDTH]; else { wfx[x + y * LCD_WIDTH] = (WorkFrame[x * NES_DISP_WIDTH / LCD_WIDTH + y * NES_DISP_WIDTH] + WorkFrame[x * NES_DISP_WIDTH / LCD_WIDTH + y * NES_DISP_WIDTH + 1]) /2; } } } for(y = 0; y < LCD_HEIGHT; y++) { for(x = 0; x < LCD_WIDTH; x++) { if(y * NES_DISP_HEIGHT % LCD_HEIGHT == 0) rb->lcd_set_foreground(wfx[x + y * NES_DISP_HEIGHT / LCD_HEIGHT * LCD_WIDTH]); else { rb->lcd_set_foreground((wfx[x + y * NES_DISP_HEIGHT / LCD_HEIGHT * LCD_WIDTH] + wfx[x + y * NES_DISP_HEIGHT / LCD_HEIGHT * LCD_WIDTH]) / 2); } rb->lcd_drawpixel(x, y); } } #endif rb->lcd_update(); //rb->splash(stime, "mapper no: %d", MapperNo); /* SDL_LockSurface(screen); pl=(BYTE *)screen->pixels; pw = WorkFrame; for(y=0; ypitch; pw+=(0x100-NES_DISP_WIDTH); } SDL_UnlockSurface(screen); SDL_Flip(screen); */ } /* Get a joypad state */ void InfoNES_PadState( DWORD *pdwPad1, DWORD *pdwPad2, DWORD *pdwSystem ) { poll_event(); *pdwPad1 = dwPad1; *pdwPad2 = dwPad2; *pdwSystem = dwSystem; } static const int joy_commit_range = 3276; void poll_event(void) { int bs; bs = rb->button_status(); if(bs & 0x40) //up dwPad1 |= 1 << 4; else dwPad1 &= ~(1 << 4); if(bs & 0x80) //down dwPad1 |= 1 << 5; else dwPad1 &= ~(1 << 5); if(bs & 0x02) //left dwPad1 |= 1 << 6; else dwPad1 &= ~(1 << 6); if(bs & 0x04) //right dwPad1 |= 1 << 7; else dwPad1 &= ~(1 << 7); if(bs & 0x8) //a //upper right dwPad1 |= 1 << 1; else dwPad1 &= ~(1 << 1); if(bs & 0x10) //b //mid right dwPad1 |= 1 << 0; else dwPad1 &= ~(1 << 0); if(bs & 0x20) //select //low right dwPad1 |= 1 << 2; else dwPad1 &= ~(1 << 2); if(bs & 0x01) //start //left dwPad1 |= 1 << 3; else dwPad1 &= ~(1 << 3); /* //switch(rb->button_get(0) switch(rb->button_status()) { case 0x40: //up dwPad1 = 1 << 4; break; case 0x80: //down dwPad1 = 1 << 5; break; case 0x02: //left dwPad1 = 1 << 6; break; case 0x04: //right dwPad1 = 1 << 7; break; case 0x08: //a //upper right dwPad1 = 1 << 1; break; case 0x10: //b //mid right dwPad1 = 1 << 0; break; case 0x20: //select //low right dwPad1 = 1 << 2; break; case 0x01: //start //left dwPad1 = 1 << 3; break; default: dwPad1 = 0; break; } */ if(dwPad1 & (1 << 3)) ++start_menu; if(start_menu == 20) menu(); return; #if 0 SDL_Event e; static signed char x_joy=0, y_joy=0; while(SDL_PollEvent(&e)) { switch(e.type) { case SDL_QUIT: dwSystem|=PAD_SYS_QUIT; quit=1; break; case SDL_KEYDOWN: switch(e.key.keysym.sym) { case SDLK_ESCAPE: dwSystem|=PAD_SYS_QUIT; quit=1; break; /* case SDLK_RIGHT: dwPad1 |= (1<<7);break; case SDLK_LEFT: dwPad1 |= (1<<6);break; case SDLK_DOWN: dwPad1 |= (1<<5);break; case SDLK_UP: dwPad1 |= (1<<4);break; case SDLK_s: dwPad1 |= (1<<3);break; Start case SDLK_a: dwPad1 |= (1<<2);break; Select case SDLK_z: dwPad1 |= (1<<1);break; 'B' case SDLK_x: dwPad1 |= (1<<0);break; 'A' */ case SDLK_f: dwPad1 |= (1<<7);break; case SDLK_w: dwPad1 |= (1<<6);break; case SDLK_d: dwPad1 |= (1<<5);break; case SDLK_a: dwPad1 |= (1<<4);break; case SDLK_m: dwPad1 |= (1<<3);break; case SDLK_2: dwPad1 |= (1<<2);break; case SDLK_3: dwPad1 |= (1<<1);break; case SDLK_RETURN: dwPad1 |= (1<<0);break; case SDLK_c: /* Toggle up and down clipping PPU_UpDown_Clip = ( PPU_UpDown_Clip ? 0 : 1 ); */ break; } /* keydown */ break; case SDL_KEYUP: switch(e.key.keysym.sym) { case SDLK_f: dwPad1 &=~(1<<7);break; case SDLK_w: dwPad1 &=~(1<<6);break; case SDLK_d: dwPad1 &=~(1<<5);break; case SDLK_a: dwPad1 &=~(1<<4);break; case SDLK_m: dwPad1 &=~(1<<3);break; /* Start */ case SDLK_2: dwPad1 &=~(1<<2);break; /* Select */ case SDLK_3: dwPad1 &=~(1<<1);break; /* 'B' */ case SDLK_RETURN: dwPad1 &=~(1<<0);break; /* 'A' */ } /* keyup */ break; /* case SDL_JOYAXISMOTION: switch(e.jaxis.axis){ case 0: if(e.jaxis.value > joy_commit_range){ if(x_joy > 0) break; if(x_joy < 0) dwPad1 &=~(1<<6); dwPad1 |= (1<<7); x_joy=+1; break; } if(e.jaxis.value < -joy_commit_range){ if(x_joy < 0) break; if(x_joy > 0) dwPad1 &=~(1<<7); dwPad1 |= (1<<6); x_joy=-1; break; } if (x_joy < 0) dwPad1 &=~(1<<6); else if(x_joy > 0) dwPad1 &=~(1<<7); x_joy= 0; break; case 1: if(e.jaxis.value > joy_commit_range){ if(y_joy > 0) break; if(y_joy < 0) dwPad1 &=~(1<<4); dwPad1 |= (1<<5); y_joy=+1; break; } if(e.jaxis.value < -joy_commit_range){ if(y_joy < 0) break; if(y_joy > 0) dwPad1 &=~(1<<5); dwPad1 |= (1<<4); y_joy=-1; break; } if (y_joy < 0) dwPad1 &=~(1<<4); else if (y_joy > 0) dwPad1 &=~(1<<5); y_joy= 0; break; } case SDL_JOYBUTTONUP: switch(e.jbutton.button){ case 2: dwPad1 &=~(1<<0);break; case 1: dwPad1 &=~(1<<1);break; case 8: dwPad1 &=~(1<<2);break; case 9: dwPad1 &=~(1<<3);break; } break; case SDL_JOYBUTTONDOWN: switch(e.jbutton.button){ case 2: dwPad1 |= (1<<0);break; case 1: dwPad1 |= (1<<1);break; case 8: dwPad1 |= (1<<2);break; case 9: dwPad1 |= (1<<3);break; } break; */ } } #endif return; } /* memcpy */ void *InfoNES_MemoryCopy( void *dest, const void *src, int count ){ rb->memcpy( dest, src, count ); return dest; } /* memset */ void *InfoNES_MemorySet( void *dest, int c, int count ){ rb->memset( dest, c, count); return dest; } /* Print debug message */ void InfoNES_DebugPrint( char *pszMsg ) { rb->splash(stime, "%s\n", pszMsg); } /* Wait */ void InfoNES_Wait(){} /* Sound Initialize */ void InfoNES_SoundInit( void ){} void waveout(void *udat,BYTE *stream,int len){ /* if ( !wavdone ) { memcpy( stream, &final_wave[(wavflag - 1) << 10], len ); wavflag = 0; wavdone = 1; } */ } /* Sound Open */ int InfoNES_SoundOpen( int samples_per_sync, int sample_rate ){ /* SDL_AudioSpec asp; asp.freq=sample_rate; asp.format=AUDIO_U8; asp.channels=1; asp.samples=1024; asp.callback=waveout; if(SDL_OpenAudio(&asp,&audio_spec)<0){ fprintf(stderr,"Can't Open SDL Audio\n"); return -1; } waveptr = wavflag = 0; wavdone = 1; SDL_PauseAudio(0); */ return 1; } /* Sound Close */ void InfoNES_SoundClose( void ){ /* SDL_CloseAudio(); */ } /* Sound Output 5 Waves - 2 Pulse, 1 Triangle, 1 Noise. 1 DPCM */ void InfoNES_SoundOutput(int samples, BYTE *wave1, BYTE *wave2, BYTE *wave3, BYTE *wave4, BYTE *wave5){ /* int i; for (i = 0; i < samples; i++) { final_wave[waveptr] = ( wave1[i] + wave2[i] + wave3[i] + wave4[i] + wave5[i] ) / 5; waveptr++; if ( waveptr == 2048 ) { waveptr = 0; wavflag = 2; wavdone=0; } else if ( waveptr == 1024 ) { wavflag = 1; wavdone=0; } while (!wavdone) SDL_Delay(0); } */ } /* Print system message */ void InfoNES_MessageBox(char *pszMsg, ...){} /* End of InfoNES_System_SDL.cpp */ void menu(void) { start_menu = 0; return; }