nes 红白机模拟器 第4篇 linux 手柄驱动支持
小霸王学习机的真实手柄,实测CPU 占用 80%
接线图:
手柄读时序:
joypad.c 驱动: 普通的字符设备驱动。
1 #include <linux/module.h> 2 #include <linux/kernel.h> 3 #include <linux/fs.h> 4 #include <linux/init.h> 5 #include <linux/delay.h> 6 #include <asm/uaccess.h> 7 #include <asm/irq.h> 8 #include <asm/io.h> 9 #include <linux/device.h> 10 11 /** 12 *手柄接线定义 13 *VCC 3.3 来自 串口 14 *GND 来自 串口 15 *CLK 摄像头接口 1P IICSDA GPE15 16 *LATCH 摄像头接口 2P IICSCL GPE14 17 *DAT0 摄像头接口 5P CAMCLK GPJ11 18 */ 19 20 #define GPE_BASE 0x56000040 21 #define GPJ_BASE 0x560000d0 22 23 //定义一个结构体用来保存 GPIO 信息 24 typedef struct { 25 unsigned int con; 26 unsigned int dat; 27 unsigned int up; 28 29 }T_GPIO_REG, *PT_GPIO_REG; 30 31 //禁止编译器优化 32 static volatile PT_GPIO_REG pt_gpe_reg; 33 static volatile PT_GPIO_REG pt_gpj_reg; 34 35 static struct class *joypad_drv_class; 36 37 static ssize_t joypad_drv_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) 38 { 39 //利用 sszie_t 返回 手柄键值 40 //buf 是有符号无法保存 8 bit 41 int i; 42 ssize_t val = 0; 43 pt_gpe_reg->dat |= 1<<14; 44 udelay(2); 45 pt_gpe_reg->dat &= ~(1<<14); 46 for(i=0; i<8; i++) 47 { 48 udelay(2); 49 if(! (pt_gpj_reg->dat & 1<<11)) 50 { 51 val |= 1<<i; 52 } 53 54 pt_gpe_reg->dat |= 1<<15; 55 udelay(2); 56 pt_gpe_reg->dat &= ~(1<<15); 57 } 58 //最后输出低电平 59 pt_gpe_reg->dat &= ~(1<<14 | 1<<15); 60 return val; 61 } 62 63 static struct file_operations joypad_drv_fops = { 64 .owner = THIS_MODULE, 65 .read = joypad_drv_read, 66 }; 67 68 int major; 69 //注册驱动程序 70 int joypad_drv_init(void) 71 { 72 major = register_chrdev(0, "joypad_drv", &joypad_drv_fops); 73 74 //自动创建 dev 节点 75 joypad_drv_class = class_create(THIS_MODULE, "joypad_drv"); 76 device_create(joypad_drv_class, NULL, MKDEV(major, 0), NULL, "joypad"); 77 78 //ioremap 地址映射 79 pt_gpe_reg = ioremap(GPE_BASE, sizeof(T_GPIO_REG)); 80 pt_gpj_reg = ioremap(GPJ_BASE, sizeof(T_GPIO_REG)); 81 82 //配置GPIO 83 //GPE 14 15 配置为输出引脚 84 pt_gpe_reg->con &= ~(3<<(2*15)); 85 pt_gpe_reg->con &= ~(3<<(2*14)); 86 pt_gpe_reg->con |= 1<<(2*15); 87 pt_gpe_reg->con |= 1<<(2*14); 88 89 //默认输出低电平 90 pt_gpe_reg->dat &= ~(1<<14 | 1<<15); 91 92 //GPJ 11 配置为输入引脚 禁用内部上拉 93 pt_gpj_reg->con &= ~(3<<(2*11)); 94 pt_gpj_reg->up |= 1<<11; 95 return 0; 96 } 97 98 //卸载驱动程序 99 void joypad_drv_exit(void) 100 { 101 //取消 地址映射 102 iounmap(pt_gpe_reg); 103 iounmap(pt_gpj_reg); 104 105 unregister_chrdev(major, "joypad_drv"); 106 device_destroy(joypad_drv_class, MKDEV(major, 0)); 107 class_destroy(joypad_drv_class); 108 } 109 110 module_init(joypad_drv_init); 111 module_exit(joypad_drv_exit); 112 MODULE_LICENSE("GPL");
InfoNES InfoNES_System_Linux.cpp:
1 /*===================================================================*/ 2 /* */ 3 /* InfoNES_System_Linux.cpp : Linux specific File */ 4 /* */ 5 /* 2001/05/18 InfoNES Project ( Sound is based on DarcNES ) */ 6 /* */ 7 /*===================================================================*/ 8 9 /*-------------------------------------------------------------------*/ 10 /* Include files */ 11 /*-------------------------------------------------------------------*/ 12 13 #include <stdio.h> 14 #include <stdlib.h> 15 #include <string.h> 16 #include <pthread.h> 17 18 #include <sys/types.h> 19 #include <sys/stat.h> 20 #include <fcntl.h> 21 #include <sys/ioctl.h> 22 #include <unistd.h> 23 #include <sys/soundcard.h> 24 25 #include "../InfoNES.h" 26 #include "../InfoNES_System.h" 27 #include "../InfoNES_pAPU.h" 28 29 //bool define 30 #define TRUE 1 31 #define FALSE 0 32 33 /* lcd 操作相关 头文件 */ 34 #include <sys/types.h> 35 #include <sys/stat.h> 36 #include <fcntl.h> 37 #include <linux/fb.h> 38 #include <sys/ioctl.h> 39 #include <unistd.h> 40 #include <string.h> 41 #include <sys/mman.h> 42 #include <termios.h> 43 44 #include <fcntl.h> 45 46 #define JOYPAD_DEV "/dev/joypad" 47 static int joypad_fd; 48 49 static int fb_fd; 50 static unsigned char *fb_mem; 51 static int px_width; 52 static int line_width; 53 static int screen_width; 54 static struct fb_var_screeninfo var; 55 56 static int init_joypad() 57 { 58 joypad_fd = open(JOYPAD_DEV, O_RDONLY); 59 if(-1 == joypad_fd) 60 { 61 printf("joypad dev not found \r\n"); 62 return -1; 63 } 64 return 0; 65 } 66 67 static int lcd_fb_display_px(WORD color, int x, int y) 68 { 69 unsigned char *pen8; 70 unsigned short *pen16; 71 72 pen8 = (unsigned char *)(fb_mem + y*line_width + x*px_width); 73 pen16 = (unsigned short *)pen8; 74 *pen16 = color; 75 76 return 0; 77 } 78 79 static int lcd_fb_init() 80 { 81 //如果使用 mmap 打开方式 必须是 读定方式 82 fb_fd = open("/dev/fb0", O_RDWR); 83 if(-1 == fb_fd) 84 { 85 printf("cat't open /dev/fb0 \n"); 86 return -1; 87 } 88 //获取屏幕参数 89 if(-1 == ioctl(fb_fd, FBIOGET_VSCREENINFO, &var)) 90 { 91 close(fb_fd); 92 printf("cat't ioctl /dev/fb0 \n"); 93 return -1; 94 } 95 96 //计算参数 97 px_width = var.bits_per_pixel / 8; 98 line_width = var.xres * px_width; 99 screen_width = var.yres * line_width; 100 101 fb_mem = (unsigned char *)mmap(NULL, screen_width, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0); 102 if(fb_mem == (void *)-1) 103 { 104 close(fb_fd); 105 printf("cat't mmap /dev/fb0 \n"); 106 return -1; 107 } 108 //清屏 109 memset(fb_mem, 0 , screen_width); 110 return 0; 111 } 112 113 /*-------------------------------------------------------------------*/ 114 /* ROM image file information */ 115 /*-------------------------------------------------------------------*/ 116 117 char szRomName[256]; 118 char szSaveName[256]; 119 int nSRAM_SaveFlag; 120 121 /*-------------------------------------------------------------------*/ 122 /* Constants ( Linux specific ) */ 123 /*-------------------------------------------------------------------*/ 124 125 #define VBOX_SIZE 7 126 #define SOUND_DEVICE "/dev/dsp" 127 #define VERSION "InfoNES v0.91J" 128 129 /*-------------------------------------------------------------------*/ 130 /* Global Variables ( Linux specific ) */ 131 /*-------------------------------------------------------------------*/ 132 133 /* Emulation thread */ 134 pthread_t emulation_tid; 135 int bThread; 136 137 /* Pad state */ 138 DWORD dwKeyPad1; 139 DWORD dwKeyPad2; 140 DWORD dwKeySystem; 141 142 /* For Sound Emulation */ 143 BYTE final_wave[2048]; 144 int waveptr; 145 int wavflag; 146 int sound_fd; 147 148 /*-------------------------------------------------------------------*/ 149 /* Function prototypes ( Linux specific ) */ 150 /*-------------------------------------------------------------------*/ 151 152 void *emulation_thread( void *args ); 153 154 155 void start_application( char *filename ); 156 157 158 int LoadSRAM(); 159 160 161 int SaveSRAM(); 162 163 164 /* Palette data */ 165 WORD NesPalette[64] = 166 { 167 0x39ce, 0x1071, 0x0015, 0x2013, 0x440e, 0x5402, 0x5000, 0x3c20, 168 0x20a0, 0x0100, 0x0140, 0x00e2, 0x0ceb, 0x0000, 0x0000, 0x0000, 169 0x5ef7, 0x01dd, 0x10fd, 0x401e, 0x5c17, 0x700b, 0x6ca0, 0x6521, 170 0x45c0, 0x0240, 0x02a0, 0x0247, 0x0211, 0x0000, 0x0000, 0x0000, 171 0x7fff, 0x1eff, 0x2e5f, 0x223f, 0x79ff, 0x7dd6, 0x7dcc, 0x7e67, 172 0x7ae7, 0x4342, 0x2769, 0x2ff3, 0x03bb, 0x0000, 0x0000, 0x0000, 173 0x7fff, 0x579f, 0x635f, 0x6b3f, 0x7f1f, 0x7f1b, 0x7ef6, 0x7f75, 174 0x7f94, 0x73f4, 0x57d7, 0x5bf9, 0x4ffe, 0x0000, 0x0000, 0x0000 175 }; 176 177 /*===================================================================*/ 178 /* */ 179 /* main() : Application main */ 180 /* */ 181 /*===================================================================*/ 182 183 /* Application main */ 184 int main( int argc, char **argv ) 185 { 186 char cmd; 187 188 /*-------------------------------------------------------------------*/ 189 /* Pad Control */ 190 /*-------------------------------------------------------------------*/ 191 192 /* Initialize a pad state */ 193 dwKeyPad1 = 0; 194 dwKeyPad2 = 0; 195 dwKeySystem = 0; 196 197 /*-------------------------------------------------------------------*/ 198 /* Load Cassette & Create Thread */ 199 /*-------------------------------------------------------------------*/ 200 201 /* Initialize thread state */ 202 bThread = FALSE; 203 204 /* If a rom name specified, start it */ 205 if ( argc == 2 ) 206 { 207 start_application( argv[1] ); 208 } 209 210 lcd_fb_init(); 211 init_joypad(); 212 213 //主循环中处理输入事件 214 while(1) 215 { 216 dwKeyPad1 = read(joypad_fd, 0, 0); 217 } 218 return(0); 219 } 220 221 222 /*===================================================================*/ 223 /* */ 224 /* emulation_thread() : Thread Hooking Routine */ 225 /* */ 226 /*===================================================================*/ 227 228 void *emulation_thread( void *args ) 229 { 230 InfoNES_Main(); 231 } 232 233 234 /*===================================================================*/ 235 /* */ 236 /* start_application() : Start NES Hardware */ 237 /* */ 238 /*===================================================================*/ 239 void start_application( char *filename ) 240 { 241 /* Set a ROM image name */ 242 strcpy( szRomName, filename ); 243 244 /* Load cassette */ 245 if ( InfoNES_Load( szRomName ) == 0 ) 246 { 247 /* Load SRAM */ 248 LoadSRAM(); 249 250 /* Create Emulation Thread */ 251 bThread = TRUE; 252 pthread_create( &emulation_tid, NULL, emulation_thread, NULL ); 253 } 254 } 255 256 257 /*===================================================================*/ 258 /* */ 259 /* LoadSRAM() : Load a SRAM */ 260 /* */ 261 /*===================================================================*/ 262 int LoadSRAM() 263 { 264 /* 265 * Load a SRAM 266 * 267 * Return values 268 * 0 : Normally 269 * -1 : SRAM data couldn't be read 270 */ 271 272 FILE *fp; 273 unsigned char pSrcBuf[SRAM_SIZE]; 274 unsigned char chData; 275 unsigned char chTag; 276 int nRunLen; 277 int nDecoded; 278 int nDecLen; 279 int nIdx; 280 281 /* It doesn't need to save it */ 282 nSRAM_SaveFlag = 0; 283 284 /* It is finished if the ROM doesn't have SRAM */ 285 if ( !ROM_SRAM ) 286 return(0); 287 288 /* There is necessity to save it */ 289 nSRAM_SaveFlag = 1; 290 291 /* The preparation of the SRAM file name */ 292 strcpy( szSaveName, szRomName ); 293 strcpy( strrchr( szSaveName, '.' ) + 1, "srm" ); 294 295 /*-------------------------------------------------------------------*/ 296 /* Read a SRAM data */ 297 /*-------------------------------------------------------------------*/ 298 299 /* Open SRAM file */ 300 fp = fopen( szSaveName, "rb" ); 301 if ( fp == NULL ) 302 return(-1); 303 304 /* Read SRAM data */ 305 fread( pSrcBuf, SRAM_SIZE, 1, fp ); 306 307 /* Close SRAM file */ 308 fclose( fp ); 309 310 /*-------------------------------------------------------------------*/ 311 /* Extract a SRAM data */ 312 /*-------------------------------------------------------------------*/ 313 314 nDecoded = 0; 315 nDecLen = 0; 316 317 chTag = pSrcBuf[nDecoded++]; 318 319 while ( nDecLen < 8192 ) 320 { 321 chData = pSrcBuf[nDecoded++]; 322 323 if ( chData == chTag ) 324 { 325 chData = pSrcBuf[nDecoded++]; 326 nRunLen = pSrcBuf[nDecoded++]; 327 for ( nIdx = 0; nIdx < nRunLen + 1; ++nIdx ) 328 { 329 SRAM[nDecLen++] = chData; 330 } 331 }else { 332 SRAM[nDecLen++] = chData; 333 } 334 } 335 336 /* Successful */ 337 return(0); 338 } 339 340 341 /*===================================================================*/ 342 /* */ 343 /* SaveSRAM() : Save a SRAM */ 344 /* */ 345 /*===================================================================*/ 346 int SaveSRAM() 347 { 348 /* 349 * Save a SRAM 350 * 351 * Return values 352 * 0 : Normally 353 * -1 : SRAM data couldn't be written 354 */ 355 356 FILE *fp; 357 int nUsedTable[256]; 358 unsigned char chData; 359 unsigned char chPrevData; 360 unsigned char chTag; 361 int nIdx; 362 int nEncoded; 363 int nEncLen; 364 int nRunLen; 365 unsigned char pDstBuf[SRAM_SIZE]; 366 367 if ( !nSRAM_SaveFlag ) 368 return(0); /* It doesn't need to save it */ 369 370 /*-------------------------------------------------------------------*/ 371 /* Compress a SRAM data */ 372 /*-------------------------------------------------------------------*/ 373 374 memset( nUsedTable, 0, sizeof nUsedTable ); 375 376 for ( nIdx = 0; nIdx < SRAM_SIZE; ++nIdx ) 377 { 378 ++nUsedTable[SRAM[nIdx++]]; 379 } 380 for ( nIdx = 1, chTag = 0; nIdx < 256; ++nIdx ) 381 { 382 if ( nUsedTable[nIdx] < nUsedTable[chTag] ) 383 chTag = nIdx; 384 } 385 386 nEncoded = 0; 387 nEncLen = 0; 388 nRunLen = 1; 389 390 pDstBuf[nEncLen++] = chTag; 391 392 chPrevData = SRAM[nEncoded++]; 393 394 while ( nEncoded < SRAM_SIZE && nEncLen < SRAM_SIZE - 133 ) 395 { 396 chData = SRAM[nEncoded++]; 397 398 if ( chPrevData == chData && nRunLen < 256 ) 399 ++nRunLen; 400 else{ 401 if ( nRunLen >= 4 || chPrevData == chTag ) 402 { 403 pDstBuf[nEncLen++] = chTag; 404 pDstBuf[nEncLen++] = chPrevData; 405 pDstBuf[nEncLen++] = nRunLen - 1; 406 }else { 407 for ( nIdx = 0; nIdx < nRunLen; ++nIdx ) 408 pDstBuf[nEncLen++] = chPrevData; 409 } 410 411 chPrevData = chData; 412 nRunLen = 1; 413 } 414 } 415 if ( nRunLen >= 4 || chPrevData == chTag ) 416 { 417 pDstBuf[nEncLen++] = chTag; 418 pDstBuf[nEncLen++] = chPrevData; 419 pDstBuf[nEncLen++] = nRunLen - 1; 420 }else { 421 for ( nIdx = 0; nIdx < nRunLen; ++nIdx ) 422 pDstBuf[nEncLen++] = chPrevData; 423 } 424 425 /*-------------------------------------------------------------------*/ 426 /* Write a SRAM data */ 427 /*-------------------------------------------------------------------*/ 428 429 /* Open SRAM file */ 430 fp = fopen( szSaveName, "wb" ); 431 if ( fp == NULL ) 432 return(-1); 433 434 /* Write SRAM data */ 435 fwrite( pDstBuf, nEncLen, 1, fp ); 436 437 /* Close SRAM file */ 438 fclose( fp ); 439 440 /* Successful */ 441 return(0); 442 } 443 444 445 /*===================================================================*/ 446 /* */ 447 /* InfoNES_Menu() : Menu screen */ 448 /* */ 449 /*===================================================================*/ 450 int InfoNES_Menu() 451 { 452 /* 453 * Menu screen 454 * 455 * Return values 456 * 0 : Normally 457 * -1 : Exit InfoNES 458 */ 459 460 /* If terminated */ 461 if ( bThread == FALSE ) 462 { 463 return(-1); 464 } 465 466 /* Nothing to do here */ 467 return(0); 468 } 469 470 471 /*===================================================================*/ 472 /* */ 473 /* InfoNES_ReadRom() : Read ROM image file */ 474 /* */ 475 /*===================================================================*/ 476 int InfoNES_ReadRom( const char *pszFileName ) 477 { 478 /* 479 * Read ROM image file 480 * 481 * Parameters 482 * const char *pszFileName (Read) 483 * 484 * Return values 485 * 0 : Normally 486 * -1 : Error 487 */ 488 489 FILE *fp; 490 491 /* Open ROM file */ 492 fp = fopen( pszFileName, "rb" ); 493 if ( fp == NULL ) 494 return(-1); 495 496 /* Read ROM Header */ 497 fread( &NesHeader, sizeof NesHeader, 1, fp ); 498 if ( memcmp( NesHeader.byID, "NES\x1a", 4 ) != 0 ) 499 { 500 /* not .nes file */ 501 fclose( fp ); 502 return(-1); 503 } 504 505 /* Clear SRAM */ 506 memset( SRAM, 0, SRAM_SIZE ); 507 508 /* If trainer presents Read Triner at 0x7000-0x71ff */ 509 if ( NesHeader.byInfo1 & 4 ) 510 { 511 fread( &SRAM[0x1000], 512, 1, fp ); 512 } 513 514 /* Allocate Memory for ROM Image */ 515 ROM = (BYTE *) malloc( NesHeader.byRomSize * 0x4000 ); 516 517 /* Read ROM Image */ 518 fread( ROM, 0x4000, NesHeader.byRomSize, fp ); 519 520 if ( NesHeader.byVRomSize > 0 ) 521 { 522 /* Allocate Memory for VROM Image */ 523 VROM = (BYTE *) malloc( NesHeader.byVRomSize * 0x2000 ); 524 525 /* Read VROM Image */ 526 fread( VROM, 0x2000, NesHeader.byVRomSize, fp ); 527 } 528 529 /* File close */ 530 fclose( fp ); 531 532 /* Successful */ 533 return(0); 534 } 535 536 537 /*===================================================================*/ 538 /* */ 539 /* InfoNES_ReleaseRom() : Release a memory for ROM */ 540 /* */ 541 /*===================================================================*/ 542 void InfoNES_ReleaseRom() 543 { 544 /* 545 * Release a memory for ROM 546 * 547 */ 548 549 if ( ROM ) 550 { 551 free( ROM ); 552 ROM = NULL; 553 } 554 555 if ( VROM ) 556 { 557 free( VROM ); 558 VROM = NULL; 559 } 560 } 561 562 563 /*===================================================================*/ 564 /* */ 565 /* InfoNES_MemoryCopy() : memcpy */ 566 /* */ 567 /*===================================================================*/ 568 void *InfoNES_MemoryCopy( void *dest, const void *src, int count ) 569 { 570 /* 571 * memcpy 572 * 573 * Parameters 574 * void *dest (Write) 575 * Points to the starting address of the copied block's destination 576 * 577 * const void *src (Read) 578 * Points to the starting address of the block of memory to copy 579 * 580 * int count (Read) 581 * Specifies the size, in bytes, of the block of memory to copy 582 * 583 * Return values 584 * Pointer of destination 585 */ 586 587 memcpy( dest, src, count ); 588 return(dest); 589 } 590 591 592 /*===================================================================*/ 593 /* */ 594 /* InfoNES_MemorySet() : memset */ 595 /* */ 596 /*===================================================================*/ 597 void *InfoNES_MemorySet( void *dest, int c, int count ) 598 { 599 /* 600 * memset 601 * 602 * Parameters 603 * void *dest (Write) 604 * Points to the starting address of the block of memory to fill 605 * 606 * int c (Read) 607 * Specifies the byte value with which to fill the memory block 608 * 609 * int count (Read) 610 * Specifies the size, in bytes, of the block of memory to fill 611 * 612 * Return values 613 * Pointer of destination 614 */ 615 616 memset( dest, c, count ); 617 return(dest); 618 } 619 620 621 /*===================================================================*/ 622 /* */ 623 /* InfoNES_LoadFrame() : */ 624 /* Transfer the contents of work frame on the screen */ 625 /* */ 626 /*===================================================================*/ 627 void InfoNES_LoadFrame() 628 { 629 int x,y; 630 WORD wColor; 631 for (y = 0; y < NES_DISP_HEIGHT; y++ ) 632 { 633 for (x = 0; x < NES_DISP_WIDTH; x++ ) 634 { 635 wColor = WorkFrame[y * NES_DISP_WIDTH + x ]; 636 lcd_fb_display_px(wColor, x, y); 637 } 638 } 639 } 640 641 642 /*===================================================================*/ 643 /* */ 644 /* InfoNES_PadState() : Get a joypad state */ 645 /* */ 646 /*===================================================================*/ 647 void InfoNES_PadState( DWORD *pdwPad1, DWORD *pdwPad2, DWORD *pdwSystem ) 648 { 649 /* 650 * Get a joypad state 651 * 652 * Parameters 653 * DWORD *pdwPad1 (Write) 654 * Joypad 1 State 655 * 656 * DWORD *pdwPad2 (Write) 657 * Joypad 2 State 658 * 659 * DWORD *pdwSystem (Write) 660 * Input for InfoNES 661 * 662 */ 663 664 /* Transfer joypad state */ 665 *pdwPad1 = dwKeyPad1; 666 *pdwPad2 = dwKeyPad2; 667 *pdwSystem = dwKeySystem; 668 669 dwKeyPad1 = 0; 670 } 671 672 673 /*===================================================================*/ 674 /* */ 675 /* InfoNES_SoundInit() : Sound Emulation Initialize */ 676 /* */ 677 /*===================================================================*/ 678 void InfoNES_SoundInit( void ) 679 { 680 sound_fd = 0; 681 } 682 683 684 /*===================================================================*/ 685 /* */ 686 /* InfoNES_SoundOpen() : Sound Open */ 687 /* */ 688 /*===================================================================*/ 689 int InfoNES_SoundOpen( int samples_per_sync, int sample_rate ) 690 { 691 return 1; 692 } 693 694 695 /*===================================================================*/ 696 /* */ 697 /* InfoNES_SoundClose() : Sound Close */ 698 /* */ 699 /*===================================================================*/ 700 void InfoNES_SoundClose( void ) 701 { 702 if ( sound_fd ) 703 { 704 close( sound_fd ); 705 } 706 } 707 708 709 /*===================================================================*/ 710 /* */ 711 /* InfoNES_SoundOutput() : Sound Output 5 Waves */ 712 /* */ 713 /*===================================================================*/ 714 void InfoNES_SoundOutput( int samples, BYTE *wave1, BYTE *wave2, BYTE *wave3, BYTE *wave4, BYTE *wave5 ) 715 { 716 717 } 718 719 720 /*===================================================================*/ 721 /* */ 722 /* InfoNES_Wait() : Wait Emulation if required */ 723 /* */ 724 /*===================================================================*/ 725 void InfoNES_Wait() 726 { 727 } 728 729 730 /*===================================================================*/ 731 /* */ 732 /* InfoNES_MessageBox() : Print System Message */ 733 /* */ 734 /*===================================================================*/ 735 void InfoNES_MessageBox( char *pszMsg, ... ) 736 { 737 printf( "MessageBox: %s \n", pszMsg ); 738 } 739 740 741 /* 742 * End of InfoNES_System_Linux.cpp 743 */
转载于:https://www.cnblogs.com/ningci/p/5633731.html
nes 红白机模拟器 第4篇 linux 手柄驱动支持相关推荐
- nes 红白机模拟器 第6篇 声音支持
InfoNES 源码中并没有包含 linux 的声音支持. 但提供 wince 和 win 的工程,文件,通过分析,win 的 DirectSound 发声,在使用 linux ALSA 实现. 先使 ...
- ADI Blackfin DSP处理器-BF533的开发详解70:NES 红白机模拟器(含源码)
硬件准备 ADSP-EDU-BF533:BF533开发板 AD-HP530ICE:ADI DSP仿真器 软件准备 Visual DSP++软件 硬件链接 代码实现功能 代码实现了 NES 游戏模拟器在 ...
- fc安卓模拟器_安利一款手机上的红白机模拟器
戳上面的蓝字关注我哦! 使用平台:安卓 软件简介: NES.emu是一款任天堂红白机(NES.FC)模拟器,软件支持横竖屏.自动保存游戏进度.按键自定义等功能,还可以自行编辑作弊文件,小编为大家带来的 ...
- 撸一个VS Code插件——红白机模拟器 支持手柄 支持保存
分享我自己写的VS Code红白机模拟器 前言 我曾经利用 jense 这个库封装了一个vue组件的nes模拟器:nes-vue: Vue 3 的NES(FC)模拟器组件 (gitee.com),最近 ...
- 使用C++实现FC红白机模拟器 Cartridge 与 Mapper(实现篇)
(继上篇:原理篇,下:实现篇) 2. Cartridge 与 Mapper的实现 首先我们在QT中创建两个类,Cartridge 与 Mapper类: Cartridge 类负责加载和解析ROM,因为 ...
- 使用C++实现FC红白机模拟器 Cartridge 与 Mapper(原理篇)
1. 认识nes文件 我们既然是模拟,就不可能使用实体的卡带硬件.那我们如何获取游戏文件呢?好在已经有人为我们准备好了(心怀感恩). .nes文件是NES(FC)的rom文件,关于它的来龙去脉这里就不 ...
- 使用c++模拟红白机——概论篇(一)
任天堂的红白机系列的游戏应该是大家的童年了,红白机,又称FC,随着计算机技术的不断发展,现在市场上基本已经淘汰了红白机系列的硬件设备了.我偶尔的一个突发奇想,想要在体验一下红白机游戏的乐趣,于是乎我想 ...
- 【历史上的今天】10 月 18 日:Internet Explorer 7 正式发布;全球首家网络银行开业;“美版红白机” NES 诞生
整理 | 王启隆 透过「历史上的今天」,从过去看未来,从现在亦可以改变未来. 今天是 2022 年 10 月 18 日,在 100 年前的今天,英国 BBC 广播电视台成立:BBC 是世界上最大的新闻 ...
- 红白机原理(零)前言
今天来聊聊 FC 游戏机,FC 的意思就是 Family Computer,虽然如今渐渐落寞被淘汰,但在当年的确是风靡全球,不负 Family Computer 这名字. FC 大家应该基本知道吧,e ...
- 还记得当年陪你度过整个夏日的红白机吗?
一转眼,暑假就要过去了,小编看着周围那些忙忙碌碌准备开学的小朋友们,不由想起自己的童年. 那个时候,最开心的就是暑假可以玩游戏机,也就是现在人们口中的FC红白机.虽然在现在看来都是像素级的游戏画面,但 ...
最新文章
- 如何用12864液晶显示图片和绘制任意函数图象(打点)
- 【原】iOS学习之Xcode8关于控制台不打印错误信息
- bfs:01迷宫(洛谷P1141)
- 安防监控系统CIF、D1等格式的解释
- [完结]以C++与Java为例,详解数据结构的动态增长策略
- 【算法】二进制 与、或、异或运算
- Stanford NLP 第四课 神经网络复习
- 《Linux启动过程分析》内核挂载根文件系统
- 关于BPSK、QPSK的一些理解,以及MATLAB实现
- python初体验——单/双/三引号的用法
- 99.9%解决谷歌商店(Google Play)下载应用卡在等待中问题
- STM32初始化产生低电平引起的问题
- 对话系统调查:近期进展与新前沿
- SQL select详解(基于选课系统)
- 《Reasoning about Entailment with Neural Attention》阅读笔记
- Game Maker:一款教学工具造就了一批独立开发者
- 【转】Mosquitto持久层群推消息实现思路
- python类的使用的生物学应用_Python 类的使用
- 【区块链 | Merkle】使用Merkle Tree空投,白名单验证
- 人工智能主要研究内容
热门文章
- Polar Si9000如何选择模型计算射频线宽?
- 大漠插件7.2137
- 网课查题接口 搜题公众号对接题库教程 (附赠题库接口)
- 土木工程--钢筋下料软件(续)
- 《学习笔记13》——web前端助手:插件fehelper的使用
- MAC地址前三位是厂家标识符(Organizationally Unique Identifier),可以从IEEE官网查询
- 电子邮件收发原理和JavaMail开发
- 社区发现算法——Louvain 算法
- 基于注意力机制的循环网络进行层级性多元标签文本分类
- stc流水灯c语言程序,求51单片机流水灯跑马灯程序设计 (STC89C52RC)??