• nes 红白机模拟器 第5篇 全屏显示


    先看一下效果图

     

    放大的原理是使用最初级的算法,直接取对应像素法。

      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 /**
     14  * author:ningci dev
     15  * date:2017-04-24 21:23
     16  */
     17 
     18 #include <stdio.h>
     19 #include <stdlib.h>
     20 #include <string.h>
     21 #include <pthread.h>
     22 
     23 #include <sys/types.h>
     24 #include <sys/stat.h>
     25 #include <fcntl.h>
     26 #include <sys/ioctl.h>
     27 #include <unistd.h>
     28 #include <sys/soundcard.h>
     29 
     30 #include "../InfoNES.h"
     31 #include "../InfoNES_System.h"
     32 #include "../InfoNES_pAPU.h"
     33 
     34 //bool define
     35 #define TRUE 1
     36 #define FALSE 0
     37 
     38 /* lcd 操作相关 头文件 */
     39 #include <sys/types.h>
     40 #include <sys/stat.h>
     41 #include <fcntl.h>
     42 #include <linux/fb.h>
     43 #include <sys/ioctl.h>
     44 #include <unistd.h>
     45 #include <string.h>
     46 #include <sys/mman.h>
     47 #include <termios.h>
     48 
     49 #include <fcntl.h>
     50 
     51 #define JOYPAD_DEV "/dev/joypad"
     52 static int joypad_fd;
     53 
     54 static int fb_fd;
     55 static unsigned char *fb_mem;
     56 static int px_width;
     57 static int line_width;
     58 static int screen_width;
     59 static int lcd_width;
     60 static int lcd_height;
     61 static struct fb_var_screeninfo var;
     62 
     63 static int *zoom_x_tab;
     64 static int *zoom_y_tab;
     65 
     66 static int init_joypad()
     67 {
     68     joypad_fd = open(JOYPAD_DEV, O_RDONLY);
     69     if(-1 == joypad_fd)
     70     {
     71         printf("joypad dev not found 
    ");
     72         return -1;
     73     }
     74     return 0;
     75 }
     76 
     77 static int lcd_fb_display_px(WORD color, int x, int y)
     78 {
     79     unsigned char  *pen8;
     80     unsigned short *pen16;
     81     pen8 = (unsigned char *)(fb_mem + y*line_width + x*px_width);
     82     pen16 = (unsigned short *)pen8;
     83     *pen16 = color;
     84     
     85     return 0;
     86 }
     87 
     88 static int lcd_fb_init()
     89 {
     90     //如果使用 mmap 打开方式 必须是 读定方式
     91     fb_fd = open("/dev/fb0", O_RDWR);
     92     if(-1 == fb_fd)
     93     {
     94         printf("cat't open /dev/fb0 
    ");
     95         return -1;
     96     }
     97     //获取屏幕参数
     98     if(-1 == ioctl(fb_fd, FBIOGET_VSCREENINFO, &var))
     99     {
    100         close(fb_fd);
    101         printf("cat't ioctl /dev/fb0 
    ");
    102         return -1;
    103     }
    104     
    105     //计算参数
    106     px_width     = var.bits_per_pixel / 8;
    107     line_width   = var.xres * px_width;
    108     screen_width = var.yres * line_width;
    109     lcd_width    = var.xres;
    110     lcd_height   = var.yres;
    111     
    112     fb_mem = (unsigned char *)mmap(NULL, screen_width, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);
    113     if(fb_mem == (void *)-1)
    114     {
    115         close(fb_fd);
    116         printf("cat't mmap /dev/fb0 
    ");
    117         return -1;
    118     }
    119     //清屏
    120     memset(fb_mem, 0 , screen_width);
    121     return 0;
    122 }
    123 
    124 /**
    125  * 生成zoom 缩放表
    126  */
    127 int make_zoom_tab()
    128 {
    129     int i;
    130     zoom_x_tab = (int *)malloc(sizeof(int) * lcd_width);
    131     if(NULL == zoom_x_tab)
    132     {
    133         printf("make zoom_x_tab error
    ");
    134         return -1;
    135     }
    136     for(i=0; i<lcd_width; i++)
    137     {
    138         zoom_x_tab[i] = (i+0.4999999)*NES_DISP_WIDTH/lcd_width-0.5;
    139     }
    140     zoom_y_tab = (int *)malloc(sizeof(int) * lcd_height);
    141     if(NULL == zoom_y_tab)
    142     {
    143         printf("make zoom_y_tab error
    ");
    144         return -1;
    145     }
    146     for(i=0; i<lcd_height; i++)
    147     {
    148         zoom_y_tab[i] = (i+0.4999999)*NES_DISP_HEIGHT/lcd_height-0.5;
    149     }
    150     return 1;
    151 }
    152 
    153 /*-------------------------------------------------------------------*/
    154 /*  ROM image file information                                       */
    155 /*-------------------------------------------------------------------*/
    156 
    157 char    szRomName[256];
    158 char    szSaveName[256];
    159 int    nSRAM_SaveFlag;
    160 
    161 /*-------------------------------------------------------------------*/
    162 /*  Constants ( Linux specific )                                     */
    163 /*-------------------------------------------------------------------*/
    164 
    165 #define VBOX_SIZE    7
    166 #define SOUND_DEVICE    "/dev/dsp"
    167 #define VERSION        "InfoNES v0.91J"
    168 
    169 /*-------------------------------------------------------------------*/
    170 /*  Global Variables ( Linux specific )                              */
    171 /*-------------------------------------------------------------------*/
    172 
    173 /* Emulation thread */
    174 pthread_t  emulation_tid;
    175 int bThread;
    176 
    177 /* Pad state */
    178 DWORD    dwKeyPad1;
    179 DWORD    dwKeyPad2;
    180 DWORD    dwKeySystem;
    181 
    182 /* For Sound Emulation */
    183 BYTE    final_wave[2048];
    184 int    waveptr;
    185 int    wavflag;
    186 int    sound_fd;
    187 
    188 /*-------------------------------------------------------------------*/
    189 /*  Function prototypes ( Linux specific )                           */
    190 /*-------------------------------------------------------------------*/
    191 
    192 void *emulation_thread( void *args );
    193 
    194 
    195 void start_application( char *filename );
    196 
    197 
    198 int LoadSRAM();
    199 
    200 
    201 int SaveSRAM();
    202 
    203 
    204 /* Palette data */
    205 WORD NesPalette[64] =
    206 {
    207     0x39ce, 0x1071, 0x0015, 0x2013, 0x440e, 0x5402, 0x5000, 0x3c20,
    208     0x20a0, 0x0100, 0x0140, 0x00e2, 0x0ceb, 0x0000, 0x0000, 0x0000,
    209     0x5ef7, 0x01dd, 0x10fd, 0x401e, 0x5c17, 0x700b, 0x6ca0, 0x6521,
    210     0x45c0, 0x0240, 0x02a0, 0x0247, 0x0211, 0x0000, 0x0000, 0x0000,
    211     0x7fff, 0x1eff, 0x2e5f, 0x223f, 0x79ff, 0x7dd6, 0x7dcc, 0x7e67,
    212     0x7ae7, 0x4342, 0x2769, 0x2ff3, 0x03bb, 0x0000, 0x0000, 0x0000,
    213     0x7fff, 0x579f, 0x635f, 0x6b3f, 0x7f1f, 0x7f1b, 0x7ef6, 0x7f75,
    214     0x7f94, 0x73f4, 0x57d7, 0x5bf9, 0x4ffe, 0x0000, 0x0000, 0x0000
    215 };
    216 
    217 /*===================================================================*/
    218 /*                                                                   */
    219 /*                main() : Application main                          */
    220 /*                                                                   */
    221 /*===================================================================*/
    222 
    223 /* Application main */
    224 int main( int argc, char **argv )
    225 {
    226     char cmd;
    227 
    228     /*-------------------------------------------------------------------*/
    229     /*  Pad Control                                                      */
    230     /*-------------------------------------------------------------------*/
    231 
    232     /* Initialize a pad state */
    233     dwKeyPad1    = 0;
    234     dwKeyPad2    = 0;
    235     dwKeySystem = 0;
    236 
    237     /*-------------------------------------------------------------------*/
    238     /*  Load Cassette & Create Thread                                    */
    239     /*-------------------------------------------------------------------*/
    240 
    241     /* Initialize thread state */
    242     bThread = FALSE;
    243 
    244     /* If a rom name specified, start it */
    245     if ( argc == 2 )
    246     {
    247         start_application( argv[1] );
    248     }
    249     
    250     lcd_fb_init();
    251     init_joypad();
    252     //初始化 zoom 缩放表
    253     make_zoom_tab();
    254     
    255     //主循环中处理输入事件
    256     while(1)
    257     {    
    258         if(0 < joypad_fd)
    259         {
    260             dwKeyPad1 = read(joypad_fd, 0, 0);
    261         }
    262     }
    263     return(0);
    264 }
    265 
    266 
    267 /*===================================================================*/
    268 /*                                                                   */
    269 /*           emulation_thread() : Thread Hooking Routine             */
    270 /*                                                                   */
    271 /*===================================================================*/
    272 
    273 void *emulation_thread( void *args )
    274 {
    275     InfoNES_Main();
    276 }
    277 
    278 
    279 /*===================================================================*/
    280 /*                                                                   */
    281 /*     start_application() : Start NES Hardware                      */
    282 /*                                                                   */
    283 /*===================================================================*/
    284 void start_application( char *filename )
    285 {
    286     /* Set a ROM image name */
    287     strcpy( szRomName, filename );
    288 
    289     /* Load cassette */
    290     if ( InfoNES_Load( szRomName ) == 0 )
    291     {
    292         /* Load SRAM */
    293         LoadSRAM();
    294 
    295         /* Create Emulation Thread */
    296         bThread = TRUE;
    297         pthread_create( &emulation_tid, NULL, emulation_thread, NULL );
    298     }
    299 }
    300 
    301 
    302 /*===================================================================*/
    303 /*                                                                   */
    304 /*           LoadSRAM() : Load a SRAM                                */
    305 /*                                                                   */
    306 /*===================================================================*/
    307 int LoadSRAM()
    308 {
    309 /*
    310  *  Load a SRAM
    311  *
    312  *  Return values
    313  *     0 : Normally
    314  *    -1 : SRAM data couldn't be read
    315  */
    316 
    317     FILE        *fp;
    318     unsigned char    pSrcBuf[SRAM_SIZE];
    319     unsigned char    chData;
    320     unsigned char    chTag;
    321     int        nRunLen;
    322     int        nDecoded;
    323     int        nDecLen;
    324     int        nIdx;
    325 
    326     /* It doesn't need to save it */
    327     nSRAM_SaveFlag = 0;
    328 
    329     /* It is finished if the ROM doesn't have SRAM */
    330     if ( !ROM_SRAM )
    331         return(0);
    332 
    333     /* There is necessity to save it */
    334     nSRAM_SaveFlag = 1;
    335 
    336     /* The preparation of the SRAM file name */
    337     strcpy( szSaveName, szRomName );
    338     strcpy( strrchr( szSaveName, '.' ) + 1, "srm" );
    339 
    340     /*-------------------------------------------------------------------*/
    341     /*  Read a SRAM data                                                 */
    342     /*-------------------------------------------------------------------*/
    343 
    344     /* Open SRAM file */
    345     fp = fopen( szSaveName, "rb" );
    346     if ( fp == NULL )
    347         return(-1);
    348 
    349     /* Read SRAM data */
    350     fread( pSrcBuf, SRAM_SIZE, 1, fp );
    351 
    352     /* Close SRAM file */
    353     fclose( fp );
    354 
    355     /*-------------------------------------------------------------------*/
    356     /*  Extract a SRAM data                                              */
    357     /*-------------------------------------------------------------------*/
    358 
    359     nDecoded    = 0;
    360     nDecLen        = 0;
    361 
    362     chTag = pSrcBuf[nDecoded++];
    363 
    364     while ( nDecLen < 8192 )
    365     {
    366         chData = pSrcBuf[nDecoded++];
    367 
    368         if ( chData == chTag )
    369         {
    370             chData    = pSrcBuf[nDecoded++];
    371             nRunLen = pSrcBuf[nDecoded++];
    372             for ( nIdx = 0; nIdx < nRunLen + 1; ++nIdx )
    373             {
    374                 SRAM[nDecLen++] = chData;
    375             }
    376         }else  {
    377             SRAM[nDecLen++] = chData;
    378         }
    379     }
    380 
    381     /* Successful */
    382     return(0);
    383 }
    384 
    385 
    386 /*===================================================================*/
    387 /*                                                                   */
    388 /*           SaveSRAM() : Save a SRAM                                */
    389 /*                                                                   */
    390 /*===================================================================*/
    391 int SaveSRAM()
    392 {
    393 /*
    394  *  Save a SRAM
    395  *
    396  *  Return values
    397  *     0 : Normally
    398  *    -1 : SRAM data couldn't be written
    399  */
    400 
    401     FILE        *fp;
    402     int        nUsedTable[256];
    403     unsigned char    chData;
    404     unsigned char    chPrevData;
    405     unsigned char    chTag;
    406     int        nIdx;
    407     int        nEncoded;
    408     int        nEncLen;
    409     int        nRunLen;
    410     unsigned char    pDstBuf[SRAM_SIZE];
    411 
    412     if ( !nSRAM_SaveFlag )
    413         return(0);  /* It doesn't need to save it */
    414 
    415     /*-------------------------------------------------------------------*/
    416     /*  Compress a SRAM data                                             */
    417     /*-------------------------------------------------------------------*/
    418 
    419     memset( nUsedTable, 0, sizeof nUsedTable );
    420 
    421     for ( nIdx = 0; nIdx < SRAM_SIZE; ++nIdx )
    422     {
    423         ++nUsedTable[SRAM[nIdx++]];
    424     }
    425     for ( nIdx = 1, chTag = 0; nIdx < 256; ++nIdx )
    426     {
    427         if ( nUsedTable[nIdx] < nUsedTable[chTag] )
    428             chTag = nIdx;
    429     }
    430 
    431     nEncoded    = 0;
    432     nEncLen        = 0;
    433     nRunLen        = 1;
    434 
    435     pDstBuf[nEncLen++] = chTag;
    436 
    437     chPrevData = SRAM[nEncoded++];
    438 
    439     while ( nEncoded < SRAM_SIZE && nEncLen < SRAM_SIZE - 133 )
    440     {
    441         chData = SRAM[nEncoded++];
    442 
    443         if ( chPrevData == chData && nRunLen < 256 )
    444             ++nRunLen;
    445         else{
    446             if ( nRunLen >= 4 || chPrevData == chTag )
    447             {
    448                 pDstBuf[nEncLen++]    = chTag;
    449                 pDstBuf[nEncLen++]    = chPrevData;
    450                 pDstBuf[nEncLen++]    = nRunLen - 1;
    451             }else  {
    452                 for ( nIdx = 0; nIdx < nRunLen; ++nIdx )
    453                     pDstBuf[nEncLen++] = chPrevData;
    454             }
    455 
    456             chPrevData    = chData;
    457             nRunLen        = 1;
    458         }
    459     }
    460     if ( nRunLen >= 4 || chPrevData == chTag )
    461     {
    462         pDstBuf[nEncLen++]    = chTag;
    463         pDstBuf[nEncLen++]    = chPrevData;
    464         pDstBuf[nEncLen++]    = nRunLen - 1;
    465     }else  {
    466         for ( nIdx = 0; nIdx < nRunLen; ++nIdx )
    467             pDstBuf[nEncLen++] = chPrevData;
    468     }
    469 
    470     /*-------------------------------------------------------------------*/
    471     /*  Write a SRAM data                                                */
    472     /*-------------------------------------------------------------------*/
    473 
    474     /* Open SRAM file */
    475     fp = fopen( szSaveName, "wb" );
    476     if ( fp == NULL )
    477         return(-1);
    478 
    479     /* Write SRAM data */
    480     fwrite( pDstBuf, nEncLen, 1, fp );
    481 
    482     /* Close SRAM file */
    483     fclose( fp );
    484 
    485     /* Successful */
    486     return(0);
    487 }
    488 
    489 
    490 /*===================================================================*/
    491 /*                                                                   */
    492 /*                  InfoNES_Menu() : Menu screen                     */
    493 /*                                                                   */
    494 /*===================================================================*/
    495 int InfoNES_Menu()
    496 {
    497 /*
    498  *  Menu screen
    499  *
    500  *  Return values
    501  *     0 : Normally
    502  *    -1 : Exit InfoNES
    503  */
    504 
    505     /* If terminated */
    506     if ( bThread == FALSE )
    507     {
    508         return(-1);
    509     }
    510 
    511     /* Nothing to do here */
    512     return(0);
    513 }
    514 
    515 
    516 /*===================================================================*/
    517 /*                                                                   */
    518 /*               InfoNES_ReadRom() : Read ROM image file             */
    519 /*                                                                   */
    520 /*===================================================================*/
    521 int InfoNES_ReadRom( const char *pszFileName )
    522 {
    523 /*
    524  *  Read ROM image file
    525  *
    526  *  Parameters
    527  *    const char *pszFileName          (Read)
    528  *
    529  *  Return values
    530  *     0 : Normally
    531  *    -1 : Error
    532  */
    533 
    534     FILE *fp;
    535 
    536     /* Open ROM file */
    537     fp = fopen( pszFileName, "rb" );
    538     if ( fp == NULL )
    539         return(-1);
    540 
    541     /* Read ROM Header */
    542     fread( &NesHeader, sizeof NesHeader, 1, fp );
    543     if ( memcmp( NesHeader.byID, "NESx1a", 4 ) != 0 )
    544     {
    545         /* not .nes file */
    546         fclose( fp );
    547         return(-1);
    548     }
    549 
    550     /* Clear SRAM */
    551     memset( SRAM, 0, SRAM_SIZE );
    552 
    553     /* If trainer presents Read Triner at 0x7000-0x71ff */
    554     if ( NesHeader.byInfo1 & 4 )
    555     {
    556         fread( &SRAM[0x1000], 512, 1, fp );
    557     }
    558 
    559     /* Allocate Memory for ROM Image */
    560     ROM = (BYTE *) malloc( NesHeader.byRomSize * 0x4000 );
    561 
    562     /* Read ROM Image */
    563     fread( ROM, 0x4000, NesHeader.byRomSize, fp );
    564 
    565     if ( NesHeader.byVRomSize > 0 )
    566     {
    567         /* Allocate Memory for VROM Image */
    568         VROM = (BYTE *) malloc( NesHeader.byVRomSize * 0x2000 );
    569 
    570         /* Read VROM Image */
    571         fread( VROM, 0x2000, NesHeader.byVRomSize, fp );
    572     }
    573 
    574     /* File close */
    575     fclose( fp );
    576 
    577     /* Successful */
    578     return(0);
    579 }
    580 
    581 
    582 /*===================================================================*/
    583 /*                                                                   */
    584 /*           InfoNES_ReleaseRom() : Release a memory for ROM         */
    585 /*                                                                   */
    586 /*===================================================================*/
    587 void InfoNES_ReleaseRom()
    588 {
    589 /*
    590  *  Release a memory for ROM
    591  *
    592  */
    593 
    594     if ( ROM )
    595     {
    596         free( ROM );
    597         ROM = NULL;
    598     }
    599 
    600     if ( VROM )
    601     {
    602         free( VROM );
    603         VROM = NULL;
    604     }
    605 }
    606 
    607 
    608 /*===================================================================*/
    609 /*                                                                   */
    610 /*             InfoNES_MemoryCopy() : memcpy                         */
    611 /*                                                                   */
    612 /*===================================================================*/
    613 void *InfoNES_MemoryCopy( void *dest, const void *src, int count )
    614 {
    615 /*
    616  *  memcpy
    617  *
    618  *  Parameters
    619  *    void *dest                       (Write)
    620  *      Points to the starting address of the copied block's destination
    621  *
    622  *    const void *src                  (Read)
    623  *      Points to the starting address of the block of memory to copy
    624  *
    625  *    int count                        (Read)
    626  *      Specifies the size, in bytes, of the block of memory to copy
    627  *
    628  *  Return values
    629  *    Pointer of destination
    630  */
    631 
    632     memcpy( dest, src, count );
    633     return(dest);
    634 }
    635 
    636 
    637 /*===================================================================*/
    638 /*                                                                   */
    639 /*             InfoNES_MemorySet() : memset                          */
    640 /*                                                                   */
    641 /*===================================================================*/
    642 void *InfoNES_MemorySet( void *dest, int c, int count )
    643 {
    644 /*
    645  *  memset
    646  *
    647  *  Parameters
    648  *    void *dest                       (Write)
    649  *      Points to the starting address of the block of memory to fill
    650  *
    651  *    int c                            (Read)
    652  *      Specifies the byte value with which to fill the memory block
    653  *
    654  *    int count                        (Read)
    655  *      Specifies the size, in bytes, of the block of memory to fill
    656  *
    657  *  Return values
    658  *    Pointer of destination
    659  */
    660 
    661     memset( dest, c, count );
    662     return(dest);
    663 }
    664 
    665 
    666 /*===================================================================*/
    667 /*                                                                   */
    668 /*      InfoNES_LoadFrame() :                                        */
    669 /*           Transfer the contents of work frame on the screen       */
    670 /*                                                                   */
    671 /*===================================================================*/
    672 void InfoNES_LoadFrame()
    673 {
    674     #if 0
    675     int x,y;
    676     WORD wColor;
    677     for (y = 0; y < NES_DISP_HEIGHT; y++ )
    678     {
    679         for (x = 0; x < NES_DISP_WIDTH; x++ )
    680         {
    681             wColor = WorkFrame[y * NES_DISP_WIDTH  + x ];
    682             lcd_fb_display_px(wColor, x, y);
    683         }
    684     }
    685     #else
    686     int x,y;
    687     WORD wColor;
    688     for (y = 0; y < lcd_height; y++ )
    689     {
    690         for (x = 0; x < lcd_width; x++ )
    691         {
    692             wColor = WorkFrame[zoom_y_tab[y] * NES_DISP_WIDTH  + zoom_x_tab[x]];
    693             lcd_fb_display_px(wColor, x, y);
    694         }
    695     }
    696     #endif
    697 }
    698 
    699 
    700 /*===================================================================*/
    701 /*                                                                   */
    702 /*             InfoNES_PadState() : Get a joypad state               */
    703 /*                                                                   */
    704 /*===================================================================*/
    705 void InfoNES_PadState( DWORD *pdwPad1, DWORD *pdwPad2, DWORD *pdwSystem )
    706 {
    707 /*
    708  *  Get a joypad state
    709  *
    710  *  Parameters
    711  *    DWORD *pdwPad1                   (Write)
    712  *      Joypad 1 State
    713  *
    714  *    DWORD *pdwPad2                   (Write)
    715  *      Joypad 2 State
    716  *
    717  *    DWORD *pdwSystem                 (Write)
    718  *      Input for InfoNES
    719  *
    720  */
    721 
    722     /* Transfer joypad state */
    723     *pdwPad1    = dwKeyPad1;
    724     *pdwPad2    = dwKeyPad2;
    725     *pdwSystem    = dwKeySystem;
    726     
    727     dwKeyPad1 = 0;
    728 }
    729 
    730 
    731 /*===================================================================*/
    732 /*                                                                   */
    733 /*        InfoNES_SoundInit() : Sound Emulation Initialize           */
    734 /*                                                                   */
    735 /*===================================================================*/
    736 void InfoNES_SoundInit( void )
    737 {
    738     sound_fd = 0;
    739 }
    740 
    741 
    742 /*===================================================================*/
    743 /*                                                                   */
    744 /*        InfoNES_SoundOpen() : Sound Open                           */
    745 /*                                                                   */
    746 /*===================================================================*/
    747 int InfoNES_SoundOpen( int samples_per_sync, int sample_rate )
    748 {
    749     return 1;
    750 }
    751 
    752 
    753 /*===================================================================*/
    754 /*                                                                   */
    755 /*        InfoNES_SoundClose() : Sound Close                         */
    756 /*                                                                   */
    757 /*===================================================================*/
    758 void InfoNES_SoundClose( void )
    759 {
    760     if ( sound_fd )
    761     {
    762         close( sound_fd );
    763     }
    764 }
    765 
    766 
    767 /*===================================================================*/
    768 /*                                                                   */
    769 /*            InfoNES_SoundOutput() : Sound Output 5 Waves           */
    770 /*                                                                   */
    771 /*===================================================================*/
    772 void InfoNES_SoundOutput( int samples, BYTE *wave1, BYTE *wave2, BYTE *wave3, BYTE *wave4, BYTE *wave5 )
    773 {
    774     
    775 }
    776 
    777 
    778 /*===================================================================*/
    779 /*                                                                   */
    780 /*            InfoNES_Wait() : Wait Emulation if required            */
    781 /*                                                                   */
    782 /*===================================================================*/
    783 void InfoNES_Wait()
    784 {
    785 }
    786 
    787 
    788 /*===================================================================*/
    789 /*                                                                   */
    790 /*            InfoNES_MessageBox() : Print System Message            */
    791 /*                                                                   */
    792 /*===================================================================*/
    793 void InfoNES_MessageBox( char *pszMsg, ... )
    794 {
    795     printf( "MessageBox: %s 
    ", pszMsg );
    796 }
    797 
    798 
    799 /*
    800  * End of InfoNES_System_Linux.cpp
    801  */

    发另外一个高级点的放大算法 - 二次线性插值缩放算法

    发算法核心部分,原理是,取原图相邻的4个橡素,算权重。 经过测试效率非常低(每秒一两帧的样子,当然也未做优化)

     1 //得到指定位置的像素颜色
     2 static int get_pixel(unsigned short *src_fb, int x, int y, int line_len, unsigned short *color)
     3 {
     4     int src_height = NES_DISP_HEIGHT;
     5     int src_width  = NES_DISP_WIDTH;
     6     if(y>src_height || x>src_width)
     7     {
     8         *color = 0;
     9         return 0;
    10     }
    11     *color = src_fb[line_len * y + x];
    12 }
    13 
    14 static unsigned short color_avg(unsigned short color1, unsigned short color2, unsigned short color3, unsigned short color4)
    15 {
    16     unsigned short newColor;
    17     unsigned int r,g,b;
    18     //565
    19     r = ((color1>>11)&0x1f + (color2>>11)&0x1f + (color3>>11)&0x1f + (color4>>11)&0x1f)/4;
    20     g = ((color1>>5)&0x3f  + (color2>>5)&0x3f  + (color3>>5)&0x3f  + (color4>>5)&0x3f) /4;
    21     b = ((color1>>0)&0x1f  + (color2>>0)&0x1f  + (color3>>0)&0x1f  + (color4>>0)&0x1f) /4;
    22     newColor = ((r<<11) | (g<<5) | (b));
    23     return newColor;
    24 }
    25 
    26 //使用 二次线性插值 实现画面放大 
    27 //说明 目前仅支持 16bpp 的LCD 显示 
    28 //其它的还要修改兼容
    29 static void lcd_draw()
    30 {
    31     int x;
    32     int y;
    33     float srcx;
    34     float srcy;
    35     int dst_y_line;
    36     int src_height = NES_DISP_HEIGHT;
    37     int src_width  = NES_DISP_WIDTH;
    38     int dst_height = lcd_height;
    39     int dst_width  = lcd_width;
    40     unsigned short *src_fb = nes_disp_fb;
    41     unsigned short *dst_fb = zoom_disp_fb;
    42     int line_len = src_width;
    43     
    44     //Y坐标邻近的4个像素
    45     unsigned short color1;
    46     unsigned short color2;
    47     unsigned short color3;
    48     unsigned short color4;
    49 
    50     //算法说明
    51     //1,取出目标XY坐标邻近的4个像素
    52     for(y=0; y<dst_height; y++)
    53     {
    54         srcy = (y+0.49)*src_height/dst_height-0.5;
    55         srcy = int(srcy);
    56         dst_y_line = y*lcd_width;
    57         for(x=0; x<dst_width; x++)
    58         {
    59             srcx = (x+0.49)*src_width/dst_width-0.5;
    60             srcx = int(srcx);
    61             get_pixel(src_fb, srcx,   srcy,   line_len, &color1);
    62             get_pixel(src_fb, srcx,   srcy+1, line_len, &color2);
    63             get_pixel(src_fb, srcx+1, srcy,   line_len, &color3);
    64             get_pixel(src_fb, srcx+1, srcy+1, line_len, &color4);
    65             //dst_fb[dst_y_line+x] = color_avg(color1, color2, color3, color4);
    66             dst_fb[dst_y_line+x] = color1;
    67         }
    68     }
    69     //复制到 fb
    70     memcpy(fb_mem, dst_fb, screen_width);
    71 }
  • 相关阅读:
    67. Add Binary
    66. Plus One
    64. Minimum Path Sum
    63. Unique Paths II
    How to skip all the wizard pages and go directly to the installation process?
    Inno Setup打包之先卸载再安装
    How to change the header background color of a QTableView
    Openstack object list 一次最多有一万个 object
    Openstack 的 Log 在 /var/log/syslog 里 【Ubuntu】
    Git 分支
  • 原文地址:https://www.cnblogs.com/ningci/p/6755623.html
Copyright © 2020-2023  润新知