📄 wince_video.c
字号:
/* PocketCultMAME - MAME Emulator for PocketPC
(c) Copyright 2006 Manuel Castrillo Mart韓ez
Some parts of this file was licensed under MAME License terms.
Some parts of this file was ported from MAME GP2X by Franxis.
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 program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "wince_video.h"
#include "wince_util.h"
#include "wince_input.h"
#include "wince_cfg.h"
#include "vidsys.h"
#include "vidfunc.h"
#include "wince_opengl.h"
#include "driver.h"
struct osd_bitmap *scrbitmap;
unsigned char current_palette[256][3];
unsigned short palette565[256];
unsigned short palette565dark[256];
unsigned char dirtycolor[256];
int dirtypalette;
/* Graphic Display Variables */
int game_width;
int game_height;
int visible_game_width;
int visible_game_height;
int visible_game_width_offset;
int visible_game_height_offset;
int XRes;
int YRes;
int xPosCenter, yPosCenter;
long previousTickFrame = 0;
long TicksForOneSecond = 0;
int frameCount = 0;
int frameCountSecond = 0;
extern int frameskip;
extern VidSysInfo VideoInfo;
extern unsigned short * textureBitmap[];
extern int xTextureCount, yTextureCount;
extern cfgStruct GameConfig;
// Effects
typedef void (*BlitFunctionDef)( long *Source, long *Destination );
BlitFunctionDef BlitFunction;
int scanlineFlag;
/* Machine code definitions of assembly code */
#define arm_saveRegisters 0xe92d5ff0 // stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr}
#define arm_restoreReturn 0xe8bd9ff0 // ldmia sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, pc}
#define arm_clearR5 0xe3a05000 // mov r5, #0
#define arm_SrcIndexToR5 0xe5d05000 // ldrb r5, [r0, #0]
#define arm_LSL1R5 0xe1a05085 // mov r5, r5, lsl #1
#define arm_colorToR6 0xe19260b5 // ldrh r6, [r2, r5]
#define arm_colorToDest 0xe1c160b0 // strh r6, [r1]
unsigned long arm_NextPixel[] = {
0xe2811002, // add r1, r1, #2 -> Next pixel in any portrait 240
0xe2811002, // add r1, r1, #2 -> Next pixel in any portrait 480
0xe2411e1e, // sub r1, r1, #480 -> Next pixel in landscape 90cw 240x320 or 240x240
0xe2411d0f, // sub r1, r1, #960 -> Next pixel in landscapr 90cw 480x640 or 480x480
0xe2811e1e, // add r1, r1, #480 -> Next pixel in landscape 90ccw 240x320 or 240x240
0xe2811d0f, // add r1, r1, #960 -> Next pixel in landscapr 90ccw 480x640 or 480x480
};
/* Definition for the 'on the fly' blit line function */
unsigned long *ARMBlitLineDefCode;
typedef void (*ARMBlitLineDef)( long *Source, long *Destination, long *Colors );
ARMBlitLineDef ARMBlitLine;
unsigned short *LinesToBlit; // Lines to be blitted
/* Forward declarations */
void CreateARMBlitLineCode( int srcX, int srcY, int destX, int destY );
/* Blit modes */
void BlitNormal( long *Source, long *Destination );
void BlitScanlines( long *Source, long *Destination );
void BlitSteplines( long *Source, long *Destination );
///
void clearScreen(void)
{
BeginDraw();
cls();
EndDraw();
}
void osd_close_display(void)
{
if (scrbitmap)
{
osd_free_bitmap(scrbitmap);
scrbitmap = NULL;
}
}
void CreateARMBlitLineCode( int srcX, int srcY, int destX, int destY )
{
float CounterSrc, factor;
int x, y, topX, topY;
unsigned long *ARMBlitLineDefCodeWriter;
XRes = ( destX <= VideoInfo.xPixelsResolution ) ? destX : VideoInfo.xPixelsResolution;
YRes = ( destY <= VideoInfo.yPixelsResolution ) ? destY : VideoInfo.yPixelsResolution;
// *** Prepare code for horizontal blitting ***
// code size = 5instructions * 4bytes each * num pixels + 8bytes save and restore registers.
ARMBlitLineDefCode = (unsigned long *)malloc( ((5*4*destX)+8) );
ARMBlitLineDefCodeWriter = ARMBlitLineDefCode;
CounterSrc = 0;
factor = ((float)srcX / (float)destX);
*ARMBlitLineDefCodeWriter++ = arm_saveRegisters;
for( x = 0; x < XRes; x++ )
{
*ARMBlitLineDefCodeWriter++ = arm_SrcIndexToR5 + (int)CounterSrc;
*ARMBlitLineDefCodeWriter++ = arm_LSL1R5;
*ARMBlitLineDefCodeWriter++ = arm_colorToR6;
*ARMBlitLineDefCodeWriter++ = arm_colorToDest;
*ARMBlitLineDefCodeWriter++ = arm_NextPixel[ (2*VideoInfo.Rotation)+VideoInfo.displayVGA ];
CounterSrc = CounterSrc + factor;
}
*ARMBlitLineDefCodeWriter = arm_restoreReturn;
ARMBlitLine = (ARMBlitLineDef)ARMBlitLineDefCode;
// *** Calculate lines to blit ***
LinesToBlit = (unsigned short *)malloc( destY*2 );
CounterSrc = 0;
factor = ((float)srcY / (float)destY);
for( y = 0; y < YRes; y++ )
{
LinesToBlit[y] = (unsigned short)CounterSrc;
CounterSrc = CounterSrc + factor;
}
}
/* Create a bitmap. Also calls osd_clearbitmap() to appropriately initialize */
/* it to the background color. */
/* VERY IMPORTANT: the function must allocate also a "safety area" 8 pixels wide all */
/* around the bitmap. This is required because, for performance reasons, some graphic */
/* routines don't clip at boundaries of the bitmap. */
struct osd_bitmap *osd_new_bitmap(int width,int height,int depth) /* ASG 980209 */
{
struct osd_bitmap *bitmap;
if (Machine->orientation & ORIENTATION_SWAP_XY)
{
int temp;
temp = width;
width = height;
height = temp;
}
if ((bitmap = malloc(sizeof(struct osd_bitmap))) != 0)
{
int i,rowlen,rdwidth;
unsigned char *bm;
int safety;
if (width > 32) safety = 8;
else safety = 0; /* don't create the safety area for GfxElement bitmaps */
if (depth != 8 && depth != 16) depth = 8;
bitmap->depth = depth;
bitmap->width = width;
bitmap->height = height;
rdwidth = (width + 7) & ~7; /* round width to a quadword */
if (depth == 16)
rowlen = 2 * (rdwidth + 2 * safety) * sizeof(unsigned char);
else
rowlen = (rdwidth + 2 * safety) * sizeof(unsigned char);
if (!(bm = malloc((height + 2 * safety) * rowlen)))
{
writeLog("osd_new_bitmap(): Out of Memory");
free(bitmap);
return 0;
}
memset(bm,0,(height + 2 * safety) * rowlen);
if (!(bitmap->line = malloc(height * sizeof(unsigned char *))))
{
writeLog("osd_new_bitmap(): Out of Memory");
free(bm);
free(bitmap);
return 0;
}
for (i = 0;i < height;i++)
bitmap->line[i] = &bm[(i + safety) * rowlen + safety];
bitmap->_private = bm;
osd_clearbitmap(bitmap);
}
if(!bitmap)
writeLog("osd_new_bitmap(): Out of Memory");
return bitmap;
}
void osd_free_bitmap(struct osd_bitmap *bitmap)
{
if (bitmap)
{
free(bitmap->line);
free(bitmap->_private);
free(bitmap);
}
}
void osd_clearbitmap(struct osd_bitmap *bitmap)
{
}
void osd_get_pen(int pen,unsigned char *red, unsigned char *green, unsigned char *blue)
{
*red = current_palette[pen][0];
*green = current_palette[pen][1];
*blue = current_palette[pen][2];
}
void osd_modify_pen(int pen,unsigned char red, unsigned char green, unsigned char blue)
{
if (scrbitmap->depth != 8)
{
return;
}
if (current_palette[pen][0] != red ||
current_palette[pen][1] != green ||
current_palette[pen][2] != blue)
{
current_palette[pen][0] = red;
current_palette[pen][1] = green;
current_palette[pen][2] = blue;
dirtycolor[pen] = 1;
dirtypalette = 1;
}
}
/* palette is an array of 'totalcolors' R,G,B triplets. The function returns */
/* in *pens the pen values corresponding to the requested colors. */
/* If 'totalcolors' is 32768, 'palette' is ignored and the *pens array is filled */
/* with pen values corresponding to a 5-5-5 15-bit palette */
void osd_allocate_colors(unsigned int totalcolors,const unsigned char *palette,unsigned short *pens)
{
int i;
/* initialize the palette */
for (i = 0;i < 256;i++)
current_palette[i][0] = current_palette[i][1] = current_palette[i][2] = 0;
if (totalcolors >= 255)
{
int bestblack,bestwhite;
int bestblackscore,bestwhitescore;
for (i = 0;i < totalcolors;i++)
pens[i] = i;
bestblack = bestwhite = 0;
bestblackscore = 3*255*255;
bestwhitescore = 0;
for (i = 0;i < totalcolors;i++)
{
int r,g,b,score;
r = palette[3*i];
g = palette[3*i+1];
b = palette[3*i+2];
score = r*r + g*g + b*b;
if (score < bestblackscore)
{
bestblack = i;
bestblackscore = score;
}
if (score > bestwhitescore)
{
bestwhite = i;
bestwhitescore = score;
}
}
}
else
{
/* reserve color 1 for the user interface text */
current_palette[1][0] = current_palette[1][1] = current_palette[1][2] = 0xff;
/* fill the palette starting from the end, so we mess up badly written */
/* drivers which don't go through Machine->pens[] */
for (i = 0;i < totalcolors;i++)
pens[i] = 255-i;
}
for (i = 0;i < totalcolors;i++)
{
current_palette[pens[i]][0] = palette[3*i];
current_palette[pens[i]][1] = palette[3*i+1];
current_palette[pens[i]][2] = palette[3*i+2];
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -