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 linux 应用程序 nes 红白机模拟器 第1篇

nes 红白机模拟器 第6篇 声音支持

arm 2440 linux 应用程序 nes 红白机模拟器 第2篇 InfoNES

arm 2440 linux 应用程序 nes 红白机模拟器 第4篇 linux 手柄驱动支持

nes 红白机模拟器 第3篇 游戏手柄测试 51 STM32

NES 系统架构