nes 红白机模拟器 第5篇 全屏显示
Posted 宁次
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 \\r\\n"); 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 \\n"); 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 \\n"); 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 \\n"); 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\\n"); 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\\n"); 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 /*===================================================================*/以上是关于nes 红白机模拟器 第5篇 全屏显示的主要内容,如果未能解决你的问题,请参考以下文章
arm 2440 linux 应用程序 nes 红白机模拟器 第2篇 InfoNES
arm 2440 linux 应用程序 nes 红白机模拟器 第4篇 linux 手柄驱动支持