mirror of
https://github.com/dborth/fceugx.git
synced 2025-01-07 14:28:18 +01:00
FCE Ultra code base cleanup
This commit is contained in:
parent
fe0b937cd6
commit
2032df6465
@ -27,7 +27,6 @@
|
||||
#include "ppu.h"
|
||||
|
||||
#include "cart.h"
|
||||
#include "memory.h"
|
||||
#include "x6502.h"
|
||||
|
||||
#include "general.h"
|
||||
@ -442,7 +441,7 @@ void OpenGenie(void)
|
||||
{
|
||||
char *fn;
|
||||
|
||||
if(!(GENIEROM=(uint8 *)FCEU_malloc(4096+1024))) return;
|
||||
if(!(GENIEROM=(uint8 *)malloc(4096+1024))) return;
|
||||
|
||||
fn=FCEU_MakeFName(FCEUMKF_GGROM,0,0);
|
||||
fp=FCEUD_UTF8fopen(fn,"rb");
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include "fceu.h"
|
||||
#include "general.h"
|
||||
#include "cart.h"
|
||||
#include "memory.h"
|
||||
|
||||
static uint8 *CheatRPtrs[64];
|
||||
|
||||
|
@ -1,520 +0,0 @@
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2003 Xodnizel
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "x6502.h"
|
||||
#include "fceu.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
|
||||
void FCEUI_DumpMem(const char *fname, uint32 start, uint32 end)
|
||||
{
|
||||
FILE *fp=FCEUD_UTF8fopen(fname,"wb");
|
||||
fceuindbg=1;
|
||||
for(;start<=end;start++)
|
||||
fputc(ARead[start](start),fp);
|
||||
fclose(fp);
|
||||
fceuindbg=0;
|
||||
}
|
||||
|
||||
void FCEUI_LoadMem(const char *fname, uint32 start, int hl)
|
||||
{
|
||||
int t;
|
||||
|
||||
FILE *fp=FCEUD_UTF8fopen(fname,"rb");
|
||||
while((t=fgetc(fp))>=0)
|
||||
{
|
||||
if(start>0xFFFF) break;
|
||||
if(hl)
|
||||
{
|
||||
extern uint8 *Page[32];
|
||||
if(Page[start/2048])
|
||||
Page[start/2048][start]=t;
|
||||
}
|
||||
else
|
||||
BWrite[start](start,t);
|
||||
start++;
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
static char *fstrings[12]=
|
||||
{
|
||||
"#$%02X", // immediate
|
||||
"$%04X", // RELATIVE(jump)
|
||||
"$%02X", // Z
|
||||
"$%02X,X", // Z,x
|
||||
"$%02X,Y", // Z,y
|
||||
"$%04X", //ABS
|
||||
"$%04X,X", // ABS,x
|
||||
"$%04X,Y", // ABS,y
|
||||
"($%04X)", // IND
|
||||
"($%02X,X)", // INX
|
||||
"($%02X),Y", // INY
|
||||
""
|
||||
};
|
||||
static int flengths[12]={1,1,1,1,1,2,2,2,2,1,1,0};
|
||||
|
||||
#define IMD(x) ((0<<16)|x)
|
||||
#define REL(x) ((1<<16)|x)
|
||||
#define ZP(x) ((2<<16)|x)
|
||||
#define ZPX(x) ((3<<16)|x)
|
||||
#define ZPY(x) ((4<<16)|x)
|
||||
#define ABS(x) ((5<<16)|x)
|
||||
#define ABX(x) ((6<<16)|x)
|
||||
#define ABY(x) ((7<<16)|x)
|
||||
#define IND(x) ((8<<16)|x)
|
||||
#define INX(x) ((9<<16)|x)
|
||||
#define INY(x) ((10<<16)|x)
|
||||
#define IMP(x) ((11<<16)|x)
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
int type; /* 1 for read, 2 for write, 3 for r then write. */
|
||||
int32 modes[10];
|
||||
} OPS;
|
||||
#define NUMOPS 56
|
||||
static OPS optable[NUMOPS]=
|
||||
{
|
||||
{"BRK",0,{IMP(0x00),-1}},
|
||||
{"RTI",0,{IMP(0x40),-1}},
|
||||
{"RTS",0,{IMP(0x60),-1}},
|
||||
{"PHA",2,{IMP(0x48),-1}},
|
||||
{"PHP",2,{IMP(0x08),-1}},
|
||||
{"PLA",1,{IMP(0x68),-1}},
|
||||
{"PLP",1,{IMP(0x28),-1}},
|
||||
{"JMP",0,{ABS(0x4C),IND(0x6C),-1}},
|
||||
{"JSR",0,{ABS(0x20),-1}},
|
||||
{"TAX",0,{IMP(0xAA),-1}},
|
||||
{"TXA",0,{IMP(0x8A),-1}},
|
||||
{"TAY",0,{IMP(0xA8),-1}},
|
||||
{"TYA",0,{IMP(0x98),-1}},
|
||||
{"TSX",0,{IMP(0xBA),-1}},
|
||||
{"TXS",0,{IMP(0x9A),-1}},
|
||||
{"DEX",0,{IMP(0xCA),-1}},
|
||||
{"DEY",0,{IMP(0x88),-1}},
|
||||
{"INX",0,{IMP(0xE8),-1}},
|
||||
{"INY",0,{IMP(0xC8),-1}},
|
||||
{"CLC",0,{IMP(0x18),-1}},
|
||||
{"CLD",0,{IMP(0xD8),-1}},
|
||||
{"CLI",0,{IMP(0x58),-1}},
|
||||
{"CLV",0,{IMP(0xB8),-1}},
|
||||
{"SEC",0,{IMP(0x38),-1}},
|
||||
{"SED",0,{IMP(0xF8),-1}},
|
||||
{"SEI",0,{IMP(0x78),-1}},
|
||||
{"NOP",0,{IMP(0xEA),-1}},
|
||||
{"ASL",1,{IMP(0x0a),ZP(0x06),ZPX(0x16),ABS(0x0E),ABX(0x1E),-1}},
|
||||
{"DEC",3,{ZP(0xc6),ZPX(0xd6),ABS(0xcE),ABX(0xdE),-1}},
|
||||
{"INC",3,{ZP(0xe6),ZPX(0xf6),ABS(0xeE),ABX(0xfE),-1}},
|
||||
{"LSR",3,{IMP(0x4a),ZP(0x46),ZPX(0x56),ABS(0x4E),ABX(0x5E),-1}},
|
||||
{"ROL",3,{IMP(0x2a),ZP(0x26),ZPX(0x36),ABS(0x2E),ABX(0x3E),-1}},
|
||||
{"ROR",3,{IMP(0x6a),ZP(0x66),ZPX(0x76),ABS(0x6E),ABX(0x7E),-1}},
|
||||
{"ADC",1,{IMD(0x69),ZP(0x65),ZPX(0x75),ABS(0x6D),ABX(0x7d),ABY(0x79),
|
||||
INX(0x61),INY(0x71),-1}},
|
||||
{"AND",1,{IMD(0x29),ZP(0x25),ZPX(0x35),ABS(0x2D),ABX(0x3d),ABY(0x39),
|
||||
INX(0x21),INY(0x31),-1}},
|
||||
{"BIT",1,{ZP(0x24),ABS(0x2c),-1}},
|
||||
{"CMP",1,{IMD(0xc9),ZP(0xc5),ZPX(0xd5),ABS(0xcD),ABX(0xdd),ABY(0xd9),
|
||||
INX(0xc1),INY(0xd1),-1}},
|
||||
{"CPX",1,{IMD(0xe0),ZP(0xe4),ABS(0xec),-1}},
|
||||
{"CPY",1,{IMD(0xc0),ZP(0xc4),ABS(0xcc),-1}},
|
||||
{"EOR",1,{IMD(0x49),ZP(0x45),ZPX(0x55),ABS(0x4D),ABX(0x5d),ABY(0x59),
|
||||
INX(0x41),INY(0x51),-1}},
|
||||
{"LDA",1,{IMD(0xa9),ZP(0xa5),ZPX(0xb5),ABS(0xaD),ABX(0xbd),ABY(0xb9),
|
||||
INX(0xa1),INY(0xb1),-1}},
|
||||
{"LDX",1,{IMD(0xa2),ZP(0xa6),ZPY(0xB6),ABS(0xae),ABY(0xbe),-1}},
|
||||
{"LDY",1,{IMD(0xa0),ZP(0xa4),ZPX(0xB4),ABS(0xac),ABX(0xbc),-1}},
|
||||
{"ORA",1,{IMD(0x09),ZP(0x05),ZPX(0x15),ABS(0x0D),ABX(0x1d),ABY(0x19),
|
||||
INX(0x01),INY(0x11),-1}},
|
||||
{"SBC",1,{IMD(0xEB),IMD(0xe9),ZP(0xe5),ZPX(0xf5),ABS(0xeD),ABX(0xfd),ABY(0xf9),
|
||||
INX(0xe1),INY(0xf1),-1}},
|
||||
{"STA",2,{ZP(0x85),ZPX(0x95),ABS(0x8D),ABX(0x9d),ABY(0x99),
|
||||
INX(0x81),INY(0x91),-1}},
|
||||
{"STX",2,{ZP(0x86),ZPY(0x96),ABS(0x8E),-1}},
|
||||
{"STY",2,{ZP(0x84),ZPX(0x94),ABS(0x8C),-1}},
|
||||
{"BCC",1,{REL(0x90),-1}},
|
||||
{"BCS",1,{REL(0xb0),-1}},
|
||||
{"BEQ",1,{REL(0xf0),-1}},
|
||||
{"BNE",1,{REL(0xd0),-1}},
|
||||
{"BMI",1,{REL(0x30),-1}},
|
||||
{"BPL",1,{REL(0x10),-1}},
|
||||
{"BVC",1,{REL(0x50),-1}},
|
||||
{"BVS",1,{REL(0x70),-1}},
|
||||
};
|
||||
|
||||
uint16 FCEUI_Disassemble(void *XA, uint16 a, char *stringo)
|
||||
{
|
||||
X6502 *X=XA;
|
||||
uint8 buf;
|
||||
unsigned int arg;
|
||||
int32 info;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
info=-1;
|
||||
fceuindbg=1;
|
||||
|
||||
buf=ARead[a](a);
|
||||
a++;
|
||||
|
||||
for(x=0;x<NUMOPS;x++)
|
||||
{
|
||||
y=0;
|
||||
while(optable[x].modes[y]>=0)
|
||||
{
|
||||
if((optable[x].modes[y]&0xFF)==buf)
|
||||
{
|
||||
info=optable[x].modes[y];
|
||||
goto endy;
|
||||
}
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
endy:
|
||||
sprintf(stringo,"%02X ",buf);
|
||||
if(info>=0)
|
||||
{
|
||||
int z=flengths[(info>>16)];
|
||||
|
||||
if(z)
|
||||
{
|
||||
arg=ARead[a](a);
|
||||
sprintf(stringo+strlen(stringo),"%02X ",arg);
|
||||
a++;
|
||||
if(z==2) {arg|=ARead[a](a)<<8;sprintf(stringo+strlen(stringo),"%02X ",arg>>8);a++;}
|
||||
else
|
||||
strcat(stringo," ");
|
||||
|
||||
if((info>>16)==1) /* Relative branch */
|
||||
arg=a+(char)arg;
|
||||
sprintf(stringo+strlen(stringo),"%s ",optable[x].name);
|
||||
sprintf(stringo+strlen(stringo),fstrings[info>>16],arg);
|
||||
/*
|
||||
0 "#$%02X", // immediate
|
||||
1 "$%04X", // RELATIVE(jump)
|
||||
2 "$%02X", // Z
|
||||
3 "$%02X,X", // Z,x
|
||||
4 "$%02X,Y", // Z,y
|
||||
5 "$%04X", //ABS
|
||||
6 "$%04X,X", // ABS,x
|
||||
7 "$%04X,Y", // ABS,y
|
||||
8 "($%04X)", // IND
|
||||
9 "($%02X,X)", // INX
|
||||
10 "($%02X),Y", // INY
|
||||
11 #define IMP(x) ((11<<16)|x)
|
||||
*/
|
||||
{
|
||||
unsigned int tmp;
|
||||
switch(info>>16)
|
||||
{
|
||||
case 2:tmp=arg;
|
||||
if(optable[x].type&1)
|
||||
{
|
||||
sprintf(stringo+strlen(stringo)," @ $%04X",tmp);
|
||||
sprintf(stringo+strlen(stringo)," = $%02X",ARead[tmp](tmp));
|
||||
}
|
||||
break;
|
||||
case 3:tmp=(arg+X->X)&0xff;
|
||||
sprintf(stringo+strlen(stringo)," @ $%04X",tmp);
|
||||
if(optable[x].type&1)
|
||||
sprintf(stringo+strlen(stringo)," = $%02X",ARead[tmp](tmp));
|
||||
break;
|
||||
case 4:tmp=(arg+X->Y)&0xff;
|
||||
sprintf(stringo+strlen(stringo)," @ $%04X",tmp);
|
||||
if(optable[x].type&1)
|
||||
sprintf(stringo+strlen(stringo)," = $%02X",ARead[tmp](tmp));
|
||||
break;
|
||||
case 5:tmp=arg;
|
||||
if(optable[x].type&1)
|
||||
{
|
||||
sprintf(stringo+strlen(stringo)," @ $%04X",tmp);
|
||||
sprintf(stringo+strlen(stringo)," = $%02X",ARead[tmp](tmp));
|
||||
}
|
||||
break;
|
||||
case 6:tmp=(arg+X->X)&0xffff;
|
||||
sprintf(stringo+strlen(stringo)," @ $%04X",tmp);
|
||||
if(optable[x].type&1)
|
||||
sprintf(stringo+strlen(stringo)," = $%02X",ARead[tmp](tmp));
|
||||
break;
|
||||
case 7:tmp=(arg+X->Y)&0xffff;
|
||||
sprintf(stringo+strlen(stringo)," @ $%04X",tmp);
|
||||
if(optable[x].type&1)
|
||||
sprintf(stringo+strlen(stringo)," = $%02X",ARead[tmp](tmp));
|
||||
break;
|
||||
case 8:tmp=ARead[arg](arg)|(ARead[(arg+1)&0xffff]((arg+1)&0xffff)<<8);
|
||||
sprintf(stringo+strlen(stringo)," $%04X",tmp);
|
||||
break;
|
||||
case 9:tmp=(arg+X->X)&0xFF;
|
||||
tmp=ARead[tmp](tmp) | (ARead[(tmp+1)&0xFF]((tmp+1)&0xFF)<<8);
|
||||
sprintf(stringo+strlen(stringo)," @ $%04X",tmp);
|
||||
if(optable[x].type&1)
|
||||
sprintf(stringo+strlen(stringo)," = $%02X",ARead[tmp](tmp));
|
||||
break;
|
||||
case 10:tmp=ARead[arg](arg) | (ARead[(arg+1)&0xFF]((arg+1)&0xFF)<<8);
|
||||
tmp=(tmp+X->Y)&0xFFFF;
|
||||
sprintf(stringo+strlen(stringo)," @ $%04X",tmp);
|
||||
if(optable[x].type&1)
|
||||
sprintf(stringo+strlen(stringo)," = $%02X",ARead[tmp](tmp));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat(stringo," ");
|
||||
strcat(stringo,optable[x].name);
|
||||
}
|
||||
}
|
||||
else
|
||||
sprintf(stringo+strlen(stringo)," .db $%02X",buf);
|
||||
fceuindbg=0;
|
||||
return(a);
|
||||
}
|
||||
|
||||
void FCEUI_MemDump(uint16 a, int32 len, void (*callb)(uint16 a, uint8 v))
|
||||
{
|
||||
fceuindbg=1;
|
||||
while(len)
|
||||
{
|
||||
callb(a,ARead[a](a));
|
||||
a++;
|
||||
len--;
|
||||
}
|
||||
fceuindbg=0;
|
||||
}
|
||||
|
||||
uint8 FCEUI_MemSafePeek(uint16 A)
|
||||
{
|
||||
uint8 ret;
|
||||
|
||||
fceuindbg=1;
|
||||
ret=ARead[A](A);
|
||||
fceuindbg=0;
|
||||
return(ret);
|
||||
}
|
||||
|
||||
void FCEUI_MemPoke(uint16 a, uint8 v, int hl)
|
||||
{
|
||||
extern uint8 *Page[32];
|
||||
if(hl)
|
||||
{
|
||||
if(Page[a/2048])
|
||||
Page[a/2048][a]=v;
|
||||
}
|
||||
else
|
||||
BWrite[a](a,v);
|
||||
}
|
||||
|
||||
typedef struct __BPOINT {
|
||||
struct __BPOINT *next;
|
||||
void (*Handler)(X6502 *X, int type, unsigned int A);
|
||||
unsigned int A[2];
|
||||
int type;
|
||||
} BPOINT;
|
||||
|
||||
static BPOINT *BreakPoints=NULL;
|
||||
static BPOINT *LastBP=NULL;
|
||||
|
||||
static void (*CPUHook)(X6502 *)=NULL;
|
||||
|
||||
static int FindBPoint(X6502 *X, int who, unsigned int A)
|
||||
{
|
||||
BPOINT *tmp;
|
||||
|
||||
tmp=BreakPoints;
|
||||
while(tmp)
|
||||
{
|
||||
if(tmp->type&who)
|
||||
{
|
||||
if(tmp->type&BPOINT_PC)
|
||||
if(X->PC!=A) goto don; /* Doesn't match, so go on. */
|
||||
|
||||
if((A>=tmp->A[0]) && (A<=tmp->A[1])) /* Whee, match. */
|
||||
{
|
||||
tmp->Handler(X,tmp->type,A);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
don:
|
||||
tmp=tmp->next;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
static uint8 ReadHandler(X6502 *X, unsigned int A)
|
||||
{
|
||||
extern X6502 XSave;
|
||||
|
||||
if(X->preexec)
|
||||
FindBPoint(&XSave,BPOINT_READ,A);
|
||||
return(ARead[A](A));
|
||||
}
|
||||
|
||||
static void WriteHandler(X6502 *X, unsigned int A, uint8 V)
|
||||
{
|
||||
extern X6502 XSave;
|
||||
|
||||
if(X->preexec)
|
||||
FindBPoint(&XSave,BPOINT_WRITE,A);
|
||||
else
|
||||
BWrite[A](A,V);
|
||||
}
|
||||
|
||||
int FCEUI_AddBreakPoint(int type, unsigned int A1, unsigned int A2,
|
||||
void (*Handler)(X6502 *, int type, unsigned int A))
|
||||
{
|
||||
BPOINT *tmp;
|
||||
|
||||
tmp=(BPOINT *)malloc(sizeof(BPOINT));
|
||||
|
||||
tmp->A[0]=A1;
|
||||
tmp->A[1]=A2;
|
||||
tmp->Handler=Handler;
|
||||
tmp->type=type;
|
||||
tmp->next=0;
|
||||
|
||||
if(BreakPoints==NULL)
|
||||
BreakPoints=tmp;
|
||||
else
|
||||
LastBP->next=tmp;
|
||||
|
||||
LastBP=tmp;
|
||||
|
||||
X6502_Debug(CPUHook,ReadHandler,WriteHandler);
|
||||
return(1);
|
||||
}
|
||||
|
||||
int FCEUI_SetBreakPoint(uint32 w, int type, unsigned int A1, unsigned int A2,
|
||||
void (*Handler)(X6502 *, int type, unsigned int A))
|
||||
{
|
||||
uint32 x=0;
|
||||
BPOINT *tmp;
|
||||
|
||||
tmp=BreakPoints;
|
||||
|
||||
while(tmp)
|
||||
{
|
||||
if(w==x)
|
||||
{
|
||||
tmp->type=type;
|
||||
tmp->A[0]=A1;
|
||||
tmp->A[1]=A2;
|
||||
tmp->Handler=Handler;
|
||||
return(1);
|
||||
}
|
||||
x++;
|
||||
tmp=tmp->next;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int FCEUI_GetBreakPoint(uint32 w, int *type, unsigned int *A1, unsigned int *A2,
|
||||
void (**Handler)(X6502 *, int type, unsigned int A))
|
||||
{
|
||||
uint32 x=0;
|
||||
BPOINT *tmp;
|
||||
|
||||
tmp=BreakPoints;
|
||||
|
||||
while(tmp)
|
||||
{
|
||||
if(w==x)
|
||||
{
|
||||
*type=tmp->type;
|
||||
*A1=tmp->A[0];
|
||||
*A2=tmp->A[1];
|
||||
*Handler=tmp->Handler;
|
||||
return(1);
|
||||
}
|
||||
x++;
|
||||
tmp=tmp->next;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int FCEUI_ListBreakPoints(int (*callb)(int type, unsigned int A1, unsigned int A2,
|
||||
void (*Handler)(X6502 *, int type, unsigned int A) ))
|
||||
{
|
||||
BPOINT *tmp;
|
||||
tmp=BreakPoints;
|
||||
while(tmp)
|
||||
{
|
||||
callb(tmp->type,tmp->A[0],tmp->A[1],tmp->Handler);
|
||||
tmp=tmp->next;
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
int FCEUI_DeleteBreakPoint(uint32 w)
|
||||
{
|
||||
BPOINT *tmp,*prev=NULL;
|
||||
uint32 x=0;
|
||||
|
||||
tmp=BreakPoints;
|
||||
|
||||
while(tmp)
|
||||
{
|
||||
if(w==x)
|
||||
{
|
||||
if(prev) /* Not the first breakpoint. */
|
||||
{
|
||||
if(tmp->next) /* More breakpoints. */
|
||||
prev->next=tmp->next;
|
||||
else /* This is the last breakpoint. */
|
||||
{
|
||||
prev->next=0;
|
||||
LastBP=prev;
|
||||
}
|
||||
}
|
||||
else /* The first breakpoint. */
|
||||
{
|
||||
if(tmp->next) /* More breakpoints. */
|
||||
BreakPoints=tmp->next;
|
||||
else
|
||||
{
|
||||
BreakPoints=LastBP=0; /* No more breakpoints. */
|
||||
/* Update the CPU hooks. */
|
||||
X6502_Debug(CPUHook,BreakPoints?ReadHandler:0,BreakPoints?WriteHandler:0);
|
||||
}
|
||||
}
|
||||
free(tmp);
|
||||
return(1);
|
||||
}
|
||||
prev=tmp;
|
||||
tmp=tmp->next;
|
||||
x++;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
void FCEUI_SetCPUCallback(void (*callb)(X6502 *X))
|
||||
{
|
||||
CPUHook=callb;
|
||||
X6502_Debug(CPUHook,BreakPoints?ReadHandler:0,BreakPoints?WriteHandler:0);
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
|
||||
/* Type attributes, you can OR them together. */
|
||||
#define BPOINT_READ 1
|
||||
#define BPOINT_WRITE 2
|
||||
#define BPOINT_PC 4
|
||||
|
||||
#include "x6502struct.h"
|
||||
|
||||
void FCEUI_DumpMem(const char *fname, uint32 start, uint32 end);
|
||||
void FCEUI_LoadMem(const char *fname, uint32 start, int hl);
|
||||
void FCEUI_SetCPUCallback(void (*callb)(X6502 *X));
|
||||
int FCEUI_DeleteBreakPoint(uint32 w);
|
||||
int FCEUI_ListBreakPoints(int (*callb)(int type, unsigned int A1, unsigned int A2,
|
||||
void (*Handler)(X6502 *, int type, unsigned int A) ));
|
||||
int FCEUI_GetBreakPoint(uint32 w, int *type, unsigned int *A1, unsigned int *A2,
|
||||
void (**Handler)(X6502 *, int type, unsigned int A));
|
||||
int FCEUI_SetBreakPoint(uint32 w, int type, unsigned int A1, unsigned int A2,
|
||||
void (*Handler)(X6502 *, int type, unsigned int A));
|
||||
int FCEUI_AddBreakPoint(int type, unsigned int A1, unsigned int A2,
|
||||
void (*Handler)(X6502 *, int type, unsigned int A));
|
@ -1,98 +0,0 @@
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/****************************************************************/
|
||||
/* FCE Ultra */
|
||||
/* */
|
||||
/* This file contains code for parsing command-line */
|
||||
/* options. */
|
||||
/* */
|
||||
/****************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../../types.h"
|
||||
#include "args.h"
|
||||
|
||||
void ParseEA(int x, int argc, char *argv[], ARGPSTRUCT *argsps)
|
||||
{
|
||||
int y=0;
|
||||
|
||||
do
|
||||
{
|
||||
if(!argsps[y].name)
|
||||
{
|
||||
ParseEA(x,argc,argv,(ARGPSTRUCT*)argsps[y].var);
|
||||
y++;
|
||||
continue;
|
||||
}
|
||||
if(!strcmp(argv[x],argsps[y].name)) // A match.
|
||||
{
|
||||
if(argsps[y].subs)
|
||||
{
|
||||
if((x+1)>=argc)
|
||||
break;
|
||||
if(argsps[y].substype&0x2000)
|
||||
{
|
||||
((void (*)(char *))argsps[y].subs)(argv[x+1]);
|
||||
}
|
||||
else if(argsps[y].substype&0x8000)
|
||||
{
|
||||
*(int *)argsps[y].subs&=~(argsps[y].substype&(~0x8000));
|
||||
*(int *)argsps[y].subs|=atoi(argv[x+1])?(argsps[y].substype&(~0x8000)):0;
|
||||
}
|
||||
else
|
||||
switch(argsps[y].substype&(~0x4000))
|
||||
{
|
||||
case 0: // Integer
|
||||
*(int *)argsps[y].subs=atoi(argv[x+1]);
|
||||
break;
|
||||
case 2: // Double float
|
||||
*(double *)argsps[y].subs=atof(argv[x+1]);
|
||||
break;
|
||||
case 1: // String
|
||||
if(argsps[y].substype&0x4000)
|
||||
{
|
||||
if(*(char **)argsps[y].subs)
|
||||
free(*(char **)argsps[y].subs);
|
||||
if(!( *(char **)argsps[y].subs=(char*)malloc(strlen(argv[x+1])+1) ))
|
||||
break;
|
||||
}
|
||||
strcpy(*(char **)argsps[y].subs,argv[x+1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(argsps[y].var)
|
||||
*argsps[y].var=1;
|
||||
}
|
||||
y++;
|
||||
} while(argsps[y].var || argsps[y].subs);
|
||||
}
|
||||
|
||||
void ParseArguments(int argc, char *argv[], ARGPSTRUCT *argsps)
|
||||
{
|
||||
int x;
|
||||
|
||||
for(x=0;x<argc;x++)
|
||||
ParseEA(x,argc,argv,argsps);
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
#ifndef _DRIVERS_ARGH
|
||||
typedef struct {
|
||||
char *name;
|
||||
int *var;
|
||||
|
||||
void *subs;
|
||||
int substype;
|
||||
} ARGPSTRUCT;
|
||||
|
||||
void ParseArguments(int argc, char *argv[], ARGPSTRUCT *argsps);
|
||||
#define _DRIVERS_ARGH
|
||||
#endif
|
@ -1,523 +0,0 @@
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include "../../driver.h"
|
||||
|
||||
static void GetString(char *s, int max)
|
||||
{
|
||||
int x;
|
||||
fgets(s,max,stdin);
|
||||
|
||||
for(x=0;x<max;x++)
|
||||
if(s[x]=='\n')
|
||||
{
|
||||
s[x]=0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get unsigned 16-bit integer from stdin in hex. */
|
||||
static uint32 GetH16(unsigned int def)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
fgets(buf,32,stdin);
|
||||
if(buf[0]=='\n')
|
||||
return(def);
|
||||
if(buf[0]=='$')
|
||||
sscanf(buf+1,"%04x",&def);
|
||||
else
|
||||
sscanf(buf,"%04x",&def);
|
||||
return def;
|
||||
}
|
||||
|
||||
/* Get unsigned 8-bit integer from stdin in decimal. */
|
||||
static uint8 Get8(unsigned int def)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
fgets(buf,32,stdin);
|
||||
if(buf[0]=='\n')
|
||||
return(def);
|
||||
sscanf(buf,"%u",&def);
|
||||
return def;
|
||||
}
|
||||
|
||||
static int GetI(int def)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
fgets(buf,32,stdin);
|
||||
if(buf[0]=='\n')
|
||||
return(def);
|
||||
sscanf(buf,"%d",&def);
|
||||
return def;
|
||||
}
|
||||
|
||||
static int GetYN(int def)
|
||||
{
|
||||
char buf[32];
|
||||
printf("(Y/N)[%s]: ",def?"Y":"N");
|
||||
fgets(buf,32,stdin);
|
||||
if(buf[0]=='y' || buf[0]=='Y')
|
||||
return(1);
|
||||
if(buf[0]=='n' || buf[0]=='N')
|
||||
return(0);
|
||||
return(def);
|
||||
}
|
||||
|
||||
/*
|
||||
** Begin list code.
|
||||
**
|
||||
*/
|
||||
static int listcount;
|
||||
static int listids[16];
|
||||
static int listsel;
|
||||
static int mordoe;
|
||||
|
||||
void BeginListShow(void)
|
||||
{
|
||||
listcount=0;
|
||||
listsel=-1;
|
||||
mordoe=0;
|
||||
}
|
||||
|
||||
/* Hmm =0 for in list choices, hmm=1 for end of list choices. */
|
||||
/* Return equals 0 to continue, -1 to stop, otherwise a number. */
|
||||
int ListChoice(int hmm)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
if(!hmm)
|
||||
{
|
||||
int num=0;
|
||||
|
||||
tryagain:
|
||||
printf(" <'Enter' to continue, (S)top, or enter a number.> ");
|
||||
fgets(buf,32,stdin);
|
||||
if(buf[0]=='s' || buf[0]=='S') return(-1);
|
||||
if(buf[0]=='\n') return(0);
|
||||
if(!sscanf(buf,"%d",&num))
|
||||
return(0);
|
||||
if(num<1) goto tryagain;
|
||||
return(num);
|
||||
}
|
||||
else
|
||||
{
|
||||
int num=0;
|
||||
|
||||
tryagain2:
|
||||
printf(" <'Enter' to make no selection or enter a number.> ");
|
||||
fgets(buf,32,stdin);
|
||||
if(buf[0]=='\n') return(0);
|
||||
if(!sscanf(buf,"%d",&num))
|
||||
return(0);
|
||||
if(num<1) goto tryagain2;
|
||||
return(num);
|
||||
}
|
||||
}
|
||||
|
||||
int EndListShow(void)
|
||||
{
|
||||
if(mordoe)
|
||||
{
|
||||
int r=ListChoice(1);
|
||||
if(r>0 && r<=listcount)
|
||||
listsel=listids[r-1];
|
||||
}
|
||||
return(listsel);
|
||||
}
|
||||
|
||||
/* Returns 0 to stop listing, 1 to continue. */
|
||||
int AddToList(char *text, uint32 id)
|
||||
{
|
||||
if(listcount==16)
|
||||
{
|
||||
int t=ListChoice(0);
|
||||
mordoe=0;
|
||||
if(t==-1) return(0); // Stop listing.
|
||||
else if(t>0 && t<17)
|
||||
{
|
||||
listsel=listids[t-1];
|
||||
return(0);
|
||||
}
|
||||
listcount=0;
|
||||
}
|
||||
mordoe=1;
|
||||
listids[listcount]=id;
|
||||
printf("%2d) %s\n",listcount+1,text);
|
||||
listcount++;
|
||||
return(1);
|
||||
}
|
||||
|
||||
/*
|
||||
**
|
||||
** End list code.
|
||||
**/
|
||||
|
||||
typedef struct MENU {
|
||||
char *text;
|
||||
void *action;
|
||||
int type; // 0 for menu, 1 for function.
|
||||
} MENU;
|
||||
|
||||
static void SetOC(void)
|
||||
{
|
||||
FCEUI_CheatSearchSetCurrentAsOriginal();
|
||||
}
|
||||
|
||||
static void UnhideEx(void)
|
||||
{
|
||||
FCEUI_CheatSearchShowExcluded();
|
||||
}
|
||||
|
||||
static void ToggleCheat(int num)
|
||||
{
|
||||
printf("Cheat %d %sabled.\n",1+num,
|
||||
FCEUI_ToggleCheat(num)?"en":"dis");
|
||||
}
|
||||
|
||||
static void ModifyCheat(int num)
|
||||
{
|
||||
char *name;
|
||||
char buf[256];
|
||||
uint32 A;
|
||||
uint8 V;
|
||||
int compare;
|
||||
int type;
|
||||
|
||||
int s;
|
||||
int t;
|
||||
|
||||
FCEUI_GetCheat(num, &name, &A, &V, &compare, &s, &type);
|
||||
|
||||
printf("Name [%s]: ",name);
|
||||
GetString(buf,256);
|
||||
|
||||
/* This obviously doesn't allow for cheats with no names. Bah. Who wants
|
||||
nameless cheats anyway...
|
||||
*/
|
||||
|
||||
if(buf[0])
|
||||
name=buf; // Change name when FCEUI_SetCheat() is called.
|
||||
else
|
||||
name=0; // Don't change name when FCEUI_SetCheat() is called.
|
||||
|
||||
printf("Address [$%04x]: ",(unsigned int)A);
|
||||
A=GetH16(A);
|
||||
|
||||
printf("Value [%03d]: ",(unsigned int)V);
|
||||
V=Get8(V);
|
||||
|
||||
printf("Compare [%3d]: ",compare);
|
||||
compare=GetI(compare);
|
||||
|
||||
printf("Type(0=Old Style, 1=Read Substitute) [%1d]: ",type);
|
||||
type=GetI(type)?1:0;
|
||||
|
||||
printf("Enable [%s]: ",s?"Y":"N");
|
||||
t=getchar();
|
||||
if(t=='Y' || t=='y') s=1;
|
||||
else if(t=='N' || t=='n') s=0;
|
||||
|
||||
FCEUI_SetCheat(num,name,A,V,compare,s,type);
|
||||
}
|
||||
|
||||
|
||||
static void AddCheatGGPAR(int which)
|
||||
{
|
||||
uint16 A;
|
||||
uint8 V;
|
||||
int C;
|
||||
int type;
|
||||
char name[256],code[256];
|
||||
|
||||
printf("Name: ");
|
||||
GetString(name,256);
|
||||
|
||||
printf("Code: ");
|
||||
GetString(code,256);
|
||||
|
||||
printf("Add cheat \"%s\" for code \"%s\"?",name,code);
|
||||
if(GetYN(0))
|
||||
{
|
||||
if(which)
|
||||
{
|
||||
if(!FCEUI_DecodePAR(code,&A,&V,&C,&type))
|
||||
{
|
||||
puts("Invalid Game Genie code.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!FCEUI_DecodeGG(code,&A,&V,&C))
|
||||
{
|
||||
puts("Invalid Game Genie code.");
|
||||
return;
|
||||
}
|
||||
type=1;
|
||||
}
|
||||
|
||||
if(FCEUI_AddCheat(name,A,V,C,type))
|
||||
puts("Cheat added.");
|
||||
else
|
||||
puts("Error adding cheat.");
|
||||
}
|
||||
}
|
||||
|
||||
static void AddCheatGG(void)
|
||||
{
|
||||
AddCheatGGPAR(0);
|
||||
}
|
||||
|
||||
static void AddCheatPAR(void)
|
||||
{
|
||||
AddCheatGGPAR(1);
|
||||
}
|
||||
|
||||
static void AddCheatParam(uint32 A, uint8 V)
|
||||
{
|
||||
char name[256];
|
||||
|
||||
printf("Name: ");
|
||||
GetString(name,256);
|
||||
printf("Address [$%04x]: ",(unsigned int)A);
|
||||
A=GetH16(A);
|
||||
printf("Value [%03d]: ",(unsigned int)V);
|
||||
V=Get8(V);
|
||||
printf("Add cheat \"%s\" for address $%04x with value %03d?",name,(unsigned int)A,(unsigned int)V);
|
||||
if(GetYN(0))
|
||||
{
|
||||
if(FCEUI_AddCheat(name,A,V,-1,0))
|
||||
puts("Cheat added.");
|
||||
else
|
||||
puts("Error adding cheat.");
|
||||
}
|
||||
}
|
||||
|
||||
static void AddCheat(void)
|
||||
{
|
||||
AddCheatParam(0,0);
|
||||
}
|
||||
|
||||
static int lid;
|
||||
static int clistcallb(char *name, uint32 a, uint8 v, int compare, int s, int type, void *data)
|
||||
{
|
||||
char tmp[512];
|
||||
int ret;
|
||||
|
||||
if(compare>=0)
|
||||
sprintf(tmp,"%s $%04x:%03d:%03d - %s",s?"*":" ",(unsigned int)a,(unsigned int)v,compare,name);
|
||||
else
|
||||
sprintf(tmp,"%s $%04x:%03d - %s",s?"*":" ",(unsigned int)a,(unsigned int)v,name);
|
||||
if(type==1)
|
||||
tmp[2]='S';
|
||||
ret=AddToList(tmp,lid);
|
||||
lid++;
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static void ListCheats(void)
|
||||
{
|
||||
int which;
|
||||
lid=0;
|
||||
|
||||
BeginListShow();
|
||||
FCEUI_ListCheats(clistcallb,0);
|
||||
which=EndListShow();
|
||||
if(which>=0)
|
||||
{
|
||||
char tmp[32];
|
||||
printf(" <(T)oggle status, (M)odify, or (D)elete this cheat.> ");
|
||||
fgets(tmp,32,stdin);
|
||||
switch(tolower(tmp[0]))
|
||||
{
|
||||
case 't':ToggleCheat(which);
|
||||
break;
|
||||
case 'd':if(!FCEUI_DelCheat(which))
|
||||
puts("Error deleting cheat!");
|
||||
else
|
||||
puts("Cheat has been deleted.");
|
||||
break;
|
||||
case 'm':ModifyCheat(which);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ResetSearch(void)
|
||||
{
|
||||
FCEUI_CheatSearchBegin();
|
||||
puts("Done.");
|
||||
}
|
||||
|
||||
static int srescallb(uint32 a, uint8 last, uint8 current, void *data)
|
||||
{
|
||||
char tmp[13];
|
||||
sprintf(tmp, "$%04x:%03d:%03d",(unsigned int)a,(unsigned int)last,(unsigned int)current);
|
||||
return(AddToList(tmp,a));
|
||||
}
|
||||
|
||||
static void ShowRes(void)
|
||||
{
|
||||
int n=FCEUI_CheatSearchGetCount();
|
||||
printf(" %d results:\n",n);
|
||||
if(n)
|
||||
{
|
||||
int which;
|
||||
BeginListShow();
|
||||
FCEUI_CheatSearchGet(srescallb,0);
|
||||
which=EndListShow();
|
||||
if(which>=0)
|
||||
AddCheatParam(which,0);
|
||||
}
|
||||
}
|
||||
|
||||
static int ShowShortList(char *moe[], int n, int def)
|
||||
{
|
||||
int x,c;
|
||||
unsigned int baa;
|
||||
char tmp[16];
|
||||
|
||||
red:
|
||||
for(x=0;x<n;x++)
|
||||
printf("%d) %s\n",x+1,moe[x]);
|
||||
puts("D) Display List");
|
||||
clo:
|
||||
|
||||
printf("\nSelection [%d]> ",def+1);
|
||||
fgets(tmp,256,stdin);
|
||||
if(tmp[0]=='\n')
|
||||
return def;
|
||||
c=tolower(tmp[0]);
|
||||
baa=c-'1';
|
||||
|
||||
if(baa<n)
|
||||
return baa;
|
||||
else if(c=='d')
|
||||
goto red;
|
||||
else
|
||||
{
|
||||
puts("Invalid selection.");
|
||||
goto clo;
|
||||
}
|
||||
}
|
||||
|
||||
static void DoSearch(void)
|
||||
{
|
||||
static int v1=0,v2=0;
|
||||
static int method=0;
|
||||
char *m[6]={"O==V1 && C==V2","O==V1 && |O-C|==V2","|O-C|==V2","O!=C","Value decreased","Value increased"};
|
||||
printf("\nSearch Filter:\n");
|
||||
|
||||
method=ShowShortList(m,6,method);
|
||||
if(method<=1)
|
||||
{
|
||||
printf("V1 [%03d]: ",v1);
|
||||
v1=Get8(v1);
|
||||
}
|
||||
if(method<=2)
|
||||
{
|
||||
printf("V2 [%03d]: ",v2);
|
||||
v2=Get8(v2);
|
||||
}
|
||||
FCEUI_CheatSearchEnd(method,v1,v2);
|
||||
puts("Search completed.\n");
|
||||
}
|
||||
|
||||
|
||||
static MENU NewCheatsMenu[]={
|
||||
{"Add Cheat",(void *)AddCheat,1},
|
||||
{"Reset Search",(void *)ResetSearch,1},
|
||||
{"Do Search",(void *)DoSearch,1},
|
||||
{"Set Original to Current",(void *)SetOC,1},
|
||||
{"Unhide Excluded",(void *)UnhideEx,1},
|
||||
{"Show Results",(void *)ShowRes,1},
|
||||
{"Add Game Genie Cheat",(void *)AddCheatGG,1},
|
||||
{"Add PAR Cheat",(void *)AddCheatPAR,1},
|
||||
{0}
|
||||
};
|
||||
|
||||
static MENU MainMenu[]={
|
||||
{"List Cheats",(void *)ListCheats,1},
|
||||
{"New Cheats...",(void *)NewCheatsMenu,0},
|
||||
{0}
|
||||
};
|
||||
|
||||
static void DoMenu(MENU *men)
|
||||
{
|
||||
int x=0;
|
||||
|
||||
redisplay:
|
||||
x=0;
|
||||
puts("");
|
||||
while(men[x].text)
|
||||
{
|
||||
printf("%d) %s\n",x+1,men[x].text);
|
||||
x++;
|
||||
}
|
||||
puts("D) Display Menu\nX) Return to Previous\n");
|
||||
{
|
||||
char buf[32];
|
||||
int c;
|
||||
|
||||
recommand:
|
||||
printf("Command> ");
|
||||
fgets(buf,32,stdin);
|
||||
c=tolower(buf[0]);
|
||||
if(c=='\n')
|
||||
goto recommand;
|
||||
else if(c=='d')
|
||||
goto redisplay;
|
||||
else if(c=='x')
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if(sscanf(buf,"%d",&c))
|
||||
{
|
||||
if(c>x) goto invalid;
|
||||
if(men[c-1].type)
|
||||
{
|
||||
void (*func)(void)=(void(*)())men[c-1].action;
|
||||
func();
|
||||
}
|
||||
else
|
||||
DoMenu((MENU*)men[c-1].action); /* Mmm...recursivey goodness. */
|
||||
goto redisplay;
|
||||
}
|
||||
else
|
||||
{
|
||||
invalid:
|
||||
puts("Invalid command.\n");
|
||||
goto recommand;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void DoConsoleCheatConfig(void)
|
||||
{
|
||||
MENU *curmenu=MainMenu;
|
||||
|
||||
DoMenu(curmenu);
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
void DoConsoleCheatConfig(void);
|
@ -1,152 +0,0 @@
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/****************************************************************/
|
||||
/* FCE Ultra */
|
||||
/* */
|
||||
/* This file contains routines for reading/writing the */
|
||||
/* configuration file. */
|
||||
/* */
|
||||
/****************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../../types.h"
|
||||
#include "config.h"
|
||||
|
||||
static int FReadString(FILE *fp, char *str, int n)
|
||||
{
|
||||
int x=0,z;
|
||||
for(;;)
|
||||
{
|
||||
z=fgetc(fp);
|
||||
str[x]=z;
|
||||
x++;
|
||||
if(z<=0) break;
|
||||
if(x>=n) return 0;
|
||||
}
|
||||
if(z<0) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void GetValueR(FILE *fp, char *str, void *v, int c)
|
||||
{
|
||||
char buf[256];
|
||||
int s;
|
||||
|
||||
while(FReadString(fp,buf,256))
|
||||
{
|
||||
fread(&s,1,4,fp);
|
||||
if(!strcmp(str, buf))
|
||||
{
|
||||
if(!c) // String, allocate some memory.
|
||||
{
|
||||
if(!(*(char **)v=(char*)malloc(s)))
|
||||
goto gogl;
|
||||
fread(*(char **)v,1,s,fp);
|
||||
continue;
|
||||
}
|
||||
else if(s>c || s<c)
|
||||
{
|
||||
gogl:
|
||||
fseek(fp,s,SEEK_CUR);
|
||||
continue;
|
||||
}
|
||||
fread((uint8*)v,1,c,fp);
|
||||
}
|
||||
else
|
||||
fseek(fp,s,SEEK_CUR);
|
||||
}
|
||||
fseek(fp,4,SEEK_SET);
|
||||
}
|
||||
|
||||
static void SetValueR(FILE *fp, char *str, void *v, int c)
|
||||
{
|
||||
fwrite(str,1,strlen(str)+1,fp);
|
||||
fwrite((uint8*)&c,1,4,fp);
|
||||
fwrite((uint8*)v,1,c,fp);
|
||||
}
|
||||
|
||||
static void SaveParse(CFGSTRUCT *cfgst, FILE *fp)
|
||||
{
|
||||
int x=0;
|
||||
|
||||
while(cfgst[x].ptr)
|
||||
{
|
||||
if(!cfgst[x].name) // Link to new config structure
|
||||
{
|
||||
SaveParse((CFGSTRUCT*)cfgst[x].ptr,fp); // Recursion is sexy. I could
|
||||
// save a little stack space if I made
|
||||
// the file pointer a non-local
|
||||
// variable...
|
||||
x++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(cfgst[x].len) // Plain data
|
||||
SetValueR(fp,cfgst[x].name,cfgst[x].ptr,cfgst[x].len);
|
||||
else // String
|
||||
if(*(char **)cfgst[x].ptr) // Only save it if there IS a string.
|
||||
SetValueR(fp,cfgst[x].name,*(char **)cfgst[x].ptr,
|
||||
strlen(*(char **)cfgst[x].ptr)+1);
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
void SaveFCEUConfig(char *filename, CFGSTRUCT *cfgst)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp=fopen(filename,"wb");
|
||||
if(fp==NULL) return;
|
||||
|
||||
SaveParse(cfgst,fp);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
static void LoadParse(CFGSTRUCT *cfgst, FILE *fp)
|
||||
{
|
||||
int x=0;
|
||||
|
||||
while(cfgst[x].ptr)
|
||||
{
|
||||
if(!cfgst[x].name) // Link to new config structure
|
||||
{
|
||||
LoadParse((CFGSTRUCT*)cfgst[x].ptr,fp);
|
||||
x++;
|
||||
continue;
|
||||
}
|
||||
GetValueR(fp,cfgst[x].name,cfgst[x].ptr,cfgst[x].len);
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
void LoadFCEUConfig(char *filename, CFGSTRUCT *cfgst)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp=fopen(filename,"rb");
|
||||
if(fp==NULL) return;
|
||||
LoadParse(cfgst,fp);
|
||||
fclose(fp);
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
#ifndef _DRIVERS_CONFIGH
|
||||
typedef struct {
|
||||
char *name;
|
||||
void *ptr;
|
||||
int len;
|
||||
} CFGSTRUCT;
|
||||
|
||||
void SaveFCEUConfig(char *filename, CFGSTRUCT *cfgst);
|
||||
void LoadFCEUConfig(char *filename, CFGSTRUCT *cfgst);
|
||||
|
||||
/* Macros for building CFGSTRUCT structures. */
|
||||
|
||||
/* CFGSTRUCT structures must always end with ENDCFGSTRUCT */
|
||||
#define ENDCFGSTRUCT { 0,0,0 }
|
||||
|
||||
/* When this macro is used, the config loading/saving code will parse
|
||||
the new config structure until the end of it is detected, then it
|
||||
will continue parsing the original config structure.
|
||||
*/
|
||||
#define ADDCFGSTRUCT(x) { 0,&x,0 }
|
||||
|
||||
/* Oops. The NAC* macros shouldn't have the # in front of the w, but
|
||||
fixing this would break configuration files of previous versions and it
|
||||
isn't really hurting much.
|
||||
*/
|
||||
|
||||
/* Single piece of data(integer). */
|
||||
#define AC(x) { #x,&x,sizeof(x)}
|
||||
#define NAC(w,x) { #w,&x,sizeof(x)}
|
||||
|
||||
/* Array. */
|
||||
#define ACA(x) {#x,x,sizeof(x)}
|
||||
#define NACA(w,x) {#w,x,sizeof(x)}
|
||||
|
||||
/* String(pointer) with automatic memory allocation. */
|
||||
#define ACS(x) {#x,&x,0}
|
||||
#define NACS(w,x) {#w,&x,0}
|
||||
|
||||
#define _DRIVERS_CONFIGH
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +0,0 @@
|
||||
void hq2x_32( unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int BpL);
|
||||
int hq2x_InitLUTs(void);
|
||||
void hq2x_Kill(void);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +0,0 @@
|
||||
void hq3x_32( unsigned char * pIn, unsigned char * pOut, int Xres, int Yres, int BpL);
|
||||
int hq3x_InitLUTs(void);
|
||||
void hq3x_Kill(void);
|
||||
|
@ -1,923 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Scale2x project.
|
||||
*
|
||||
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains a C and MMX implementation of the Scale2x effect.
|
||||
*
|
||||
* You can find an high level description of the effect at :
|
||||
*
|
||||
* http://scale2x.sourceforge.net/
|
||||
*
|
||||
* Alternatively at the previous license terms, you are allowed to use this
|
||||
* code in your program with these conditions:
|
||||
* - the program is not used in commercial activities.
|
||||
* - the whole source code of the program is released with the binary.
|
||||
* - derivative works of the program are allowed.
|
||||
*/
|
||||
|
||||
#include "scale2x.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/***************************************************************************/
|
||||
/* Scale2x C implementation */
|
||||
|
||||
static inline void scale2x_8_def_single(scale2x_uint8* __restrict__ dst, const scale2x_uint8* __restrict__ src0, const scale2x_uint8* __restrict__ src1, const scale2x_uint8* __restrict__ src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
dst[0] = src1[0];
|
||||
if (src1[1] == src0[0] && src2[0] != src0[0])
|
||||
dst[1] = src0[0];
|
||||
else
|
||||
dst[1] = src1[0];
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 2;
|
||||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
|
||||
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 2;
|
||||
--count;
|
||||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src1[-1] == src0[0] && src2[0] != src0[0])
|
||||
dst[0] = src0[0];
|
||||
else
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
||||
static inline void scale2x_16_def_single(scale2x_uint16* __restrict__ dst, const scale2x_uint16* __restrict__ src0, const scale2x_uint16* __restrict__ src1, const scale2x_uint16* __restrict__ src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
dst[0] = src1[0];
|
||||
if (src1[1] == src0[0] && src2[0] != src0[0])
|
||||
dst[1] = src0[0];
|
||||
else
|
||||
dst[1] = src1[0];
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 2;
|
||||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
|
||||
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 2;
|
||||
--count;
|
||||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src1[-1] == src0[0] && src2[0] != src0[0])
|
||||
dst[0] = src0[0];
|
||||
else
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
||||
static inline void scale2x_32_def_single(scale2x_uint32* __restrict__ dst, const scale2x_uint32* __restrict__ src0, const scale2x_uint32* __restrict__ src1, const scale2x_uint32* __restrict__ src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
dst[0] = src1[0];
|
||||
if (src1[1] == src0[0] && src2[0] != src0[0])
|
||||
dst[1] = src0[0];
|
||||
else
|
||||
dst[1] = src1[0];
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 2;
|
||||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = src1[-1] == src0[0] ? src0[0] : src1[0];
|
||||
dst[1] = src1[1] == src0[0] ? src0[0] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 2;
|
||||
--count;
|
||||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src1[-1] == src0[0] && src2[0] != src0[0])
|
||||
dst[0] = src0[0];
|
||||
else
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale by a factor of 2 a row of pixels of 8 bits.
|
||||
* The function is implemented in C.
|
||||
* The pixels over the left and right borders are assumed of the same color of
|
||||
* the pixels on the border.
|
||||
* \param src0 Pointer at the first pixel of the previous row.
|
||||
* \param src1 Pointer at the first pixel of the current row.
|
||||
* \param src2 Pointer at the first pixel of the next row.
|
||||
* \param count Length in pixels of the src0, src1 and src2 rows.
|
||||
* It must be at least 2.
|
||||
* \param dst0 First destination row, double length in pixels.
|
||||
* \param dst1 Second destination row, double length in pixels.
|
||||
*/
|
||||
void scale2x_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
scale2x_8_def_single(dst0, src0, src1, src2, count);
|
||||
scale2x_8_def_single(dst1, src2, src1, src0, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale by a factor of 2 a row of pixels of 16 bits.
|
||||
* This function operates like scale2x_8_def() but for 16 bits pixels.
|
||||
* \param src0 Pointer at the first pixel of the previous row.
|
||||
* \param src1 Pointer at the first pixel of the current row.
|
||||
* \param src2 Pointer at the first pixel of the next row.
|
||||
* \param count Length in pixels of the src0, src1 and src2 rows.
|
||||
* It must be at least 2.
|
||||
* \param dst0 First destination row, double length in pixels.
|
||||
* \param dst1 Second destination row, double length in pixels.
|
||||
*/
|
||||
void scale2x_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
scale2x_16_def_single(dst0, src0, src1, src2, count);
|
||||
scale2x_16_def_single(dst1, src2, src1, src0, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale by a factor of 2 a row of pixels of 32 bits.
|
||||
* This function operates like scale2x_8_def() but for 32 bits pixels.
|
||||
* \param src0 Pointer at the first pixel of the previous row.
|
||||
* \param src1 Pointer at the first pixel of the current row.
|
||||
* \param src2 Pointer at the first pixel of the next row.
|
||||
* \param count Length in pixels of the src0, src1 and src2 rows.
|
||||
* It must be at least 2.
|
||||
* \param dst0 First destination row, double length in pixels.
|
||||
* \param dst1 Second destination row, double length in pixels.
|
||||
*/
|
||||
void scale2x_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
scale2x_32_def_single(dst0, src0, src1, src2, count);
|
||||
scale2x_32_def_single(dst1, src2, src1, src0, count);
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* Scale2x MMX implementation */
|
||||
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
|
||||
/*
|
||||
* Apply the Scale2x effect at a single row.
|
||||
* This function must be called only by the other scale2x functions.
|
||||
*
|
||||
* Considering the pixel map :
|
||||
*
|
||||
* ABC (src0)
|
||||
* DEF (src1)
|
||||
* GHI (src2)
|
||||
*
|
||||
* this functions compute 2 new pixels in substitution of the source pixel E
|
||||
* like this map :
|
||||
*
|
||||
* ab (dst)
|
||||
*
|
||||
* with these variables :
|
||||
*
|
||||
* ¤t -> E
|
||||
* ¤t_left -> D
|
||||
* ¤t_right -> F
|
||||
* ¤t_upper -> B
|
||||
* ¤t_lower -> H
|
||||
*
|
||||
* %0 -> current_upper
|
||||
* %1 -> current
|
||||
* %2 -> current_lower
|
||||
* %3 -> dst
|
||||
* %4 -> counter
|
||||
*
|
||||
* %mm0 -> *current_left
|
||||
* %mm1 -> *current_next
|
||||
* %mm2 -> tmp0
|
||||
* %mm3 -> tmp1
|
||||
* %mm4 -> tmp2
|
||||
* %mm5 -> tmp3
|
||||
* %mm6 -> *current_upper
|
||||
* %mm7 -> *current
|
||||
*/
|
||||
static inline void scale2x_8_mmx_single(scale2x_uint8* dst, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 16);
|
||||
assert(count % 8 == 0);
|
||||
|
||||
/* always do the first and last run */
|
||||
count -= 2*8;
|
||||
|
||||
__asm__ __volatile__(
|
||||
/* first run */
|
||||
/* set the current, current_pre, current_next registers */
|
||||
"movq 0(%1), %%mm0\n"
|
||||
"movq 0(%1), %%mm7\n"
|
||||
"movq 8(%1), %%mm1\n"
|
||||
"psllq $56, %%mm0\n"
|
||||
"psllq $56, %%mm1\n"
|
||||
"psrlq $56, %%mm0\n"
|
||||
"movq %%mm7, %%mm2\n"
|
||||
"movq %%mm7, %%mm3\n"
|
||||
"psllq $8, %%mm2\n"
|
||||
"psrlq $8, %%mm3\n"
|
||||
"por %%mm2, %%mm0\n"
|
||||
"por %%mm3, %%mm1\n"
|
||||
|
||||
/* current_upper */
|
||||
"movq (%0), %%mm6\n"
|
||||
|
||||
/* compute the upper-left pixel for dst on %%mm2 */
|
||||
/* compute the upper-right pixel for dst on %%mm4 */
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"movq %%mm0, %%mm3\n"
|
||||
"movq %%mm1, %%mm5\n"
|
||||
"pcmpeqb %%mm6, %%mm2\n"
|
||||
"pcmpeqb %%mm6, %%mm4\n"
|
||||
"pcmpeqb (%2), %%mm3\n"
|
||||
"pcmpeqb (%2), %%mm5\n"
|
||||
"pandn %%mm2, %%mm3\n"
|
||||
"pandn %%mm4, %%mm5\n"
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"pcmpeqb %%mm1, %%mm2\n"
|
||||
"pcmpeqb %%mm0, %%mm4\n"
|
||||
"pandn %%mm3, %%mm2\n"
|
||||
"pandn %%mm5, %%mm4\n"
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"movq %%mm4, %%mm5\n"
|
||||
"pand %%mm6, %%mm2\n"
|
||||
"pand %%mm6, %%mm4\n"
|
||||
"pandn %%mm7, %%mm3\n"
|
||||
"pandn %%mm7, %%mm5\n"
|
||||
"por %%mm3, %%mm2\n"
|
||||
"por %%mm5, %%mm4\n"
|
||||
|
||||
/* set *dst */
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"punpcklbw %%mm4, %%mm2\n"
|
||||
"punpckhbw %%mm4, %%mm3\n"
|
||||
"movq %%mm2, (%3)\n"
|
||||
"movq %%mm3, 8(%3)\n"
|
||||
|
||||
/* next */
|
||||
"addl $8, %0\n"
|
||||
"addl $8, %1\n"
|
||||
"addl $8, %2\n"
|
||||
"addl $16, %3\n"
|
||||
|
||||
/* central runs */
|
||||
"shrl $3, %4\n"
|
||||
"jz 1f\n"
|
||||
|
||||
"0:\n"
|
||||
|
||||
/* set the current, current_pre, current_next registers */
|
||||
"movq -8(%1), %%mm0\n"
|
||||
"movq (%1), %%mm7\n"
|
||||
"movq 8(%1), %%mm1\n"
|
||||
"psrlq $56, %%mm0\n"
|
||||
"psllq $56, %%mm1\n"
|
||||
"movq %%mm7, %%mm2\n"
|
||||
"movq %%mm7, %%mm3\n"
|
||||
"psllq $8, %%mm2\n"
|
||||
"psrlq $8, %%mm3\n"
|
||||
"por %%mm2, %%mm0\n"
|
||||
"por %%mm3, %%mm1\n"
|
||||
|
||||
/* current_upper */
|
||||
"movq (%0), %%mm6\n"
|
||||
|
||||
/* compute the upper-left pixel for dst on %%mm2 */
|
||||
/* compute the upper-right pixel for dst on %%mm4 */
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"movq %%mm0, %%mm3\n"
|
||||
"movq %%mm1, %%mm5\n"
|
||||
"pcmpeqb %%mm6, %%mm2\n"
|
||||
"pcmpeqb %%mm6, %%mm4\n"
|
||||
"pcmpeqb (%2), %%mm3\n"
|
||||
"pcmpeqb (%2), %%mm5\n"
|
||||
"pandn %%mm2, %%mm3\n"
|
||||
"pandn %%mm4, %%mm5\n"
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"pcmpeqb %%mm1, %%mm2\n"
|
||||
"pcmpeqb %%mm0, %%mm4\n"
|
||||
"pandn %%mm3, %%mm2\n"
|
||||
"pandn %%mm5, %%mm4\n"
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"movq %%mm4, %%mm5\n"
|
||||
"pand %%mm6, %%mm2\n"
|
||||
"pand %%mm6, %%mm4\n"
|
||||
"pandn %%mm7, %%mm3\n"
|
||||
"pandn %%mm7, %%mm5\n"
|
||||
"por %%mm3, %%mm2\n"
|
||||
"por %%mm5, %%mm4\n"
|
||||
|
||||
/* set *dst */
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"punpcklbw %%mm4, %%mm2\n"
|
||||
"punpckhbw %%mm4, %%mm3\n"
|
||||
"movq %%mm2, (%3)\n"
|
||||
"movq %%mm3, 8(%3)\n"
|
||||
|
||||
/* next */
|
||||
"addl $8, %0\n"
|
||||
"addl $8, %1\n"
|
||||
"addl $8, %2\n"
|
||||
"addl $16, %3\n"
|
||||
|
||||
"decl %4\n"
|
||||
"jnz 0b\n"
|
||||
"1:\n"
|
||||
|
||||
/* final run */
|
||||
/* set the current, current_pre, current_next registers */
|
||||
"movq (%1), %%mm1\n"
|
||||
"movq (%1), %%mm7\n"
|
||||
"movq -8(%1), %%mm0\n"
|
||||
"psrlq $56, %%mm1\n"
|
||||
"psrlq $56, %%mm0\n"
|
||||
"psllq $56, %%mm1\n"
|
||||
"movq %%mm7, %%mm2\n"
|
||||
"movq %%mm7, %%mm3\n"
|
||||
"psllq $8, %%mm2\n"
|
||||
"psrlq $8, %%mm3\n"
|
||||
"por %%mm2, %%mm0\n"
|
||||
"por %%mm3, %%mm1\n"
|
||||
|
||||
/* current_upper */
|
||||
"movq (%0), %%mm6\n"
|
||||
|
||||
/* compute the upper-left pixel for dst on %%mm2 */
|
||||
/* compute the upper-right pixel for dst on %%mm4 */
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"movq %%mm0, %%mm3\n"
|
||||
"movq %%mm1, %%mm5\n"
|
||||
"pcmpeqb %%mm6, %%mm2\n"
|
||||
"pcmpeqb %%mm6, %%mm4\n"
|
||||
"pcmpeqb (%2), %%mm3\n"
|
||||
"pcmpeqb (%2), %%mm5\n"
|
||||
"pandn %%mm2, %%mm3\n"
|
||||
"pandn %%mm4, %%mm5\n"
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"pcmpeqb %%mm1, %%mm2\n"
|
||||
"pcmpeqb %%mm0, %%mm4\n"
|
||||
"pandn %%mm3, %%mm2\n"
|
||||
"pandn %%mm5, %%mm4\n"
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"movq %%mm4, %%mm5\n"
|
||||
"pand %%mm6, %%mm2\n"
|
||||
"pand %%mm6, %%mm4\n"
|
||||
"pandn %%mm7, %%mm3\n"
|
||||
"pandn %%mm7, %%mm5\n"
|
||||
"por %%mm3, %%mm2\n"
|
||||
"por %%mm5, %%mm4\n"
|
||||
|
||||
/* set *dst */
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"punpcklbw %%mm4, %%mm2\n"
|
||||
"punpckhbw %%mm4, %%mm3\n"
|
||||
"movq %%mm2, (%3)\n"
|
||||
"movq %%mm3, 8(%3)\n"
|
||||
|
||||
: "+r" (src0), "+r" (src1), "+r" (src2), "+r" (dst), "+r" (count)
|
||||
:
|
||||
: "cc"
|
||||
);
|
||||
}
|
||||
|
||||
static inline void scale2x_16_mmx_single(scale2x_uint16* dst, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 8);
|
||||
assert(count % 4 == 0);
|
||||
|
||||
/* always do the first and last run */
|
||||
count -= 2*4;
|
||||
|
||||
__asm__ __volatile__(
|
||||
/* first run */
|
||||
/* set the current, current_pre, current_next registers */
|
||||
"movq 0(%1), %%mm0\n"
|
||||
"movq 0(%1), %%mm7\n"
|
||||
"movq 8(%1), %%mm1\n"
|
||||
"psllq $48, %%mm0\n"
|
||||
"psllq $48, %%mm1\n"
|
||||
"psrlq $48, %%mm0\n"
|
||||
"movq %%mm7, %%mm2\n"
|
||||
"movq %%mm7, %%mm3\n"
|
||||
"psllq $16, %%mm2\n"
|
||||
"psrlq $16, %%mm3\n"
|
||||
"por %%mm2, %%mm0\n"
|
||||
"por %%mm3, %%mm1\n"
|
||||
|
||||
/* current_upper */
|
||||
"movq (%0), %%mm6\n"
|
||||
|
||||
/* compute the upper-left pixel for dst on %%mm2 */
|
||||
/* compute the upper-right pixel for dst on %%mm4 */
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"movq %%mm0, %%mm3\n"
|
||||
"movq %%mm1, %%mm5\n"
|
||||
"pcmpeqw %%mm6, %%mm2\n"
|
||||
"pcmpeqw %%mm6, %%mm4\n"
|
||||
"pcmpeqw (%2), %%mm3\n"
|
||||
"pcmpeqw (%2), %%mm5\n"
|
||||
"pandn %%mm2, %%mm3\n"
|
||||
"pandn %%mm4, %%mm5\n"
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"pcmpeqw %%mm1, %%mm2\n"
|
||||
"pcmpeqw %%mm0, %%mm4\n"
|
||||
"pandn %%mm3, %%mm2\n"
|
||||
"pandn %%mm5, %%mm4\n"
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"movq %%mm4, %%mm5\n"
|
||||
"pand %%mm6, %%mm2\n"
|
||||
"pand %%mm6, %%mm4\n"
|
||||
"pandn %%mm7, %%mm3\n"
|
||||
"pandn %%mm7, %%mm5\n"
|
||||
"por %%mm3, %%mm2\n"
|
||||
"por %%mm5, %%mm4\n"
|
||||
|
||||
/* set *dst */
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"punpcklwd %%mm4, %%mm2\n"
|
||||
"punpckhwd %%mm4, %%mm3\n"
|
||||
"movq %%mm2, (%3)\n"
|
||||
"movq %%mm3, 8(%3)\n"
|
||||
|
||||
/* next */
|
||||
"addl $8, %0\n"
|
||||
"addl $8, %1\n"
|
||||
"addl $8, %2\n"
|
||||
"addl $16, %3\n"
|
||||
|
||||
/* central runs */
|
||||
"shrl $2, %4\n"
|
||||
"jz 1f\n"
|
||||
|
||||
"0:\n"
|
||||
|
||||
/* set the current, current_pre, current_next registers */
|
||||
"movq -8(%1), %%mm0\n"
|
||||
"movq (%1), %%mm7\n"
|
||||
"movq 8(%1), %%mm1\n"
|
||||
"psrlq $48, %%mm0\n"
|
||||
"psllq $48, %%mm1\n"
|
||||
"movq %%mm7, %%mm2\n"
|
||||
"movq %%mm7, %%mm3\n"
|
||||
"psllq $16, %%mm2\n"
|
||||
"psrlq $16, %%mm3\n"
|
||||
"por %%mm2, %%mm0\n"
|
||||
"por %%mm3, %%mm1\n"
|
||||
|
||||
/* current_upper */
|
||||
"movq (%0), %%mm6\n"
|
||||
|
||||
/* compute the upper-left pixel for dst on %%mm2 */
|
||||
/* compute the upper-right pixel for dst on %%mm4 */
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"movq %%mm0, %%mm3\n"
|
||||
"movq %%mm1, %%mm5\n"
|
||||
"pcmpeqw %%mm6, %%mm2\n"
|
||||
"pcmpeqw %%mm6, %%mm4\n"
|
||||
"pcmpeqw (%2), %%mm3\n"
|
||||
"pcmpeqw (%2), %%mm5\n"
|
||||
"pandn %%mm2, %%mm3\n"
|
||||
"pandn %%mm4, %%mm5\n"
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"pcmpeqw %%mm1, %%mm2\n"
|
||||
"pcmpeqw %%mm0, %%mm4\n"
|
||||
"pandn %%mm3, %%mm2\n"
|
||||
"pandn %%mm5, %%mm4\n"
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"movq %%mm4, %%mm5\n"
|
||||
"pand %%mm6, %%mm2\n"
|
||||
"pand %%mm6, %%mm4\n"
|
||||
"pandn %%mm7, %%mm3\n"
|
||||
"pandn %%mm7, %%mm5\n"
|
||||
"por %%mm3, %%mm2\n"
|
||||
"por %%mm5, %%mm4\n"
|
||||
|
||||
/* set *dst */
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"punpcklwd %%mm4, %%mm2\n"
|
||||
"punpckhwd %%mm4, %%mm3\n"
|
||||
"movq %%mm2, (%3)\n"
|
||||
"movq %%mm3, 8(%3)\n"
|
||||
|
||||
/* next */
|
||||
"addl $8, %0\n"
|
||||
"addl $8, %1\n"
|
||||
"addl $8, %2\n"
|
||||
"addl $16, %3\n"
|
||||
|
||||
"decl %4\n"
|
||||
"jnz 0b\n"
|
||||
"1:\n"
|
||||
|
||||
/* final run */
|
||||
/* set the current, current_pre, current_next registers */
|
||||
"movq (%1), %%mm1\n"
|
||||
"movq (%1), %%mm7\n"
|
||||
"movq -8(%1), %%mm0\n"
|
||||
"psrlq $48, %%mm1\n"
|
||||
"psrlq $48, %%mm0\n"
|
||||
"psllq $48, %%mm1\n"
|
||||
"movq %%mm7, %%mm2\n"
|
||||
"movq %%mm7, %%mm3\n"
|
||||
"psllq $16, %%mm2\n"
|
||||
"psrlq $16, %%mm3\n"
|
||||
"por %%mm2, %%mm0\n"
|
||||
"por %%mm3, %%mm1\n"
|
||||
|
||||
/* current_upper */
|
||||
"movq (%0), %%mm6\n"
|
||||
|
||||
/* compute the upper-left pixel for dst on %%mm2 */
|
||||
/* compute the upper-right pixel for dst on %%mm4 */
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"movq %%mm0, %%mm3\n"
|
||||
"movq %%mm1, %%mm5\n"
|
||||
"pcmpeqw %%mm6, %%mm2\n"
|
||||
"pcmpeqw %%mm6, %%mm4\n"
|
||||
"pcmpeqw (%2), %%mm3\n"
|
||||
"pcmpeqw (%2), %%mm5\n"
|
||||
"pandn %%mm2, %%mm3\n"
|
||||
"pandn %%mm4, %%mm5\n"
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"pcmpeqw %%mm1, %%mm2\n"
|
||||
"pcmpeqw %%mm0, %%mm4\n"
|
||||
"pandn %%mm3, %%mm2\n"
|
||||
"pandn %%mm5, %%mm4\n"
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"movq %%mm4, %%mm5\n"
|
||||
"pand %%mm6, %%mm2\n"
|
||||
"pand %%mm6, %%mm4\n"
|
||||
"pandn %%mm7, %%mm3\n"
|
||||
"pandn %%mm7, %%mm5\n"
|
||||
"por %%mm3, %%mm2\n"
|
||||
"por %%mm5, %%mm4\n"
|
||||
|
||||
/* set *dst */
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"punpcklwd %%mm4, %%mm2\n"
|
||||
"punpckhwd %%mm4, %%mm3\n"
|
||||
"movq %%mm2, (%3)\n"
|
||||
"movq %%mm3, 8(%3)\n"
|
||||
|
||||
: "+r" (src0), "+r" (src1), "+r" (src2), "+r" (dst), "+r" (count)
|
||||
:
|
||||
: "cc"
|
||||
);
|
||||
}
|
||||
|
||||
static inline void scale2x_32_mmx_single(scale2x_uint32* dst, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 4);
|
||||
assert(count % 2 == 0);
|
||||
|
||||
/* always do the first and last run */
|
||||
count -= 2*2;
|
||||
|
||||
__asm__ __volatile__(
|
||||
/* first run */
|
||||
/* set the current, current_pre, current_next registers */
|
||||
"movq 0(%1), %%mm0\n"
|
||||
"movq 0(%1), %%mm7\n"
|
||||
"movq 8(%1), %%mm1\n"
|
||||
"psllq $32, %%mm0\n"
|
||||
"psllq $32, %%mm1\n"
|
||||
"psrlq $32, %%mm0\n"
|
||||
"movq %%mm7, %%mm2\n"
|
||||
"movq %%mm7, %%mm3\n"
|
||||
"psllq $32, %%mm2\n"
|
||||
"psrlq $32, %%mm3\n"
|
||||
"por %%mm2, %%mm0\n"
|
||||
"por %%mm3, %%mm1\n"
|
||||
|
||||
/* current_upper */
|
||||
"movq (%0), %%mm6\n"
|
||||
|
||||
/* compute the upper-left pixel for dst on %%mm2 */
|
||||
/* compute the upper-right pixel for dst on %%mm4 */
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"movq %%mm0, %%mm3\n"
|
||||
"movq %%mm1, %%mm5\n"
|
||||
"pcmpeqd %%mm6, %%mm2\n"
|
||||
"pcmpeqd %%mm6, %%mm4\n"
|
||||
"pcmpeqd (%2), %%mm3\n"
|
||||
"pcmpeqd (%2), %%mm5\n"
|
||||
"pandn %%mm2, %%mm3\n"
|
||||
"pandn %%mm4, %%mm5\n"
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"pcmpeqd %%mm1, %%mm2\n"
|
||||
"pcmpeqd %%mm0, %%mm4\n"
|
||||
"pandn %%mm3, %%mm2\n"
|
||||
"pandn %%mm5, %%mm4\n"
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"movq %%mm4, %%mm5\n"
|
||||
"pand %%mm6, %%mm2\n"
|
||||
"pand %%mm6, %%mm4\n"
|
||||
"pandn %%mm7, %%mm3\n"
|
||||
"pandn %%mm7, %%mm5\n"
|
||||
"por %%mm3, %%mm2\n"
|
||||
"por %%mm5, %%mm4\n"
|
||||
|
||||
/* set *dst */
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"punpckldq %%mm4, %%mm2\n"
|
||||
"punpckhdq %%mm4, %%mm3\n"
|
||||
"movq %%mm2, (%3)\n"
|
||||
"movq %%mm3, 8(%3)\n"
|
||||
|
||||
/* next */
|
||||
"addl $8, %0\n"
|
||||
"addl $8, %1\n"
|
||||
"addl $8, %2\n"
|
||||
"addl $16, %3\n"
|
||||
|
||||
/* central runs */
|
||||
"shrl $1, %4\n"
|
||||
"jz 1f\n"
|
||||
|
||||
"0:\n"
|
||||
|
||||
/* set the current, current_pre, current_next registers */
|
||||
"movq -8(%1), %%mm0\n"
|
||||
"movq (%1), %%mm7\n"
|
||||
"movq 8(%1), %%mm1\n"
|
||||
"psrlq $32, %%mm0\n"
|
||||
"psllq $32, %%mm1\n"
|
||||
"movq %%mm7, %%mm2\n"
|
||||
"movq %%mm7, %%mm3\n"
|
||||
"psllq $32, %%mm2\n"
|
||||
"psrlq $32, %%mm3\n"
|
||||
"por %%mm2, %%mm0\n"
|
||||
"por %%mm3, %%mm1\n"
|
||||
|
||||
/* current_upper */
|
||||
"movq (%0), %%mm6\n"
|
||||
|
||||
/* compute the upper-left pixel for dst on %%mm2 */
|
||||
/* compute the upper-right pixel for dst on %%mm4 */
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"movq %%mm0, %%mm3\n"
|
||||
"movq %%mm1, %%mm5\n"
|
||||
"pcmpeqd %%mm6, %%mm2\n"
|
||||
"pcmpeqd %%mm6, %%mm4\n"
|
||||
"pcmpeqd (%2), %%mm3\n"
|
||||
"pcmpeqd (%2), %%mm5\n"
|
||||
"pandn %%mm2, %%mm3\n"
|
||||
"pandn %%mm4, %%mm5\n"
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"pcmpeqd %%mm1, %%mm2\n"
|
||||
"pcmpeqd %%mm0, %%mm4\n"
|
||||
"pandn %%mm3, %%mm2\n"
|
||||
"pandn %%mm5, %%mm4\n"
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"movq %%mm4, %%mm5\n"
|
||||
"pand %%mm6, %%mm2\n"
|
||||
"pand %%mm6, %%mm4\n"
|
||||
"pandn %%mm7, %%mm3\n"
|
||||
"pandn %%mm7, %%mm5\n"
|
||||
"por %%mm3, %%mm2\n"
|
||||
"por %%mm5, %%mm4\n"
|
||||
|
||||
/* set *dst */
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"punpckldq %%mm4, %%mm2\n"
|
||||
"punpckhdq %%mm4, %%mm3\n"
|
||||
"movq %%mm2, (%3)\n"
|
||||
"movq %%mm3, 8(%3)\n"
|
||||
|
||||
/* next */
|
||||
"addl $8, %0\n"
|
||||
"addl $8, %1\n"
|
||||
"addl $8, %2\n"
|
||||
"addl $16, %3\n"
|
||||
|
||||
"decl %4\n"
|
||||
"jnz 0b\n"
|
||||
"1:\n"
|
||||
|
||||
/* final run */
|
||||
/* set the current, current_pre, current_next registers */
|
||||
"movq (%1), %%mm1\n"
|
||||
"movq (%1), %%mm7\n"
|
||||
"movq -8(%1), %%mm0\n"
|
||||
"psrlq $32, %%mm1\n"
|
||||
"psrlq $32, %%mm0\n"
|
||||
"psllq $32, %%mm1\n"
|
||||
"movq %%mm7, %%mm2\n"
|
||||
"movq %%mm7, %%mm3\n"
|
||||
"psllq $32, %%mm2\n"
|
||||
"psrlq $32, %%mm3\n"
|
||||
"por %%mm2, %%mm0\n"
|
||||
"por %%mm3, %%mm1\n"
|
||||
|
||||
/* current_upper */
|
||||
"movq (%0), %%mm6\n"
|
||||
|
||||
/* compute the upper-left pixel for dst on %%mm2 */
|
||||
/* compute the upper-right pixel for dst on %%mm4 */
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"movq %%mm0, %%mm3\n"
|
||||
"movq %%mm1, %%mm5\n"
|
||||
"pcmpeqd %%mm6, %%mm2\n"
|
||||
"pcmpeqd %%mm6, %%mm4\n"
|
||||
"pcmpeqd (%2), %%mm3\n"
|
||||
"pcmpeqd (%2), %%mm5\n"
|
||||
"pandn %%mm2, %%mm3\n"
|
||||
"pandn %%mm4, %%mm5\n"
|
||||
"movq %%mm0, %%mm2\n"
|
||||
"movq %%mm1, %%mm4\n"
|
||||
"pcmpeqd %%mm1, %%mm2\n"
|
||||
"pcmpeqd %%mm0, %%mm4\n"
|
||||
"pandn %%mm3, %%mm2\n"
|
||||
"pandn %%mm5, %%mm4\n"
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"movq %%mm4, %%mm5\n"
|
||||
"pand %%mm6, %%mm2\n"
|
||||
"pand %%mm6, %%mm4\n"
|
||||
"pandn %%mm7, %%mm3\n"
|
||||
"pandn %%mm7, %%mm5\n"
|
||||
"por %%mm3, %%mm2\n"
|
||||
"por %%mm5, %%mm4\n"
|
||||
|
||||
/* set *dst */
|
||||
"movq %%mm2, %%mm3\n"
|
||||
"punpckldq %%mm4, %%mm2\n"
|
||||
"punpckhdq %%mm4, %%mm3\n"
|
||||
"movq %%mm2, (%3)\n"
|
||||
"movq %%mm3, 8(%3)\n"
|
||||
|
||||
: "+r" (src0), "+r" (src1), "+r" (src2), "+r" (dst), "+r" (count)
|
||||
:
|
||||
: "cc"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale by a factor of 2 a row of pixels of 8 bits.
|
||||
* This is a very fast MMX implementation.
|
||||
* The implementation uses a combination of cmp/and/not operations to
|
||||
* completly remove the need of conditional jumps. This trick give the
|
||||
* major speed improvement.
|
||||
* Also, using the 8 bytes MMX registers more than one pixel are computed
|
||||
* at the same time.
|
||||
* Before calling this function you must ensure that the currenct CPU supports
|
||||
* the MMX instruction set. After calling it you must be sure to call the EMMS
|
||||
* instruction before any floating-point operation.
|
||||
* The pixels over the left and right borders are assumed of the same color of
|
||||
* the pixels on the border.
|
||||
* \param src0 Pointer at the first pixel of the previous row.
|
||||
* \param src1 Pointer at the first pixel of the current row.
|
||||
* \param src2 Pointer at the first pixel of the next row.
|
||||
* \param count Length in pixels of the src0, src1 and src2 rows. It must
|
||||
* be at least 16 and a multiple of 8.
|
||||
* \param dst0 First destination row, double length in pixels.
|
||||
* \param dst1 Second destination row, double length in pixels.
|
||||
*/
|
||||
void scale2x_8_mmx(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||
{
|
||||
if (count % 8 != 0 || count < 16) {
|
||||
scale2x_8_def(dst0, dst1, src0, src1, src2, count);
|
||||
} else {
|
||||
assert(count >= 16);
|
||||
assert(count % 8 == 0);
|
||||
|
||||
scale2x_8_mmx_single(dst0, src0, src1, src2, count);
|
||||
scale2x_8_mmx_single(dst1, src2, src1, src0, count);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale by a factor of 2 a row of pixels of 16 bits.
|
||||
* This function operates like scale2x_8_mmx() but for 16 bits pixels.
|
||||
* \param src0 Pointer at the first pixel of the previous row.
|
||||
* \param src1 Pointer at the first pixel of the current row.
|
||||
* \param src2 Pointer at the first pixel of the next row.
|
||||
* \param count Length in pixels of the src0, src1 and src2 rows. It must
|
||||
* be at least 8 and a multiple of 4.
|
||||
* \param dst0 First destination row, double length in pixels.
|
||||
* \param dst1 Second destination row, double length in pixels.
|
||||
*/
|
||||
void scale2x_16_mmx(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count)
|
||||
{
|
||||
if (count % 4 != 0 || count < 8) {
|
||||
scale2x_16_def(dst0, dst1, src0, src1, src2, count);
|
||||
} else {
|
||||
assert(count >= 8);
|
||||
assert(count % 4 == 0);
|
||||
|
||||
scale2x_16_mmx_single(dst0, src0, src1, src2, count);
|
||||
scale2x_16_mmx_single(dst1, src2, src1, src0, count);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale by a factor of 2 a row of pixels of 32 bits.
|
||||
* This function operates like scale2x_8_mmx() but for 32 bits pixels.
|
||||
* \param src0 Pointer at the first pixel of the previous row.
|
||||
* \param src1 Pointer at the first pixel of the current row.
|
||||
* \param src2 Pointer at the first pixel of the next row.
|
||||
* \param count Length in pixels of the src0, src1 and src2 rows. It must
|
||||
* be at least 4 and a multiple of 2.
|
||||
* \param dst0 First destination row, double length in pixels.
|
||||
* \param dst1 Second destination row, double length in pixels.
|
||||
*/
|
||||
void scale2x_32_mmx(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count)
|
||||
{
|
||||
if (count % 2 != 0 || count < 4) {
|
||||
scale2x_32_def(dst0, dst1, src0, src1, src2, count);
|
||||
} else {
|
||||
assert(count >= 4);
|
||||
assert(count % 2 == 0);
|
||||
|
||||
scale2x_32_mmx_single(dst0, src0, src1, src2, count);
|
||||
scale2x_32_mmx_single(dst1, src2, src1, src0, count);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Scale2x project.
|
||||
*
|
||||
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __SCALE2X_H
|
||||
#define __SCALE2X_H
|
||||
|
||||
typedef unsigned char scale2x_uint8;
|
||||
typedef unsigned short scale2x_uint16;
|
||||
typedef unsigned scale2x_uint32;
|
||||
|
||||
void scale2x_8_def(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count);
|
||||
void scale2x_16_def(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count);
|
||||
void scale2x_32_def(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count);
|
||||
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
|
||||
void scale2x_8_mmx(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count);
|
||||
void scale2x_16_mmx(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint16* src0, const scale2x_uint16* src1, const scale2x_uint16* src2, unsigned count);
|
||||
void scale2x_32_mmx(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint32* src0, const scale2x_uint32* src1, const scale2x_uint32* src2, unsigned count);
|
||||
|
||||
/**
|
||||
* End the use of the MMX instructions.
|
||||
* This function must be called before using any floating-point operations.
|
||||
*/
|
||||
static inline void scale2x_mmx_emms(void)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"emms"
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,382 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Scale2x project.
|
||||
*
|
||||
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains a C and MMX implementation of the Scale2x effect.
|
||||
*
|
||||
* You can find an high level description of the effect at :
|
||||
*
|
||||
* http://scale2x.sourceforge.net/
|
||||
*
|
||||
* Alternatively at the previous license terms, you are allowed to use this
|
||||
* code in your program with these conditions:
|
||||
* - the program is not used in commercial activities.
|
||||
* - the whole source code of the program is released with the binary.
|
||||
* - derivative works of the program are allowed.
|
||||
*/
|
||||
|
||||
#include "scale3x.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/***************************************************************************/
|
||||
/* Scale3x C implementation */
|
||||
|
||||
static inline void scale3x_8_def_border(scale3x_uint8* __restrict__ dst, const scale3x_uint8* __restrict__ src0, const scale3x_uint8* __restrict__ src1, const scale3x_uint8* __restrict__ src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
if (src1[1] == src0[0] && src2[0] != src0[0])
|
||||
dst[2] = src0[0];
|
||||
else
|
||||
dst[2] = src1[0];
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 3;
|
||||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
|
||||
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
|
||||
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 3;
|
||||
--count;
|
||||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src1[-1] == src0[0] && src2[0] != src0[0])
|
||||
dst[0] = src0[0];
|
||||
else
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
|
||||
static inline void scale3x_8_def_center(scale3x_uint8* __restrict__ dst, const scale3x_uint8* __restrict__ src0, const scale3x_uint8* __restrict__ src1, const scale3x_uint8* __restrict__ src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
if (src0[0] != src2[0]) {
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 3;
|
||||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 3;
|
||||
--count;
|
||||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src0[0] != src2[0]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
}
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
|
||||
static inline void scale3x_16_def_border(scale3x_uint16* __restrict__ dst, const scale3x_uint16* __restrict__ src0, const scale3x_uint16* __restrict__ src1, const scale3x_uint16* __restrict__ src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
if (src1[1] == src0[0] && src2[0] != src0[0])
|
||||
dst[2] = src0[0];
|
||||
else
|
||||
dst[2] = src1[0];
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 3;
|
||||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
|
||||
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
|
||||
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 3;
|
||||
--count;
|
||||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src1[-1] == src0[0] && src2[0] != src0[0])
|
||||
dst[0] = src0[0];
|
||||
else
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
|
||||
static inline void scale3x_16_def_center(scale3x_uint16* __restrict__ dst, const scale3x_uint16* __restrict__ src0, const scale3x_uint16* __restrict__ src1, const scale3x_uint16* __restrict__ src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
if (src0[0] != src2[0]) {
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 3;
|
||||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 3;
|
||||
--count;
|
||||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src0[0] != src2[0]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
}
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
|
||||
static inline void scale3x_32_def_border(scale3x_uint32* __restrict__ dst, const scale3x_uint32* __restrict__ src0, const scale3x_uint32* __restrict__ src1, const scale3x_uint32* __restrict__ src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
if (src1[1] == src0[0] && src2[0] != src0[0])
|
||||
dst[2] = src0[0];
|
||||
else
|
||||
dst[2] = src1[0];
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 3;
|
||||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = src1[-1] == src0[0] ? src1[-1] : src1[0];
|
||||
dst[1] = (src1[-1] == src0[0] && src1[0] != src0[1]) || (src1[1] == src0[0] && src1[0] != src0[-1]) ? src0[0] : src1[0];
|
||||
dst[2] = src1[1] == src0[0] ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 3;
|
||||
--count;
|
||||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src1[-1] == src0[0] && src2[0] != src0[0])
|
||||
dst[0] = src0[0];
|
||||
else
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
|
||||
static inline void scale3x_32_def_center(scale3x_uint32* __restrict__ dst, const scale3x_uint32* __restrict__ src0, const scale3x_uint32* __restrict__ src1, const scale3x_uint32* __restrict__ src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
if (src0[0] != src2[0]) {
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 3;
|
||||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src0[0] != src2[0] && src1[-1] != src1[1]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = (src1[1] == src0[0] && src1[0] != src2[1]) || (src1[1] == src2[0] && src1[0] != src0[1]) ? src1[1] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst += 3;
|
||||
--count;
|
||||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src0[0] != src2[0]) {
|
||||
dst[0] = (src1[-1] == src0[0] && src1[0] != src2[-1]) || (src1[-1] == src2[0] && src1[0] != src0[-1]) ? src1[-1] : src1[0];
|
||||
} else {
|
||||
dst[0] = src1[0];
|
||||
}
|
||||
dst[1] = src1[0];
|
||||
dst[2] = src1[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale by a factor of 3 a row of pixels of 8 bits.
|
||||
* The function is implemented in C.
|
||||
* The pixels over the left and right borders are assumed of the same color of
|
||||
* the pixels on the border.
|
||||
* \param src0 Pointer at the first pixel of the previous row.
|
||||
* \param src1 Pointer at the first pixel of the current row.
|
||||
* \param src2 Pointer at the first pixel of the next row.
|
||||
* \param count Length in pixels of the src0, src1 and src2 rows.
|
||||
* It must be at least 2.
|
||||
* \param dst0 First destination row, triple length in pixels.
|
||||
* \param dst1 Second destination row, triple length in pixels.
|
||||
* \param dst2 Third destination row, triple length in pixels.
|
||||
*/
|
||||
void scale3x_8_def(scale3x_uint8* dst0, scale3x_uint8* dst1, scale3x_uint8* dst2, const scale3x_uint8* src0, const scale3x_uint8* src1, const scale3x_uint8* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
scale3x_8_def_border(dst0, src0, src1, src2, count);
|
||||
scale3x_8_def_center(dst1, src0, src1, src2, count);
|
||||
scale3x_8_def_border(dst2, src2, src1, src0, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale by a factor of 3 a row of pixels of 16 bits.
|
||||
* This function operates like scale3x_8_def() but for 16 bits pixels.
|
||||
* \param src0 Pointer at the first pixel of the previous row.
|
||||
* \param src1 Pointer at the first pixel of the current row.
|
||||
* \param src2 Pointer at the first pixel of the next row.
|
||||
* \param count Length in pixels of the src0, src1 and src2 rows.
|
||||
* It must be at least 2.
|
||||
* \param dst0 First destination row, triple length in pixels.
|
||||
* \param dst1 Second destination row, triple length in pixels.
|
||||
* \param dst2 Third destination row, triple length in pixels.
|
||||
*/
|
||||
void scale3x_16_def(scale3x_uint16* dst0, scale3x_uint16* dst1, scale3x_uint16* dst2, const scale3x_uint16* src0, const scale3x_uint16* src1, const scale3x_uint16* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
scale3x_16_def_border(dst0, src0, src1, src2, count);
|
||||
scale3x_16_def_center(dst1, src0, src1, src2, count);
|
||||
scale3x_16_def_border(dst2, src2, src1, src0, count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale by a factor of 3 a row of pixels of 32 bits.
|
||||
* This function operates like scale3x_8_def() but for 32 bits pixels.
|
||||
* \param src0 Pointer at the first pixel of the previous row.
|
||||
* \param src1 Pointer at the first pixel of the current row.
|
||||
* \param src2 Pointer at the first pixel of the next row.
|
||||
* \param count Length in pixels of the src0, src1 and src2 rows.
|
||||
* It must be at least 2.
|
||||
* \param dst0 First destination row, triple length in pixels.
|
||||
* \param dst1 Second destination row, triple length in pixels.
|
||||
* \param dst2 Third destination row, triple length in pixels.
|
||||
*/
|
||||
void scale3x_32_def(scale3x_uint32* dst0, scale3x_uint32* dst1, scale3x_uint32* dst2, const scale3x_uint32* src0, const scale3x_uint32* src1, const scale3x_uint32* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
scale3x_32_def_border(dst0, src0, src1, src2, count);
|
||||
scale3x_32_def_center(dst1, src0, src1, src2, count);
|
||||
scale3x_32_def_border(dst2, src2, src1, src0, count);
|
||||
}
|
||||
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Scale2x project.
|
||||
*
|
||||
* Copyright (C) 2001, 2002, 2003, 2004 Andrea Mazzoleni
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __SCALE3X_H
|
||||
#define __SCALE3X_H
|
||||
|
||||
typedef unsigned char scale3x_uint8;
|
||||
typedef unsigned short scale3x_uint16;
|
||||
typedef unsigned scale3x_uint32;
|
||||
|
||||
void scale3x_8_def(scale3x_uint8* dst0, scale3x_uint8* dst1, scale3x_uint8* dst2, const scale3x_uint8* src0, const scale3x_uint8* src1, const scale3x_uint8* src2, unsigned count);
|
||||
void scale3x_16_def(scale3x_uint16* dst0, scale3x_uint16* dst1, scale3x_uint16* dst2, const scale3x_uint16* src0, const scale3x_uint16* src1, const scale3x_uint16* src2, unsigned count);
|
||||
void scale3x_32_def(scale3x_uint32* dst0, scale3x_uint32* dst1, scale3x_uint32* dst2, const scale3x_uint32* src0, const scale3x_uint32* src1, const scale3x_uint32* src2, unsigned count);
|
||||
|
||||
#endif
|
||||
|
@ -1,385 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Scale2x project.
|
||||
*
|
||||
* Copyright (C) 2003 Andrea Mazzoleni
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains an example implementation of the Scale effect
|
||||
* applyed to a generic bitmap.
|
||||
*
|
||||
* You can find an high level description of the effect at :
|
||||
*
|
||||
* http://scale2x.sourceforge.net/
|
||||
*
|
||||
* Alternatively at the previous license terms, you are allowed to use this
|
||||
* code in your program with these conditions:
|
||||
* - the program is not used in commercial activities.
|
||||
* - the whole source code of the program is released with the binary.
|
||||
* - derivative works of the program are allowed.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "scale2x.h"
|
||||
#include "scale3x.h"
|
||||
|
||||
#if HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* Apply the Scale2x effect on a group of rows. Used internally.
|
||||
*/
|
||||
static inline void stage_scale2x(void* dst0, void* dst1, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
|
||||
{
|
||||
switch (pixel) {
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
case 1 : scale2x_8_mmx(dst0, dst1, src0, src1, src2, pixel_per_row); break;
|
||||
case 2 : scale2x_16_mmx(dst0, dst1, src0, src1, src2, pixel_per_row); break;
|
||||
case 4 : scale2x_32_mmx(dst0, dst1, src0, src1, src2, pixel_per_row); break;
|
||||
#else
|
||||
case 1 : scale2x_8_def(dst0, dst1, src0, src1, src2, pixel_per_row); break;
|
||||
case 2 : scale2x_16_def(dst0, dst1, src0, src1, src2, pixel_per_row); break;
|
||||
case 4 : scale2x_32_def(dst0, dst1, src0, src1, src2, pixel_per_row); break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the Scale3x effect on a group of rows. Used internally.
|
||||
*/
|
||||
static inline void stage_scale3x(void* dst0, void* dst1, void* dst2, const void* src0, const void* src1, const void* src2, unsigned pixel, unsigned pixel_per_row)
|
||||
{
|
||||
switch (pixel) {
|
||||
case 1 : scale3x_8_def(dst0, dst1, dst2, src0, src1, src2, pixel_per_row); break;
|
||||
case 2 : scale3x_16_def(dst0, dst1, dst2, src0, src1, src2, pixel_per_row); break;
|
||||
case 4 : scale3x_32_def(dst0, dst1, dst2, src0, src1, src2, pixel_per_row); break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the Scale4x effect on a group of rows. Used internally.
|
||||
*/
|
||||
static inline void stage_scale4x(void* dst0, void* dst1, void* dst2, void* dst3, const void* src0, const void* src1, const void* src2, const void* src3, unsigned pixel, unsigned pixel_per_row)
|
||||
{
|
||||
stage_scale2x(dst0, dst1, src0, src1, src2, pixel, 2 * pixel_per_row);
|
||||
stage_scale2x(dst2, dst3, src1, src2, src3, pixel, 2 * pixel_per_row);
|
||||
}
|
||||
|
||||
#define SCDST(i) (dst+(i)*dst_slice)
|
||||
#define SCSRC(i) (src+(i)*src_slice)
|
||||
#define SCMID(i) (mid[(i)])
|
||||
|
||||
/**
|
||||
* Apply the Scale2x effect on a bitmap.
|
||||
* The destination bitmap is filled with the scaled version of the source bitmap.
|
||||
* The source bitmap isn't modified.
|
||||
* The destination bitmap must be manually allocated before calling the function,
|
||||
* note that the resulting size is exactly 2x2 times the size of the source bitmap.
|
||||
* \param void_dst Pointer at the first pixel of the destination bitmap.
|
||||
* \param dst_slice Size in bytes of a destination bitmap row.
|
||||
* \param void_src Pointer at the first pixel of the source bitmap.
|
||||
* \param src_slice Size in bytes of a source bitmap row.
|
||||
* \param pixel Bytes per pixel of the source and destination bitmap.
|
||||
* \param width Horizontal size in pixels of the source bitmap.
|
||||
* \param height Vertical size in pixels of the source bitmap.
|
||||
*/
|
||||
static void scale2x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||
{
|
||||
unsigned char* dst = (unsigned char*)void_dst;
|
||||
const unsigned char* src = (unsigned char*)void_src;
|
||||
unsigned count;
|
||||
|
||||
assert(height >= 2);
|
||||
|
||||
count = height;
|
||||
|
||||
stage_scale2x(SCDST(0), SCDST(1), SCSRC(0), SCSRC(0), SCSRC(1), pixel, width);
|
||||
|
||||
dst = SCDST(2);
|
||||
|
||||
count -= 2;
|
||||
while (count) {
|
||||
stage_scale2x(SCDST(0), SCDST(1), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
|
||||
|
||||
dst = SCDST(2);
|
||||
src = SCSRC(1);
|
||||
|
||||
--count;
|
||||
}
|
||||
|
||||
stage_scale2x(SCDST(0), SCDST(1), SCSRC(1-1), SCSRC(2-1), SCSRC(2-1), pixel, width);
|
||||
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
scale2x_mmx_emms();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the Scale32x effect on a bitmap.
|
||||
* The destination bitmap is filled with the scaled version of the source bitmap.
|
||||
* The source bitmap isn't modified.
|
||||
* The destination bitmap must be manually allocated before calling the function,
|
||||
* note that the resulting size is exactly 3x3 times the size of the source bitmap.
|
||||
* \param void_dst Pointer at the first pixel of the destination bitmap.
|
||||
* \param dst_slice Size in bytes of a destination bitmap row.
|
||||
* \param void_src Pointer at the first pixel of the source bitmap.
|
||||
* \param src_slice Size in bytes of a source bitmap row.
|
||||
* \param pixel Bytes per pixel of the source and destination bitmap.
|
||||
* \param width Horizontal size in pixels of the source bitmap.
|
||||
* \param height Vertical size in pixels of the source bitmap.
|
||||
*/
|
||||
static void scale3x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||
{
|
||||
unsigned char* dst = (unsigned char*)void_dst;
|
||||
const unsigned char* src = (unsigned char*)void_src;
|
||||
unsigned count;
|
||||
|
||||
assert(height >= 2);
|
||||
|
||||
count = height;
|
||||
|
||||
stage_scale3x(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(0), SCSRC(1), pixel, width);
|
||||
|
||||
dst = SCDST(3);
|
||||
|
||||
count -= 2;
|
||||
while (count) {
|
||||
stage_scale3x(SCDST(0), SCDST(1), SCDST(2), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
|
||||
|
||||
dst = SCDST(3);
|
||||
src = SCSRC(1);
|
||||
|
||||
--count;
|
||||
}
|
||||
|
||||
stage_scale3x(SCDST(0), SCDST(1), SCDST(2), SCSRC(1-1), SCSRC(2-1), SCSRC(2-1), pixel, width);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the Scale4x effect on a bitmap.
|
||||
* The destination bitmap is filled with the scaled version of the source bitmap.
|
||||
* The source bitmap isn't modified.
|
||||
* The destination bitmap must be manually allocated before calling the function,
|
||||
* note that the resulting size is exactly 4x4 times the size of the source bitmap.
|
||||
* \note This function requires also a small buffer bitmap used internally to store
|
||||
* intermediate results. This bitmap must have at least an horizontal size in bytes of 2*width*pixel,
|
||||
* and a vertical size of 6 rows. The memory of this buffer must not be allocated
|
||||
* in video memory because it's also read and not only written. Generally
|
||||
* a heap (malloc) or a stack (alloca) buffer is the best choices.
|
||||
* \param void_dst Pointer at the first pixel of the destination bitmap.
|
||||
* \param dst_slice Size in bytes of a destination bitmap row.
|
||||
* \param void_mid Pointer at the first pixel of the buffer bitmap.
|
||||
* \param mid_slice Size in bytes of a buffer bitmap row.
|
||||
* \param void_src Pointer at the first pixel of the source bitmap.
|
||||
* \param src_slice Size in bytes of a source bitmap row.
|
||||
* \param pixel Bytes per pixel of the source and destination bitmap.
|
||||
* \param width Horizontal size in pixels of the source bitmap.
|
||||
* \param height Vertical size in pixels of the source bitmap.
|
||||
*/
|
||||
static void scale4x_buf(void* void_dst, unsigned dst_slice, void* void_mid, unsigned mid_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||
{
|
||||
unsigned char* dst = (unsigned char*)void_dst;
|
||||
const unsigned char* src = (unsigned char*)void_src;
|
||||
unsigned count;
|
||||
unsigned char* mid[6];
|
||||
|
||||
assert(height >= 4);
|
||||
|
||||
count = height;
|
||||
|
||||
/* set the 6 buffer pointers */
|
||||
mid[0] = (unsigned char*)void_mid;
|
||||
mid[1] = mid[0] + mid_slice;
|
||||
mid[2] = mid[1] + mid_slice;
|
||||
mid[3] = mid[2] + mid_slice;
|
||||
mid[4] = mid[3] + mid_slice;
|
||||
mid[5] = mid[4] + mid_slice;
|
||||
|
||||
stage_scale2x(SCMID(-2+6), SCMID(-1+6), SCSRC(0), SCSRC(0), SCSRC(1), pixel, width);
|
||||
stage_scale2x(SCMID(0), SCMID(1), SCSRC(0), SCSRC(1), SCSRC(2), pixel, width);
|
||||
stage_scale2x(SCMID(2), SCMID(3), SCSRC(1), SCSRC(2), SCSRC(3), pixel, width);
|
||||
stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(-2+6), SCMID(-2+6), SCMID(-1+6), SCMID(0), pixel, width);
|
||||
|
||||
dst = SCDST(4);
|
||||
|
||||
stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(-1+6), SCMID(0), SCMID(1), SCMID(2), pixel, width);
|
||||
|
||||
dst = SCDST(4);
|
||||
|
||||
count -= 4;
|
||||
while (count) {
|
||||
unsigned char* tmp;
|
||||
|
||||
stage_scale2x(SCMID(4), SCMID(5), SCSRC(2), SCSRC(3), SCSRC(4), pixel, width);
|
||||
stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(1), SCMID(2), SCMID(3), SCMID(4), pixel, width);
|
||||
|
||||
dst = SCDST(4);
|
||||
src = SCSRC(1);
|
||||
|
||||
tmp = SCMID(0); /* shift by 2 position */
|
||||
SCMID(0) = SCMID(2);
|
||||
SCMID(2) = SCMID(4);
|
||||
SCMID(4) = tmp;
|
||||
tmp = SCMID(1);
|
||||
SCMID(1) = SCMID(3);
|
||||
SCMID(3) = SCMID(5);
|
||||
SCMID(5) = tmp;
|
||||
|
||||
--count;
|
||||
}
|
||||
|
||||
stage_scale2x(SCMID(4), SCMID(5), SCSRC(2), SCSRC(3), SCSRC(3), pixel, width);
|
||||
stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(1), SCMID(2), SCMID(3), SCMID(4), pixel, width);
|
||||
|
||||
dst = SCDST(4);
|
||||
|
||||
stage_scale4x(SCDST(0), SCDST(1), SCDST(2), SCDST(3), SCMID(3), SCMID(4), SCMID(5), SCMID(5), pixel, width);
|
||||
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
scale2x_mmx_emms();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the Scale4x effect on a bitmap.
|
||||
* The destination bitmap is filled with the scaled version of the source bitmap.
|
||||
* The source bitmap isn't modified.
|
||||
* The destination bitmap must be manually allocated before calling the function,
|
||||
* note that the resulting size is exactly 4x4 times the size of the source bitmap.
|
||||
* \note This function operates like ::scale4x_buf() but the intermediate buffer is
|
||||
* automatically allocated in the stack.
|
||||
* \param void_dst Pointer at the first pixel of the destination bitmap.
|
||||
* \param dst_slice Size in bytes of a destination bitmap row.
|
||||
* \param void_src Pointer at the first pixel of the source bitmap.
|
||||
* \param src_slice Size in bytes of a source bitmap row.
|
||||
* \param pixel Bytes per pixel of the source and destination bitmap.
|
||||
* \param width Horizontal size in pixels of the source bitmap.
|
||||
* \param height Vertical size in pixels of the source bitmap.
|
||||
*/
|
||||
static void scale4x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||
{
|
||||
unsigned mid_slice;
|
||||
void* mid;
|
||||
|
||||
mid_slice = 2 * pixel * width; /* required space for 1 row buffer */
|
||||
|
||||
mid_slice = (mid_slice + 0x7) & ~0x7; /* align to 8 bytes */
|
||||
|
||||
#if HAVE_ALLOCA
|
||||
mid = alloca(6 * mid_slice); /* allocate space for 6 row buffers */
|
||||
|
||||
assert(mid != 0); /* alloca should never fails */
|
||||
#else
|
||||
mid = malloc(6 * mid_slice); /* allocate space for 6 row buffers */
|
||||
|
||||
if (!mid)
|
||||
return;
|
||||
#endif
|
||||
|
||||
scale4x_buf(void_dst, dst_slice, mid, mid_slice, void_src, src_slice, pixel, width, height);
|
||||
|
||||
#if !HAVE_ALLOCA
|
||||
free(mid);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the scale implementation is applicable at the given arguments.
|
||||
* \param scale Scale factor. 2, 3 or 4.
|
||||
* \param pixel Bytes per pixel of the source and destination bitmap.
|
||||
* \param width Horizontal size in pixels of the source bitmap.
|
||||
* \param height Vertical size in pixels of the source bitmap.
|
||||
* \return
|
||||
* - -1 on precondition violated.
|
||||
* - 0 on success.
|
||||
*/
|
||||
int scale_precondition(unsigned scale, unsigned pixel, unsigned width, unsigned height)
|
||||
{
|
||||
if (scale != 2 && scale != 3 && scale != 4)
|
||||
return -1;
|
||||
|
||||
if (pixel != 1 && pixel != 2 && pixel != 4)
|
||||
return -1;
|
||||
|
||||
switch (scale) {
|
||||
case 2 :
|
||||
case 3 :
|
||||
if (height < 2)
|
||||
return -1;
|
||||
break;
|
||||
case 4 :
|
||||
if (height < 4)
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && defined(__i386__)
|
||||
switch (scale) {
|
||||
case 2 :
|
||||
case 4 :
|
||||
if (width < (16 / pixel))
|
||||
return -1;
|
||||
if (width % (8 / pixel) != 0)
|
||||
return -1;
|
||||
break;
|
||||
case 3 :
|
||||
if (width < 2)
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if (width < 2)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the Scale effect on a bitmap.
|
||||
* This function is simply a common interface for ::scale2x(), ::scale3x() and ::scale4x().
|
||||
* \param scale Scale factor. 2, 3 or 4.
|
||||
* \param void_dst Pointer at the first pixel of the destination bitmap.
|
||||
* \param dst_slice Size in bytes of a destination bitmap row.
|
||||
* \param void_src Pointer at the first pixel of the source bitmap.
|
||||
* \param src_slice Size in bytes of a source bitmap row.
|
||||
* \param pixel Bytes per pixel of the source and destination bitmap.
|
||||
* \param width Horizontal size in pixels of the source bitmap.
|
||||
* \param height Vertical size in pixels of the source bitmap.
|
||||
*/
|
||||
void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height)
|
||||
{
|
||||
switch (scale) {
|
||||
case 2 :
|
||||
scale2x(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
|
||||
break;
|
||||
case 3 :
|
||||
scale3x(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
|
||||
break;
|
||||
case 4 :
|
||||
scale4x(void_dst, dst_slice, void_src, src_slice, pixel, width, height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Scale2x project.
|
||||
*
|
||||
* Copyright (C) 2003 Andrea Mazzoleni
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains an example implementation of the Scale effect
|
||||
* applyed to a generic bitmap.
|
||||
*
|
||||
* You can find an high level description of the effect at :
|
||||
*
|
||||
* http://scale2x.sourceforge.net/
|
||||
*
|
||||
* Alternatively at the previous license terms, you are allowed to use this
|
||||
* code in your program with these conditions:
|
||||
* - the program is not used in commercial activities.
|
||||
* - the whole source code of the program is released with the binary.
|
||||
* - derivative works of the program are allowed.
|
||||
*/
|
||||
|
||||
#ifndef __SCALEBIT_H
|
||||
#define __SCALEBIT_H
|
||||
|
||||
int scale_precondition(unsigned scale, unsigned pixel, unsigned width, unsigned height);
|
||||
void scale(unsigned scale, void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height);
|
||||
|
||||
#endif
|
||||
|
@ -1,843 +0,0 @@
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "scalebit.h"
|
||||
#include "hq2x.h"
|
||||
#include "hq3x.h"
|
||||
|
||||
#include "../../types.h"
|
||||
|
||||
static uint32 CBM[3];
|
||||
static uint32 *palettetranslate=0;
|
||||
|
||||
static uint16 *specbuf=NULL; // 8bpp -> 16bpp, pre hq2x/hq3x
|
||||
static uint32 *specbuf32bpp = NULL; // Buffer to hold output
|
||||
// of hq2x/hq3x when converting
|
||||
// to 16bpp and 24bpp
|
||||
static int backBpp, backshiftr[3], backshiftl[3];
|
||||
//static uint32 backmask[3];
|
||||
|
||||
static uint8 *specbuf8bpp = NULL; // For 2xscale, 3xscale.
|
||||
|
||||
|
||||
static int silt;
|
||||
|
||||
static int Bpp; // BYTES per pixel
|
||||
static int highefx;
|
||||
|
||||
#define BLUR_RED 20
|
||||
#define BLUR_GREEN 20
|
||||
#define BLUR_BLUE 10
|
||||
|
||||
#define FVB_SCANLINES 1
|
||||
|
||||
/* The blur effect is only available for bpp>=16. It could be easily modified
|
||||
to look like what happens on the real NES and TV, but lack of decent
|
||||
synchronization to the vertical retrace period makes it look rather
|
||||
blah.
|
||||
*/
|
||||
#define FVB_BLUR 2
|
||||
|
||||
static void CalculateShift(uint32 *CBM, int *cshiftr, int *cshiftl)
|
||||
{
|
||||
int a,x,z,y;
|
||||
cshiftl[0]=cshiftl[1]=cshiftl[2]=-1;
|
||||
for(a=0;a<3;a++)
|
||||
{
|
||||
for(x=0,y=-1,z=0;x<32;x++)
|
||||
{
|
||||
if(CBM[a]&(1<<x))
|
||||
{
|
||||
if(cshiftl[a]==-1) cshiftl[a]=x;
|
||||
z++;
|
||||
}
|
||||
}
|
||||
cshiftr[a]=(8-z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int InitBlitToHigh(int b, uint32 rmask, uint32 gmask, uint32 bmask, int efx, int specfilt)
|
||||
{
|
||||
if(specfilt == 2 || specfilt == 4) // scale2x and scale3x
|
||||
{
|
||||
int multi;
|
||||
|
||||
if(specfilt == 2) multi = 2 * 2;
|
||||
else if(specfilt == 4) multi = 3 * 3;
|
||||
|
||||
specbuf8bpp = malloc(256*240*multi);
|
||||
|
||||
}
|
||||
else if(specfilt == 1 || specfilt == 3) // hq2x and hq3x
|
||||
{
|
||||
if(b == 1)
|
||||
return(0);
|
||||
|
||||
if(b == 2 || b == 3) // 8->16->(hq2x)->32-> 24 or 16. YARGH.
|
||||
{
|
||||
uint32 tmpCBM[3];
|
||||
backBpp = b;
|
||||
tmpCBM[0]=rmask;
|
||||
tmpCBM[1]=gmask;
|
||||
tmpCBM[2]=bmask;
|
||||
|
||||
CalculateShift(tmpCBM, backshiftr, backshiftl);
|
||||
|
||||
if(b == 2)
|
||||
{
|
||||
// ark
|
||||
backshiftr[0] += 16;
|
||||
backshiftr[1] += 8;
|
||||
backshiftr[2] += 0;
|
||||
|
||||
// Begin iffy code(requires 16bpp and 32bpp to have same RGB order)
|
||||
//backmask[0] = (rmask>>backshiftl[0]) << (backshiftr[0]);
|
||||
//backmask[1] = (gmask>>backshiftl[1]) << (backshiftr[1]);
|
||||
//backmask[2] = (bmask>>backshiftl[2]) << (backshiftr[2]);
|
||||
|
||||
//int x;
|
||||
//for(x=0;x<3;x++)
|
||||
// backshiftr[x] -= backshiftl[x];
|
||||
// End iffy code
|
||||
}
|
||||
if(specfilt == 1) specbuf32bpp = malloc(256*240*4*sizeof(uint32));
|
||||
else if(specfilt == 3) specbuf32bpp = malloc(256*240*9*sizeof(uint32));
|
||||
}
|
||||
|
||||
efx=0;
|
||||
b=2;
|
||||
rmask=0x1F<<11;
|
||||
gmask=0x3F<<5;
|
||||
bmask=0x1F;
|
||||
|
||||
if(specfilt == 3)
|
||||
hq3x_InitLUTs();
|
||||
else
|
||||
hq2x_InitLUTs();
|
||||
|
||||
specbuf=malloc(256*240*sizeof(uint16));
|
||||
}
|
||||
|
||||
silt = specfilt;
|
||||
|
||||
Bpp=b;
|
||||
|
||||
highefx=efx;
|
||||
|
||||
if(Bpp<=1 || Bpp>4)
|
||||
return(0);
|
||||
|
||||
if(efx&FVB_BLUR)
|
||||
{
|
||||
if(Bpp==2)
|
||||
palettetranslate=(uint32 *)malloc(65536*4);
|
||||
else if(Bpp>=3)
|
||||
palettetranslate=(uint32 *)malloc(65536*4);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Bpp==2)
|
||||
palettetranslate=(uint32*)malloc(65536*4);
|
||||
else if(Bpp>=3)
|
||||
palettetranslate=(uint32*)malloc(256*4);
|
||||
}
|
||||
|
||||
if(!palettetranslate)
|
||||
return(0);
|
||||
|
||||
|
||||
CBM[0]=rmask;
|
||||
CBM[1]=gmask;
|
||||
CBM[2]=bmask;
|
||||
return(1);
|
||||
}
|
||||
|
||||
void KillBlitToHigh(void)
|
||||
{
|
||||
if(palettetranslate)
|
||||
{
|
||||
free(palettetranslate);
|
||||
palettetranslate=NULL;
|
||||
}
|
||||
|
||||
if(specbuf8bpp)
|
||||
{
|
||||
free(specbuf8bpp);
|
||||
specbuf8bpp = NULL;
|
||||
}
|
||||
if(specbuf32bpp)
|
||||
{
|
||||
free(specbuf32bpp);
|
||||
specbuf32bpp = NULL;
|
||||
}
|
||||
if(specbuf)
|
||||
{
|
||||
if(silt == 3)
|
||||
hq3x_Kill();
|
||||
else
|
||||
hq2x_Kill();
|
||||
specbuf=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SetPaletteBlitToHigh(uint8 *src)
|
||||
{
|
||||
int cshiftr[3];
|
||||
int cshiftl[3];
|
||||
int x,y;
|
||||
|
||||
CalculateShift(CBM, cshiftr, cshiftl);
|
||||
|
||||
switch(Bpp)
|
||||
{
|
||||
case 2:
|
||||
if(highefx&FVB_BLUR)
|
||||
{
|
||||
for(x=0;x<256;x++)
|
||||
{
|
||||
uint32 r,g,b;
|
||||
for(y=0;y<256;y++)
|
||||
{
|
||||
r=src[x<<2]*(100-BLUR_RED);
|
||||
g=src[(x<<2)+1]*(100-BLUR_GREEN);
|
||||
b=src[(x<<2)+2]*(100-BLUR_BLUE);
|
||||
|
||||
r+=src[y<<2]*BLUR_RED;
|
||||
g+=src[(y<<2)+1]*BLUR_GREEN;
|
||||
b+=src[(y<<2)+2]*BLUR_BLUE;
|
||||
r/=100;
|
||||
g/=100;
|
||||
b/=100;
|
||||
|
||||
if(r>255) r=255; if(g>255) g=255; if(b>255) b=255;
|
||||
palettetranslate[x|(y<<8)]=((r>>cshiftr[0])<<cshiftl[0])|
|
||||
((g>>cshiftr[1])<<cshiftl[1])|
|
||||
((b>>cshiftr[2])<<cshiftl[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
for(x=0;x<65536;x++)
|
||||
{
|
||||
uint16 lower,upper;
|
||||
|
||||
lower=(src[((x&255)<<2)]>>cshiftr[0])<<cshiftl[0];
|
||||
lower|=(src[((x&255)<<2)+1]>>cshiftr[1])<<cshiftl[1];
|
||||
lower|=(src[((x&255)<<2)+2]>>cshiftr[2])<<cshiftl[2];
|
||||
upper=(src[((x>>8)<<2)]>>cshiftr[0])<<cshiftl[0];
|
||||
upper|=(src[((x>>8)<<2)+1]>>cshiftr[1])<<cshiftl[1];
|
||||
upper|=(src[((x>>8)<<2)+2]>>cshiftr[2])<<cshiftl[2];
|
||||
|
||||
palettetranslate[x]=lower|(upper<<16);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
for(x=0;x<256;x++)
|
||||
{
|
||||
uint32 r,g,b;
|
||||
|
||||
if(!(highefx&FVB_BLUR))
|
||||
{
|
||||
r=src[x<<2];
|
||||
g=src[(x<<2)+1];
|
||||
b=src[(x<<2)+2];
|
||||
palettetranslate[x]=(r<<cshiftl[0])|(g<<cshiftl[1])|(b<<cshiftl[2]);
|
||||
}
|
||||
else
|
||||
for(y=0;y<256;y++)
|
||||
{
|
||||
r=src[x<<2]*(100-BLUR_RED);
|
||||
g=src[(x<<2)+1]*(100-BLUR_GREEN);
|
||||
b=src[(x<<2)+2]*(100-BLUR_BLUE);
|
||||
|
||||
r+=src[y<<2]*BLUR_RED;
|
||||
g+=src[(y<<2)+1]*BLUR_GREEN;
|
||||
b+=src[(y<<2)+2]*BLUR_BLUE;
|
||||
|
||||
r/=100;
|
||||
g/=100;
|
||||
b/=100;
|
||||
if(r>255) r=255; if(g>255) g=255; if(b>255) b=255;
|
||||
|
||||
palettetranslate[x|(y<<8)]=(r<<cshiftl[0])|(g<<cshiftl[1])|(b<<cshiftl[2]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void Blit32to24(uint32 *src, uint8 *dest, int xr, int yr, int dpitch)
|
||||
{
|
||||
int x,y;
|
||||
|
||||
for(y=yr;y;y--)
|
||||
{
|
||||
for(x=xr;x;x--)
|
||||
{
|
||||
uint32 tmp = *src;
|
||||
*dest = tmp;
|
||||
dest++;
|
||||
*dest = tmp>>8;
|
||||
dest++;
|
||||
*dest = tmp>>16;
|
||||
dest++;
|
||||
src++;
|
||||
}
|
||||
dest += dpitch / 3 - xr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void Blit32to16(uint32 *src, uint16 *dest, int xr, int yr, int dpitch,
|
||||
int shiftr[3], int shiftl[3])
|
||||
{
|
||||
int x,y;
|
||||
//printf("%d\n",shiftl[1]);
|
||||
for(y=yr;y;y--)
|
||||
{
|
||||
for(x=xr;x;x--)
|
||||
{
|
||||
uint32 tmp = *src;
|
||||
uint16 dtmp;
|
||||
|
||||
// Begin iffy code
|
||||
//dtmp = (tmp & backmask[2]) >> shiftr[2];
|
||||
//dtmp |= (tmp & backmask[1]) >> shiftr[1];
|
||||
//dtmp |= (tmp & backmask[0]) >> shiftr[0];
|
||||
// End iffy code
|
||||
|
||||
// Begin non-iffy code
|
||||
dtmp = ((tmp&0x0000FF) >> shiftr[2]) << shiftl[2];
|
||||
dtmp |= ((tmp&0x00FF00) >> shiftr[1]) << shiftl[1];
|
||||
dtmp |= ((tmp&0xFF0000) >> shiftr[0]) << shiftl[0];
|
||||
// End non-iffy code
|
||||
|
||||
//dtmp = ((tmp&0x0000FF) >> 3);
|
||||
//dtmp |= ((tmp&0x00FC00) >>5);
|
||||
//dtmp |= ((tmp&0xF80000) >>8);
|
||||
|
||||
*dest = dtmp;
|
||||
src++;
|
||||
dest++;
|
||||
}
|
||||
dest += dpitch / 2 - xr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Blit8To8(uint8 *src, uint8 *dest, int xr, int yr, int pitch, int xscale, int yscale, int efx, int special)
|
||||
{
|
||||
int x,y;
|
||||
int pinc;
|
||||
|
||||
if(special==2)
|
||||
{
|
||||
if(xscale!=2 || yscale!=2) return;
|
||||
|
||||
scale(2,dest,pitch,src,256,1,xr,yr);
|
||||
return;
|
||||
}
|
||||
|
||||
if(special==4)
|
||||
{
|
||||
if(xscale!=3 || yscale!=3) return;
|
||||
scale(3,dest,pitch,src,256,1,xr,yr);
|
||||
return;
|
||||
}
|
||||
|
||||
pinc=pitch-(xr*xscale);
|
||||
if(xscale!=1 || yscale!=1)
|
||||
{
|
||||
if(efx&FVB_SCANLINES)
|
||||
{
|
||||
for(y=yr;y;y--,src+=256-xr)
|
||||
{
|
||||
int doo=yscale-(yscale>>1);
|
||||
do
|
||||
{
|
||||
for(x=xr;x;x--,src++)
|
||||
{
|
||||
int too=xscale;
|
||||
do
|
||||
{
|
||||
*(uint8 *)dest=*(uint8 *)src;
|
||||
dest++;
|
||||
} while(--too);
|
||||
}
|
||||
src-=xr;
|
||||
dest+=pinc;
|
||||
} while(--doo);
|
||||
//src-=xr*(yscale-(yscale>>1));
|
||||
dest+=pitch*(yscale>>1);
|
||||
|
||||
src+=xr;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
for(y=yr;y;y--,src+=256-xr)
|
||||
{
|
||||
int doo=yscale;
|
||||
do
|
||||
{
|
||||
for(x=xr;x;x--,src++)
|
||||
{
|
||||
int too=xscale;
|
||||
do
|
||||
{
|
||||
*(uint8 *)dest=*(uint8 *)src;
|
||||
dest++;
|
||||
} while(--too);
|
||||
}
|
||||
src-=xr;
|
||||
dest+=pinc;
|
||||
} while(--doo);
|
||||
src+=xr;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
for(y=yr;y;y--,dest+=pinc,src+=256-xr)
|
||||
for(x=xr;x;x-=4,dest+=4,src+=4)
|
||||
*(uint32 *)dest=*(uint32 *)src;
|
||||
}
|
||||
}
|
||||
|
||||
/* Todo: Make sure 24bpp code works right with big-endian cpus */
|
||||
|
||||
void Blit8ToHigh(uint8 *src, uint8 *dest, int xr, int yr, int pitch,
|
||||
int xscale, int yscale)
|
||||
{
|
||||
int x,y;
|
||||
int pinc;
|
||||
uint8 *destbackup = NULL; /* For hq2x */
|
||||
int pitchbackup = 0;
|
||||
|
||||
//static int google=0;
|
||||
//google^=1;
|
||||
|
||||
if(specbuf8bpp) // 2xscale/3xscale
|
||||
{
|
||||
int mult;
|
||||
int base;
|
||||
|
||||
if(silt == 2) mult = 2;
|
||||
else mult = 3;
|
||||
|
||||
Blit8To8(src, specbuf8bpp, xr, yr, 256*mult, xscale, yscale, 0, silt);
|
||||
|
||||
xr *= mult;
|
||||
yr *= mult;
|
||||
xscale=yscale=1;
|
||||
src = specbuf8bpp;
|
||||
base = 256*mult;
|
||||
|
||||
switch(Bpp)
|
||||
{
|
||||
case 4:
|
||||
pinc=pitch-(xr<<2);
|
||||
for(y=yr;y;y--,src+=base-xr)
|
||||
{
|
||||
for(x=xr;x;x--)
|
||||
{
|
||||
*(uint32 *)dest=palettetranslate[(uint32)*src];
|
||||
dest+=4;
|
||||
src++;
|
||||
}
|
||||
dest+=pinc;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
pinc=pitch-(xr+xr+xr);
|
||||
for(y=yr;y;y--,src+=base-xr)
|
||||
{
|
||||
for(x=xr;x;x--)
|
||||
{
|
||||
uint32 tmp=palettetranslate[(uint32)*src];
|
||||
*(uint8 *)dest=tmp;
|
||||
*((uint8 *)dest+1)=tmp>>8;
|
||||
*((uint8 *)dest+2)=tmp>>16;
|
||||
dest+=3;
|
||||
src++;
|
||||
src++;
|
||||
}
|
||||
dest+=pinc;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
pinc=pitch-(xr<<1);
|
||||
|
||||
for(y=yr;y;y--,src+=base-xr)
|
||||
{
|
||||
for(x=xr>>1;x;x--)
|
||||
{
|
||||
*(uint32 *)dest=palettetranslate[*(uint16 *)src];
|
||||
dest+=4;
|
||||
src+=2;
|
||||
}
|
||||
dest+=pinc;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if(specbuf)
|
||||
{
|
||||
destbackup=dest;
|
||||
dest=(uint8 *)specbuf;
|
||||
pitchbackup=pitch;
|
||||
|
||||
pitch=xr*sizeof(uint16);
|
||||
xscale=1;
|
||||
yscale=1;
|
||||
}
|
||||
|
||||
if(highefx&FVB_BLUR) // DONE
|
||||
{
|
||||
if(xscale!=1 || yscale!=1 || (highefx&FVB_SCANLINES)) // DONE
|
||||
{
|
||||
switch(Bpp)
|
||||
{
|
||||
case 4:
|
||||
pinc=pitch-((xr*xscale)<<2);
|
||||
for(y=yr;y;y--,src+=256-xr)
|
||||
{
|
||||
int doo=yscale;
|
||||
|
||||
if(highefx&FVB_SCANLINES)
|
||||
doo-=yscale>>1;
|
||||
do
|
||||
{
|
||||
uint8 last=0x00;
|
||||
|
||||
//if(doo == 1 && google) dest+=4;
|
||||
for(x=xr;x;x--,src++)
|
||||
{
|
||||
int too=xscale;
|
||||
do
|
||||
{
|
||||
*(uint32 *)dest=palettetranslate[*src|(last<<8)];
|
||||
dest+=4;
|
||||
} while(--too);
|
||||
last=*src;
|
||||
}
|
||||
//if(doo == 1 && google) dest-=4;
|
||||
src-=xr;
|
||||
dest+=pinc;
|
||||
} while(--doo);
|
||||
src+=xr;
|
||||
if(highefx&FVB_SCANLINES)
|
||||
dest+=pitch*(yscale>>1);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
pinc=pitch-((xr*xscale)*3);
|
||||
for(y=yr;y;y--,src+=256-xr)
|
||||
{
|
||||
int doo=yscale;
|
||||
|
||||
if(highefx&FVB_SCANLINES)
|
||||
doo-=yscale>>1;
|
||||
do
|
||||
{
|
||||
uint8 last=0x00;
|
||||
for(x=xr;x;x--,src++)
|
||||
{
|
||||
int too=xscale;
|
||||
do
|
||||
{
|
||||
*(uint32 *)dest=palettetranslate[*src|(last<<8)];
|
||||
dest+=3;
|
||||
} while(--too);
|
||||
last=*src;
|
||||
}
|
||||
src-=xr;
|
||||
dest+=pinc;
|
||||
} while(--doo);
|
||||
src+=xr;
|
||||
if(highefx&FVB_SCANLINES)
|
||||
dest+=pitch*(yscale>>1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
pinc=pitch-((xr*xscale)<<1);
|
||||
|
||||
for(y=yr;y;y--,src+=256-xr)
|
||||
{
|
||||
int doo=yscale;
|
||||
|
||||
if(highefx& FVB_SCANLINES)
|
||||
doo-=yscale>>1;
|
||||
do
|
||||
{
|
||||
uint8 last=0x00;
|
||||
for(x=xr;x;x--,src++)
|
||||
{
|
||||
int too=xscale;
|
||||
do
|
||||
{
|
||||
*(uint16 *)dest=palettetranslate[*src|(last<<8)];
|
||||
dest+=2;
|
||||
} while(--too);
|
||||
last=*src;
|
||||
}
|
||||
src-=xr;
|
||||
dest+=pinc;
|
||||
} while(--doo);
|
||||
src+=xr;
|
||||
if(highefx&FVB_SCANLINES)
|
||||
dest+=pitch*(yscale>>1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // No scaling, no scanlines, just blurring. - DONE
|
||||
switch(Bpp)
|
||||
{
|
||||
case 4:
|
||||
pinc=pitch-(xr<<2);
|
||||
for(y=yr;y;y--,src+=256-xr)
|
||||
{
|
||||
uint8 last=0x00;
|
||||
for(x=xr;x;x--)
|
||||
{
|
||||
*(uint32 *)dest=palettetranslate[*src|(last<<8)];
|
||||
last=*src;
|
||||
dest+=4;
|
||||
src++;
|
||||
}
|
||||
dest+=pinc;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
pinc=pitch-(xr+xr+xr);
|
||||
for(y=yr;y;y--,src+=256-xr)
|
||||
{
|
||||
uint8 last=0x00;
|
||||
for(x=xr;x;x--)
|
||||
{
|
||||
uint32 tmp=palettetranslate[*src|(last<<8)];
|
||||
last=*src;
|
||||
*(uint8 *)dest=tmp;
|
||||
*((uint8 *)dest+1)=tmp>>8;
|
||||
*((uint8 *)dest+2)=tmp>>16;
|
||||
dest+=3;
|
||||
src++;
|
||||
}
|
||||
dest+=pinc;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
pinc=pitch-(xr<<1);
|
||||
for(y=yr;y;y--,src+=256-xr)
|
||||
{
|
||||
uint8 last=0x00;
|
||||
for(x=xr;x;x--)
|
||||
{
|
||||
*(uint16 *)dest=palettetranslate[*src|(last<<8)];
|
||||
last=*src;
|
||||
dest+=2;
|
||||
src++;
|
||||
}
|
||||
dest+=pinc;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // No blur effects.
|
||||
{
|
||||
if(xscale!=1 || yscale!=1 || (highefx&FVB_SCANLINES))
|
||||
{
|
||||
switch(Bpp)
|
||||
{
|
||||
case 4:
|
||||
pinc=pitch-((xr*xscale)<<2);
|
||||
for(y=yr;y;y--,src+=256-xr)
|
||||
{
|
||||
int doo=yscale;
|
||||
|
||||
if(highefx& FVB_SCANLINES)
|
||||
doo-=yscale>>1;
|
||||
do
|
||||
{
|
||||
for(x=xr;x;x--,src++)
|
||||
{
|
||||
int too=xscale;
|
||||
do
|
||||
{
|
||||
*(uint32 *)dest=palettetranslate[*src];
|
||||
dest+=4;
|
||||
} while(--too);
|
||||
}
|
||||
src-=xr;
|
||||
dest+=pinc;
|
||||
} while(--doo);
|
||||
src+=xr;
|
||||
if(highefx&FVB_SCANLINES)
|
||||
dest+=pitch*(yscale>>1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
pinc=pitch-((xr*xscale)*3);
|
||||
for(y=yr;y;y--,src+=256-xr)
|
||||
{
|
||||
int doo=yscale;
|
||||
|
||||
if(highefx& FVB_SCANLINES)
|
||||
doo-=yscale>>1;
|
||||
do
|
||||
{
|
||||
for(x=xr;x;x--,src++)
|
||||
{
|
||||
int too=xscale;
|
||||
do
|
||||
{
|
||||
uint32 tmp=palettetranslate[(uint32)*src];
|
||||
*(uint8 *)dest=tmp;
|
||||
*((uint8 *)dest+1)=tmp>>8;
|
||||
*((uint8 *)dest+2)=tmp>>16;
|
||||
dest+=3;
|
||||
|
||||
//*(uint32 *)dest=palettetranslate[*src];
|
||||
//dest+=4;
|
||||
} while(--too);
|
||||
}
|
||||
src-=xr;
|
||||
dest+=pinc;
|
||||
} while(--doo);
|
||||
src+=xr;
|
||||
if(highefx&FVB_SCANLINES)
|
||||
dest+=pitch*(yscale>>1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
pinc=pitch-((xr*xscale)<<1);
|
||||
|
||||
for(y=yr;y;y--,src+=256-xr)
|
||||
{
|
||||
int doo=yscale;
|
||||
|
||||
if(highefx& FVB_SCANLINES)
|
||||
doo-=yscale>>1;
|
||||
do
|
||||
{
|
||||
for(x=xr;x;x--,src++)
|
||||
{
|
||||
int too=xscale;
|
||||
do
|
||||
{
|
||||
*(uint16 *)dest=palettetranslate[*src];
|
||||
dest+=2;
|
||||
} while(--too);
|
||||
}
|
||||
src-=xr;
|
||||
dest+=pinc;
|
||||
} while(--doo);
|
||||
src+=xr;
|
||||
if(highefx&FVB_SCANLINES)
|
||||
dest+=pitch*(yscale>>1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
switch(Bpp)
|
||||
{
|
||||
case 4:
|
||||
pinc=pitch-(xr<<2);
|
||||
for(y=yr;y;y--,src+=256-xr)
|
||||
{
|
||||
for(x=xr;x;x--)
|
||||
{
|
||||
*(uint32 *)dest=palettetranslate[(uint32)*src];
|
||||
dest+=4;
|
||||
src++;
|
||||
}
|
||||
dest+=pinc;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
pinc=pitch-(xr+xr+xr);
|
||||
for(y=yr;y;y--,src+=256-xr)
|
||||
{
|
||||
for(x=xr;x;x--)
|
||||
{
|
||||
uint32 tmp=palettetranslate[(uint32)*src];
|
||||
*(uint8 *)dest=tmp;
|
||||
*((uint8 *)dest+1)=tmp>>8;
|
||||
*((uint8 *)dest+2)=tmp>>16;
|
||||
dest+=3;
|
||||
src++;
|
||||
}
|
||||
dest+=pinc;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
pinc=pitch-(xr<<1);
|
||||
|
||||
for(y=yr;y;y--,src+=256-xr)
|
||||
{
|
||||
for(x=xr>>1;x;x--)
|
||||
{
|
||||
*(uint32 *)dest=palettetranslate[*(uint16 *)src];
|
||||
dest+=4;
|
||||
src+=2;
|
||||
}
|
||||
dest+=pinc;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(specbuf)
|
||||
{
|
||||
if(specbuf32bpp)
|
||||
{
|
||||
int mult = (silt == 3)?3:2;
|
||||
|
||||
if(silt == 3)
|
||||
hq3x_32((uint8 *)specbuf,(uint8*)specbuf32bpp,xr,yr,xr*3*sizeof(uint32));
|
||||
else
|
||||
hq2x_32((uint8 *)specbuf,(uint8*)specbuf32bpp,xr,yr,xr*2*sizeof(uint32));
|
||||
|
||||
if(backBpp == 2)
|
||||
Blit32to16(specbuf32bpp, (uint16*)destbackup, xr*mult, yr*mult, pitchbackup, backshiftr,backshiftl);
|
||||
else // == 3
|
||||
Blit32to24(specbuf32bpp, (uint8*)destbackup, xr*mult, yr*mult, pitchbackup);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(silt == 3)
|
||||
hq3x_32((uint8 *)specbuf,destbackup,xr,yr,pitchbackup);
|
||||
else
|
||||
hq2x_32((uint8 *)specbuf,destbackup,xr,yr,pitchbackup);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
int InitBlitToHigh(int b, uint32 rmask, uint32 gmask, uint32 bmask, int eefx, int specfilt);
|
||||
void SetPaletteBlitToHigh(uint8 *src);
|
||||
void KillBlitToHigh(void);
|
||||
void Blit8ToHigh(uint8 *src, uint8 *dest, int xr, int yr, int pitch, int xscale, int yscale);
|
||||
void Blit8To8(uint8 *src, uint8 *dest, int xr, int yr, int pitch, int xscale, int yscale, int efx, int special);
|
@ -31,7 +31,6 @@
|
||||
#include "netplay.h"
|
||||
#include "general.h"
|
||||
#include "endian.h"
|
||||
#include "memory.h"
|
||||
|
||||
#include "cart.h"
|
||||
#include "nsf.h"
|
||||
@ -41,7 +40,6 @@
|
||||
#include "cheat.h"
|
||||
#include "palette.h"
|
||||
#include "state.h"
|
||||
#include "movie.h"
|
||||
#include "video.h"
|
||||
#include "input.h"
|
||||
#include "file.h"
|
||||
@ -74,9 +72,9 @@ static DECLFR(ANull)
|
||||
|
||||
int AllocGenieRW(void)
|
||||
{
|
||||
if(!(AReadG=(readfunc *)FCEU_malloc(0x8000*sizeof(readfunc))))
|
||||
if(!(AReadG=(readfunc *)malloc(0x8000*sizeof(readfunc))))
|
||||
return 0;
|
||||
if(!(BWriteG=(writefunc *)FCEU_malloc(0x8000*sizeof(writefunc))))
|
||||
if(!(BWriteG=(writefunc *)malloc(0x8000*sizeof(writefunc))))
|
||||
return 0;
|
||||
RWWrap=1;
|
||||
return 1;
|
||||
@ -279,7 +277,6 @@ FCEUGI *FCEUI_LoadGame(const char *name)
|
||||
|
||||
PowerNES();
|
||||
FCEUSS_CheckStates();
|
||||
FCEUMOV_CheckMovies();
|
||||
|
||||
if(FCEUGameInfo->type!=GIT_NSF)
|
||||
{
|
||||
@ -340,7 +337,6 @@ void FCEUI_CloseGame(void)
|
||||
|
||||
void ResetNES(void)
|
||||
{
|
||||
FCEUMOV_AddCommand(FCEUNPCMD_RESET);
|
||||
if(!FCEUGameInfo) return;
|
||||
GameInterface(GI_RESETM2);
|
||||
FCEUSND_Reset();
|
||||
@ -367,8 +363,7 @@ void hand(X6502 *X, int type, unsigned int A)
|
||||
|
||||
void PowerNES(void)
|
||||
{
|
||||
FCEUMOV_AddCommand(FCEUNPCMD_POWER);
|
||||
if(!FCEUGameInfo) return;
|
||||
if(!FCEUGameInfo) return;
|
||||
|
||||
FCEU_CheatResetRAM();
|
||||
FCEU_CheatAddRAM(2,0,RAM);
|
||||
|
@ -13,7 +13,7 @@ fceustr *fceustr_create(const char *str)
|
||||
ret=malloc(sizeof(fceustr));
|
||||
|
||||
ret->data=malloc(strlen(str)+1);
|
||||
strcpy(ret->data,str);
|
||||
strcpy((char *)ret->data,str);
|
||||
|
||||
ret->len=strlen(str);
|
||||
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "general.h"
|
||||
#include "state.h"
|
||||
#include "file.h"
|
||||
#include "memory.h"
|
||||
#include "cart.h"
|
||||
#include "md5.h"
|
||||
#include "netplay.h"
|
||||
@ -702,7 +701,7 @@ static int SubLoad(FCEUFILE *fp)
|
||||
|
||||
for(x=0;x<TotalSides;x++)
|
||||
{
|
||||
diskdata[x]=(uint8 *)FCEU_malloc(65500);
|
||||
diskdata[x]=(uint8 *)malloc(65500);
|
||||
if(!diskdata[x])
|
||||
{
|
||||
int zol;
|
||||
@ -786,7 +785,7 @@ int FDSLoad(const char *name, FCEUFILE *fp)
|
||||
int x;
|
||||
for(x=0;x<TotalSides;x++)
|
||||
{
|
||||
diskdatao[x]=(uint8 *)FCEU_malloc(65500);
|
||||
diskdatao[x]=(uint8 *)malloc(65500);
|
||||
memcpy(diskdatao[x],diskdata[x],65500);
|
||||
}
|
||||
/* if((tp=FCEU_fopen(fn,0,"rb",0)))
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include "types.h"
|
||||
#include "file.h"
|
||||
#include "endian.h"
|
||||
#include "memory.h"
|
||||
#include "driver.h"
|
||||
#include "general.h"
|
||||
|
||||
@ -127,7 +126,7 @@ static MEMWRAP *MakeMemWrap(void *tz, int type)
|
||||
{
|
||||
MEMWRAP *tmp;
|
||||
|
||||
if(!(tmp=(MEMWRAP *)FCEU_malloc(sizeof(MEMWRAP))))
|
||||
if(!(tmp=(MEMWRAP *)malloc(sizeof(MEMWRAP))))
|
||||
goto doret;
|
||||
tmp->location=0;
|
||||
|
||||
@ -136,7 +135,7 @@ static MEMWRAP *MakeMemWrap(void *tz, int type)
|
||||
fseek((FILE *)tz,0,SEEK_END);
|
||||
tmp->size=ftell((FILE *)tz);
|
||||
fseek((FILE *)tz,0,SEEK_SET);
|
||||
if(!(tmp->data=(uint8*)FCEU_malloc(tmp->size)))
|
||||
if(!(tmp->data=(uint8*)malloc(tmp->size)))
|
||||
{
|
||||
free(tmp);
|
||||
tmp=0;
|
||||
@ -150,7 +149,7 @@ static MEMWRAP *MakeMemWrap(void *tz, int type)
|
||||
but I can't get to the info with the zlib interface(?). */
|
||||
for(tmp->size=0; gzgetc(tz) != EOF; tmp->size++);
|
||||
gzseek(tz,0,SEEK_SET);
|
||||
if(!(tmp->data=(uint8 *)FCEU_malloc(tmp->size)))
|
||||
if(!(tmp->data=(uint8 *)malloc(tmp->size)))
|
||||
{
|
||||
free(tmp);
|
||||
tmp=0;
|
||||
@ -164,7 +163,7 @@ static MEMWRAP *MakeMemWrap(void *tz, int type)
|
||||
unzGetCurrentFileInfo(tz,&ufo,0,0,0,0,0,0);
|
||||
|
||||
tmp->size=ufo.uncompressed_size;
|
||||
if(!(tmp->data=(uint8 *)FCEU_malloc(ufo.uncompressed_size)))
|
||||
if(!(tmp->data=(uint8 *)malloc(ufo.uncompressed_size)))
|
||||
{
|
||||
free(tmp);
|
||||
tmp=0;
|
||||
|
@ -32,7 +32,6 @@
|
||||
|
||||
#include "general.h"
|
||||
#include "state.h"
|
||||
#include "movie.h"
|
||||
|
||||
#include "driver.h"
|
||||
|
||||
@ -60,113 +59,12 @@ void FCEUI_SetDirOverride(int which, char *n)
|
||||
{
|
||||
if(which==FCEUIOD_STATE)
|
||||
FCEUSS_CheckStates();
|
||||
else if(which == FCEUIOD_MOVIE)
|
||||
FCEUMOV_CheckMovies();
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef HAVE_ASPRINTF
|
||||
static int asprintf(char **strp, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
va_start(ap,fmt);
|
||||
if(!(*strp=malloc(2048)))
|
||||
return(0);
|
||||
ret=vsnprintf(*strp,2048,fmt,ap);
|
||||
va_end(ap);
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
char *FCEU_MakeFName(int type, int id1, char *cd1)
|
||||
{
|
||||
char *ret=0;
|
||||
|
||||
/*** REMOVED GC V1.0
|
||||
struct stat tmpstat;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case FCEUMKF_NPTEMP: asprintf(&ret,"%s"PSS"m590plqd94fo.tmp",BaseDirectory);break;
|
||||
case FCEUMKF_MOVIE:if(odirs[FCEUIOD_STATE])
|
||||
asprintf(&ret,"%s"PSS"%s.%d.fcm",odirs[FCEUIOD_STATE],FileBase,id1);
|
||||
else
|
||||
asprintf(&ret,"%s"PSS"fcs"PSS"%s.%d.fcm",BaseDirectory,FileBase,id1);
|
||||
if(stat(ret,&tmpstat)==-1)
|
||||
{
|
||||
if(odirs[FCEUIOD_STATE])
|
||||
asprintf(&ret,"%s"PSS"%s.%s.%d.fcm",odirs[FCEUIOD_STATE],FileBase,md5_asciistr(FCEUGameInfo->MD5),id1);
|
||||
else
|
||||
asprintf(&ret,"%s"PSS"fcs"PSS"%s.%s.%d.fcm",BaseDirectory,FileBase,md5_asciistr(FCEUGameInfo->MD5),id1);
|
||||
}
|
||||
break;
|
||||
case FCEUMKF_STATE:if(odirs[FCEUIOD_STATE])
|
||||
asprintf(&ret,"%s"PSS"%s.fc%d",odirs[FCEUIOD_STATE],FileBase,id1);
|
||||
else
|
||||
asprintf(&ret,"%s"PSS"fcs"PSS"%s.fc%d",BaseDirectory,FileBase,id1);
|
||||
if(stat(ret,&tmpstat)==-1)
|
||||
{
|
||||
if(odirs[FCEUIOD_STATE])
|
||||
asprintf(&ret,"%s"PSS"%s.%s.fc%d",odirs[FCEUIOD_STATE],FileBase,md5_asciistr(FCEUGameInfo->MD5),id1);
|
||||
else
|
||||
asprintf(&ret,"%s"PSS"fcs"PSS"%s.%s.fc%d",BaseDirectory,FileBase,md5_asciistr(FCEUGameInfo->MD5),id1);
|
||||
}
|
||||
break;
|
||||
case FCEUMKF_SNAP:
|
||||
if(FSettings.SnapName)
|
||||
{
|
||||
if(odirs[FCEUIOD_SNAPS])
|
||||
asprintf(&ret,"%s"PSS"%s-%d.%s",odirs[FCEUIOD_SNAPS],FileBase,id1,cd1);
|
||||
else
|
||||
asprintf(&ret,"%s"PSS"snaps"PSS"%s-%d.%s",BaseDirectory,FileBase,id1,cd1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(odirs[FCEUIOD_SNAPS])
|
||||
asprintf(&ret,"%s"PSS"%d.%s",odirs[FCEUIOD_SNAPS],id1,cd1);
|
||||
else
|
||||
asprintf(&ret,"%s"PSS"snaps"PSS"%d.%s",BaseDirectory,id1,cd1);
|
||||
}
|
||||
break;
|
||||
case FCEUMKF_FDS:if(odirs[FCEUIOD_NV])
|
||||
asprintf(&ret,"%s"PSS"%s.%s.fds",odirs[FCEUIOD_NV],FileBase,md5_asciistr(FCEUGameInfo->MD5));
|
||||
else
|
||||
asprintf(&ret,"%s"PSS"sav"PSS"%s.%s.fds",BaseDirectory,FileBase,md5_asciistr(FCEUGameInfo->MD5));
|
||||
break;
|
||||
case FCEUMKF_SAV:if(odirs[FCEUIOD_NV])
|
||||
asprintf(&ret,"%s"PSS"%s.%s",odirs[FCEUIOD_NV],FileBase,cd1);
|
||||
else
|
||||
asprintf(&ret,"%s"PSS"sav"PSS"%s.%s",BaseDirectory,FileBase,cd1);
|
||||
if(stat(ret,&tmpstat)==-1)
|
||||
{
|
||||
if(odirs[FCEUIOD_NV])
|
||||
asprintf(&ret,"%s"PSS"%s.%s.%s",odirs[FCEUIOD_NV],FileBase,md5_asciistr(FCEUGameInfo->MD5),cd1);
|
||||
else
|
||||
asprintf(&ret,"%s"PSS"sav"PSS"%s.%s.%s",BaseDirectory,FileBase,md5_asciistr(FCEUGameInfo->MD5),cd1);
|
||||
}
|
||||
break;
|
||||
case FCEUMKF_CHEAT:
|
||||
if(odirs[FCEUIOD_CHEATS])
|
||||
asprintf(&ret,"%s"PSS"%s.cht",odirs[FCEUIOD_CHEATS],FileBase);
|
||||
else
|
||||
asprintf(&ret,"%s"PSS"cheats"PSS"%s.cht",BaseDirectory,FileBase);
|
||||
break;
|
||||
case FCEUMKF_IPS: asprintf(&ret,"%s"PSS"%s%s.ips",FileBaseDirectory,FileBase,FileExt);
|
||||
break;
|
||||
case FCEUMKF_GGROM:asprintf(&ret,"%s"PSS"gg.rom",BaseDirectory);break;
|
||||
case FCEUMKF_FDSROM:asprintf(&ret,"%s"PSS"disksys.rom",BaseDirectory);break;
|
||||
case FCEUMKF_PALETTE:
|
||||
if(odirs[FCEUIOD_MISC])
|
||||
asprintf(&ret,"%s"PSS"%s.pal",odirs[FCEUIOD_MISC],FileBase);
|
||||
else
|
||||
asprintf(&ret,"%s"PSS"gameinfo"PSS"%s.pal",BaseDirectory,FileBase);
|
||||
break;
|
||||
}
|
||||
|
||||
REMOVED GC V1.0 ***/
|
||||
return(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void GetFileBase(const char *f)
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "general.h"
|
||||
#include "state.h"
|
||||
#include "file.h"
|
||||
#include "memory.h"
|
||||
#include "crc32.h"
|
||||
#include "md5.h"
|
||||
#include "cheat.h"
|
||||
@ -110,7 +109,7 @@ static void iNESGI(int h)
|
||||
if(ROM) {free(ROM);ROM=0;}
|
||||
if(VROM) {free(VROM);VROM=0;}
|
||||
if(MapClose) MapClose();
|
||||
if(trainerpoo) {FCEU_gfree(trainerpoo);trainerpoo=0;}
|
||||
if(trainerpoo) {free(trainerpoo);trainerpoo=0;}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -612,11 +611,11 @@ int iNESLoad(const char *name, FCEUFILE *fp)
|
||||
|
||||
if(head.ROM_type&8) Mirroring=2;
|
||||
|
||||
if(!(ROM=(uint8 *)FCEU_malloc(ROM_size<<14)))
|
||||
if(!(ROM=(uint8 *)malloc(ROM_size<<14)))
|
||||
return 0;
|
||||
|
||||
if (VROM_size)
|
||||
if(!(VROM=(uint8 *)FCEU_malloc(VROM_size<<13)))
|
||||
if(!(VROM=(uint8 *)malloc(VROM_size<<13)))
|
||||
{
|
||||
free(ROM);
|
||||
return 0;
|
||||
@ -626,7 +625,7 @@ int iNESLoad(const char *name, FCEUFILE *fp)
|
||||
if(VROM_size) memset(VROM,0xFF,VROM_size<<13);
|
||||
if(head.ROM_type&4) /* Trainer */
|
||||
{
|
||||
trainerpoo=(uint8 *)FCEU_gmalloc(512);
|
||||
trainerpoo=(uint8 *)malloc(512);
|
||||
FCEU_fread(trainerpoo,512,1,fp);
|
||||
}
|
||||
|
||||
@ -846,10 +845,10 @@ void (*MapInitTab[256])(void)=
|
||||
0,Mapper2_init,Mapper3_init,0,
|
||||
0,Mapper6_init,Mapper7_init,Mapper8_init,
|
||||
Mapper9_init,Mapper10_init,0,0,
|
||||
Mapper13_init,0,0,Mapper16_init,
|
||||
Mapper13_init,0,Mapper15_init,Mapper16_init,
|
||||
Mapper17_init,Mapper18_init,0,0,
|
||||
Mapper21_init,Mapper22_init,Mapper23_init,Mapper24_init,
|
||||
Mapper25_init,Mapper26_init,0,0,
|
||||
Mapper25_init,Mapper26_init,Mapper27_init,0,
|
||||
0,0,0,Mapper32_init,
|
||||
Mapper33_init,Mapper34_init,0,0,
|
||||
0,0,0,Mapper40_init,
|
||||
@ -874,7 +873,7 @@ void (*MapInitTab[256])(void)=
|
||||
0,0,0,0,0,0,0,0,
|
||||
0,0,Mapper151_init,0,Mapper153_init,Mapper154_init,0,Mapper156_init,
|
||||
Mapper157_init,Mapper158_init,Mapper159_init,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,
|
||||
0,Mapper166_init,Mapper167_init,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,Mapper185_init,0,0,0,
|
||||
Mapper189_init,0,0,0,Mapper193_init,0,0,0,
|
||||
@ -883,7 +882,7 @@ void (*MapInitTab[256])(void)=
|
||||
0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,Mapper225_init,Mapper226_init,Mapper227_init,Mapper228_init,
|
||||
Mapper229_init,Mapper230_init,Mapper231_init,Mapper232_init,0,Mapper234_init,Mapper235_init,0,
|
||||
0,0,0,0,Mapper241_init,0,0,Mapper244_init,
|
||||
0,0,0,0,Mapper241_init,Mapper242_init,0,Mapper244_init,
|
||||
0,Mapper246_init,0,Mapper248_init,0,0,0,0,0,0,Mapper255_init
|
||||
};
|
||||
|
||||
@ -1058,14 +1057,14 @@ static BMAPPING bmap[] = {
|
||||
{164, Mapper164_Init},
|
||||
{163, Mapper163_Init},
|
||||
//15.c
|
||||
{15, Mapper15_init},
|
||||
//{15, Mapper15_init},
|
||||
//subor.c //warning message
|
||||
{166, Mapper166_init},
|
||||
{167, Mapper167_init},
|
||||
//{166, Mapper166_init},
|
||||
//{167, Mapper167_init},
|
||||
//27.c
|
||||
{27, Mapper27_init},
|
||||
//{27, Mapper27_init},
|
||||
//242.c
|
||||
{242, Mapper242_init},
|
||||
//{242, Mapper242_init},
|
||||
//252.c
|
||||
{252, Mapper252_Init},
|
||||
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include "fceu.h"
|
||||
#include "sound.h"
|
||||
#include "netplay.h"
|
||||
#include "movie.h"
|
||||
#include "state.h"
|
||||
|
||||
#include "input.h"
|
||||
@ -214,7 +213,6 @@ void FCEU_UpdateInput(void)
|
||||
if(coinon) coinon--;
|
||||
|
||||
if(FCEUnetplay) NetplayUpdate(joy);
|
||||
FCEUMOV_AddJoy(joy);
|
||||
|
||||
if(FCEUGameInfo->type==GIT_VSUNI)
|
||||
FCEU_VSUniSwap(&joy[0],&joy[1]);
|
||||
@ -394,10 +392,7 @@ void FCEU_QSimpleCommand(int cmd)
|
||||
FCEUNET_SendCommand(cmd, 0);
|
||||
else
|
||||
{
|
||||
if(!FCEUMOV_IsPlaying())
|
||||
FCEU_DoSimpleCommand(cmd);
|
||||
else
|
||||
FCEUMOV_AddCommand(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,8 +60,8 @@ static void FP_FASTAPASS(2) Update(void *data, int arg)
|
||||
*(uint8 *)data=0;
|
||||
seq=ptr=0;
|
||||
have=1;
|
||||
strcpy(bdata,(uint8 *)data+1);
|
||||
strcpy(&bdata[13],"SUNSOFT");
|
||||
strcpy((char *)bdata,(char *)((uint8 *)data+1));
|
||||
strcpy((char *)&bdata[13],"SUNSOFT");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ void Mapper199_Init(CartInfo *info)
|
||||
mwrap=M199MW;
|
||||
info->Power=M199Power;
|
||||
int CHRRAMSize=1024*8;
|
||||
CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
|
||||
CHRRAM=(uint8*)malloc(CHRRAMSize);
|
||||
SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
|
||||
AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
|
||||
AddExState(EXPREGS, 4, 0, "EXPR");
|
||||
|
@ -88,7 +88,7 @@ void Mapper252_Init(CartInfo *info)
|
||||
mwrap=M252MW;
|
||||
info->Power=M252Power;
|
||||
int CHRRAMSize=1024*8;
|
||||
CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
|
||||
CHRRAM=(uint8*)malloc(CHRRAMSize);
|
||||
SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
|
||||
AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
|
||||
AddExState(EXPREGS, 4, 0, "EXPR");
|
||||
|
@ -8,3 +8,4 @@
|
||||
#include "../state.h"
|
||||
#include "../cheat.h"
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
@ -308,9 +308,9 @@ static void GenMMC1Power(void)
|
||||
static void GenMMC1Close(void)
|
||||
{
|
||||
if(CHRRAM)
|
||||
FCEU_gfree(CHRRAM);
|
||||
free(CHRRAM);
|
||||
if(WRAM)
|
||||
FCEU_gfree(WRAM);
|
||||
free(WRAM);
|
||||
CHRRAM=WRAM=NULL;
|
||||
}
|
||||
|
||||
@ -327,7 +327,7 @@ static void GenMMC1Init(CartInfo *info, int prg, int chr, int wram, int battery)
|
||||
|
||||
if(wram)
|
||||
{
|
||||
WRAM=(uint8*)FCEU_gmalloc(wram*1024);
|
||||
WRAM=(uint8*)malloc(wram*1024);
|
||||
mmc1opts|=1;
|
||||
if(wram>8) mmc1opts|=4;
|
||||
SetupCartPRGMapping(0x10,WRAM,wram*1024,1);
|
||||
@ -343,7 +343,7 @@ static void GenMMC1Init(CartInfo *info, int prg, int chr, int wram, int battery)
|
||||
}
|
||||
if(!chr)
|
||||
{
|
||||
CHRRAM=(uint8*)FCEU_gmalloc(8192);
|
||||
CHRRAM=(uint8*)malloc(8192);
|
||||
SetupCartCHRMapping(0, CHRRAM, 8192, 1);
|
||||
AddExState(CHRRAM, 8192, 0, "CHRR");
|
||||
}
|
||||
|
@ -303,9 +303,9 @@ void GenMMC3Power(void)
|
||||
static void GenMMC3Close(void)
|
||||
{
|
||||
if(CHRRAM)
|
||||
FCEU_gfree(CHRRAM);
|
||||
free(CHRRAM);
|
||||
if(WRAM)
|
||||
FCEU_gfree(WRAM);
|
||||
free(WRAM);
|
||||
CHRRAM=WRAM=NULL;
|
||||
}
|
||||
|
||||
@ -333,7 +333,7 @@ void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery)
|
||||
if(wram)
|
||||
{
|
||||
mmc3opts|=1;
|
||||
WRAM=(uint8*)FCEU_gmalloc(wrams);
|
||||
WRAM=(uint8*)malloc(wrams);
|
||||
AddExState(WRAM, wrams, 0, "WRAM");
|
||||
}
|
||||
|
||||
@ -757,7 +757,7 @@ void Mapper74_Init(CartInfo *info)
|
||||
GenMMC3_Init(info, 512, 256, 8, info->battery);
|
||||
cwrap=M74CW;
|
||||
CHRRAMSize=2048;
|
||||
CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
|
||||
CHRRAM=(uint8*)malloc(CHRRAMSize);
|
||||
SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
|
||||
AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
|
||||
}
|
||||
@ -902,7 +902,7 @@ void Mapper116_Init(CartInfo *info)
|
||||
GenMMC3_Init(info, 128, 512, 0, 0);
|
||||
cwrap=M116CW;
|
||||
info->Power=M116Power;
|
||||
CHRRAM = (uint8*)FCEU_gmalloc(8192);
|
||||
CHRRAM = (uint8*)malloc(8192);
|
||||
SetupCartCHRMapping(0x10, CHRRAM, 8192, 1);
|
||||
AddExState(EXPREGS, 4, 0, "EXPR");
|
||||
}
|
||||
@ -949,7 +949,7 @@ void Mapper119_Init(CartInfo *info)
|
||||
GenMMC3_Init(info, 512, 64, 0, 0);
|
||||
cwrap=TQWRAP;
|
||||
CHRRAMSize=8192;
|
||||
CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
|
||||
CHRRAM=(uint8*)malloc(CHRRAMSize);
|
||||
SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
|
||||
}
|
||||
|
||||
@ -1015,7 +1015,7 @@ void Mapper165_Init(CartInfo *info)
|
||||
PPU_hook=M165PPU;
|
||||
info->Power=M165Power;
|
||||
CHRRAMSize = 4096;
|
||||
CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSize);
|
||||
CHRRAM = (uint8*)malloc(CHRRAMSize);
|
||||
SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
|
||||
AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
|
||||
AddExState(EXPREGS, 4, 0, "EXPR");
|
||||
@ -1068,7 +1068,7 @@ void Mapper191_Init(CartInfo *info)
|
||||
GenMMC3_Init(info, 256, 256, 8, info->battery);
|
||||
cwrap=M191CW;
|
||||
CHRRAMSize=2048;
|
||||
CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
|
||||
CHRRAM=(uint8*)malloc(CHRRAMSize);
|
||||
SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
|
||||
AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
|
||||
}
|
||||
@ -1088,7 +1088,7 @@ void Mapper192_Init(CartInfo *info)
|
||||
GenMMC3_Init(info, 512, 256, 8, info->battery);
|
||||
cwrap=M192CW;
|
||||
CHRRAMSize=4096;
|
||||
CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
|
||||
CHRRAM=(uint8*)malloc(CHRRAMSize);
|
||||
SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
|
||||
AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
|
||||
}
|
||||
@ -1108,7 +1108,7 @@ void Mapper194_Init(CartInfo *info)
|
||||
GenMMC3_Init(info, 512, 256, 8, info->battery);
|
||||
cwrap=M194CW;
|
||||
CHRRAMSize=2048;
|
||||
CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
|
||||
CHRRAM=(uint8*)malloc(CHRRAMSize);
|
||||
SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
|
||||
AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
|
||||
}
|
||||
@ -1136,7 +1136,7 @@ static void M195Power(void)
|
||||
static void M195Close(void)
|
||||
{
|
||||
if(wramtw)
|
||||
FCEU_gfree(wramtw);
|
||||
free(wramtw);
|
||||
wramtw=NULL;
|
||||
}
|
||||
|
||||
@ -1147,10 +1147,10 @@ void Mapper195_Init(CartInfo *info)
|
||||
info->Power=M195Power;
|
||||
info->Close=M195Close;
|
||||
CHRRAMSize=4096;
|
||||
CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
|
||||
CHRRAM=(uint8*)malloc(CHRRAMSize);
|
||||
SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
|
||||
wramsize=4096;
|
||||
wramtw=(uint8*)FCEU_gmalloc(wramsize);
|
||||
wramtw=(uint8*)malloc(wramsize);
|
||||
SetupCartPRGMapping(0x10, wramtw, wramsize, 1);
|
||||
AddExState(CHRRAM, CHRRAMSize, 0, "CHRR");
|
||||
AddExState(wramtw, wramsize, 0, "WRAMTW");
|
||||
@ -1184,7 +1184,7 @@ void Mapper198_Init(CartInfo *info)
|
||||
info->Power=M195Power;
|
||||
info->Close=M195Close;
|
||||
wramsize=4096;
|
||||
wramtw=(uint8*)FCEU_gmalloc(wramsize);
|
||||
wramtw=(uint8*)malloc(wramsize);
|
||||
SetupCartPRGMapping(0x10, wramtw, wramsize, 1);
|
||||
AddExState(wramtw, wramsize, 0, "WRAMTW");
|
||||
}
|
||||
@ -1603,7 +1603,7 @@ void TQROM_Init(CartInfo *info)
|
||||
GenMMC3_Init(info, 512, 64, 0, 0);
|
||||
cwrap=TQWRAP;
|
||||
CHRRAMSize=8192;
|
||||
CHRRAM=(uint8*)FCEU_gmalloc(CHRRAMSize);
|
||||
CHRRAM=(uint8*)malloc(CHRRAMSize);
|
||||
SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1);
|
||||
}
|
||||
|
||||
|
@ -685,7 +685,7 @@ void NSFMMC5_Init(void)
|
||||
{
|
||||
memset(&MMC5Sound,0,sizeof(MMC5Sound));
|
||||
mul[0]=mul[1]=0;
|
||||
ExRAM=(uint8*)FCEU_gmalloc(1024);
|
||||
ExRAM=(uint8*)malloc(1024);
|
||||
Mapper5_ESI();
|
||||
SetWriteHandler(0x5c00,0x5fef,MMC5_ExRAMWr);
|
||||
SetReadHandler(0x5c00,0x5fef,MMC5_ExRAMRd);
|
||||
@ -697,7 +697,7 @@ void NSFMMC5_Init(void)
|
||||
|
||||
void NSFMMC5_Close(void)
|
||||
{
|
||||
FCEU_gfree(ExRAM);
|
||||
free(ExRAM);
|
||||
ExRAM=0;
|
||||
}
|
||||
|
||||
@ -763,13 +763,13 @@ static void GenMMC5_Init(CartInfo *info, int wsize, int battery)
|
||||
{
|
||||
if(wsize)
|
||||
{
|
||||
WRAM=(uint8*)FCEU_gmalloc(wsize*1024);
|
||||
WRAM=(uint8*)malloc(wsize*1024);
|
||||
SetupCartPRGMapping(0x10,WRAM,wsize*1024,1);
|
||||
AddExState(WRAM, wsize*1024, 0, "WRAM");
|
||||
}
|
||||
|
||||
MMC5fill=(uint8*)FCEU_gmalloc(1024);
|
||||
ExRAM=(uint8*)FCEU_gmalloc(1024);
|
||||
MMC5fill=(uint8*)malloc(1024);
|
||||
ExRAM=(uint8*)malloc(1024);
|
||||
|
||||
AddExState(MMC5_StateRegs, ~0, 0, 0);
|
||||
AddExState(WRAM, wsize*1024, 0, "WRAM");
|
||||
|
@ -1,100 +0,0 @@
|
||||
/* FCE Ultra - NES/Famicom Emulator
|
||||
*
|
||||
* Copyright notice for this file:
|
||||
* Copyright (C) 2002 Xodnizel
|
||||
*
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "fceu.h"
|
||||
#include "memory.h"
|
||||
#include "general.h"
|
||||
|
||||
void *FCEU_gmalloc(uint32 size)
|
||||
{
|
||||
void *ret;
|
||||
ret=malloc(size);
|
||||
if(!ret)
|
||||
{
|
||||
FCEU_PrintError("Error allocating memory! Doing a hard exit.");
|
||||
exit(1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *FCEU_malloc(uint32 size)
|
||||
{
|
||||
void *ret;
|
||||
ret=malloc(size);
|
||||
if(!ret)
|
||||
{
|
||||
FCEU_PrintError("Error allocating memory!");
|
||||
return(0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void FCEU_free(void *ptr) // Might do something with this and FCEU_malloc later...
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void FCEU_gfree(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void FASTAPASS(3) FCEU_memmove(void *d, void *s, uint32 l)
|
||||
{
|
||||
uint32 x;
|
||||
int t;
|
||||
|
||||
/* Type really doesn't matter. */
|
||||
t=(int)d;
|
||||
t|=(int)s;
|
||||
t|=(int)l;
|
||||
|
||||
if(t&3) // Not 4-byte aligned and/or length is not a multiple of 4.
|
||||
{
|
||||
uint8 *tmpd, *tmps;
|
||||
|
||||
tmpd = d;
|
||||
tmps = s;
|
||||
|
||||
for(x=l;x;x--) // This could be optimized further, though(more tests could be performed).
|
||||
{
|
||||
*tmpd=*tmps;
|
||||
tmpd++;
|
||||
tmps++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 *tmpd, *tmps;
|
||||
|
||||
tmpd = d;
|
||||
tmps = s;
|
||||
|
||||
for(x=l>>2;x;x--)
|
||||
{
|
||||
*tmpd=*tmps;
|
||||
tmpd++;
|
||||
tmps++;
|
||||
}
|
||||
}
|
||||
}
|
@ -23,9 +23,3 @@
|
||||
*/
|
||||
|
||||
#define FCEU_dwmemset(d,c,n) {int _x; for(_x=n-4;_x>=0;_x-=4) *(uint32 *)&(d)[_x]=c;}
|
||||
|
||||
void *FCEU_malloc(uint32 size);
|
||||
void *FCEU_gmalloc(uint32 size);
|
||||
void FCEU_gfree(void *ptr);
|
||||
void FCEU_free(void *ptr);
|
||||
void FASTAPASS(3) FCEU_memmove(void *d, void *s, uint32 l);
|
||||
|
@ -1,277 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "input.h"
|
||||
#include "fceu.h"
|
||||
#include "driver.h"
|
||||
#include "state.h"
|
||||
#include "general.h"
|
||||
#include "video.h"
|
||||
|
||||
static int current = 0; // > 0 for recording, < 0 for playback
|
||||
static FILE *slots[10]={0};
|
||||
static uint8 joop[4];
|
||||
static uint32 framets;
|
||||
|
||||
/* Cache variables used for playback. */
|
||||
static uint32 nextts;
|
||||
static int nextd;
|
||||
|
||||
|
||||
static int CurrentMovie = 0;
|
||||
static int MovieShow = 0;
|
||||
|
||||
static int MovieStatus[10];
|
||||
|
||||
static void DoEncode(int joy, int button, int);
|
||||
|
||||
int FCEUMOV_IsPlaying(void)
|
||||
{
|
||||
if(current < 0) return(1);
|
||||
else return(0);
|
||||
}
|
||||
|
||||
void FCEUI_SaveMovie(char *fname)
|
||||
{
|
||||
FILE *fp;
|
||||
char *fn;
|
||||
|
||||
if(current < 0) /* Can't interrupt playback.*/
|
||||
return;
|
||||
|
||||
if(current > 0) /* Stop saving. */
|
||||
{
|
||||
DoEncode(0,0,1); /* Write a dummy timestamp value so that the movie will keep
|
||||
"playing" after user input has stopped.
|
||||
*/
|
||||
fclose(slots[current-1]);
|
||||
MovieStatus[current - 1] = 1;
|
||||
current=0;
|
||||
FCEU_DispMessage("Movie recording stopped.");
|
||||
return;
|
||||
}
|
||||
|
||||
current=CurrentMovie;
|
||||
|
||||
if(fname)
|
||||
fp = FCEUD_UTF8fopen(fname, "wb");
|
||||
else
|
||||
{
|
||||
fp=FCEUD_UTF8fopen(fn=FCEU_MakeFName(FCEUMKF_MOVIE,CurrentMovie,0),"wb");
|
||||
free(fn);
|
||||
}
|
||||
|
||||
if(!fp) return;
|
||||
|
||||
FCEUSS_SaveFP(fp);
|
||||
fseek(fp, 0, SEEK_END);
|
||||
slots[current] = fp;
|
||||
memset(joop,0,sizeof(joop));
|
||||
current++;
|
||||
framets=0;
|
||||
FCEUI_SelectMovie(CurrentMovie); /* Quick hack to display status. */
|
||||
}
|
||||
|
||||
static void StopPlayback(void)
|
||||
{
|
||||
fclose(slots[-1 - current]);
|
||||
current=0;
|
||||
FCEU_DispMessage("Movie playback stopped.");
|
||||
}
|
||||
|
||||
void FCEUMOV_Stop(void)
|
||||
{
|
||||
if(current < 0) StopPlayback();
|
||||
}
|
||||
|
||||
void FCEUI_LoadMovie(char *fname)
|
||||
{
|
||||
FILE *fp;
|
||||
char *fn;
|
||||
|
||||
if(current > 0) /* Can't interrupt recording.*/
|
||||
return;
|
||||
|
||||
if(current < 0) /* Stop playback. */
|
||||
{
|
||||
StopPlayback();
|
||||
return;
|
||||
}
|
||||
|
||||
if(fname)
|
||||
fp = FCEUD_UTF8fopen(fname, "rb");
|
||||
else
|
||||
{
|
||||
fp=FCEUD_UTF8fopen(fn=FCEU_MakeFName(FCEUMKF_MOVIE,CurrentMovie,0),"rb");
|
||||
free(fn);
|
||||
}
|
||||
if(!fp) return;
|
||||
|
||||
if(!FCEUSS_LoadFP(fp)) return;
|
||||
|
||||
current = CurrentMovie;
|
||||
slots[current] = fp;
|
||||
|
||||
memset(joop,0,sizeof(joop));
|
||||
current = -1 - current;
|
||||
framets=0;
|
||||
nextts=0;
|
||||
nextd = -1;
|
||||
MovieStatus[CurrentMovie] = 1;
|
||||
FCEUI_SelectMovie(CurrentMovie); /* Quick hack to display status. */
|
||||
}
|
||||
|
||||
|
||||
static void DoEncode(int joy, int button, int dummy)
|
||||
{
|
||||
uint8 d;
|
||||
|
||||
d = 0;
|
||||
|
||||
if(framets >= 65536)
|
||||
d = 3 << 5;
|
||||
else if(framets >= 256)
|
||||
d = 2 << 5;
|
||||
else if(framets > 0)
|
||||
d = 1 << 5;
|
||||
|
||||
if(dummy) d|=0x80;
|
||||
|
||||
d |= joy << 3;
|
||||
d |= button;
|
||||
|
||||
fputc(d, slots[current - 1]);
|
||||
//printf("Wr: %02x, %d\n",d,slots[current-1]);
|
||||
while(framets)
|
||||
{
|
||||
fputc(framets & 0xff, slots[current - 1]);
|
||||
//printf("Wrts: %02x\n",framets & 0xff);
|
||||
framets >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
void FCEUMOV_AddJoy(uint8 *js)
|
||||
{
|
||||
int x,y;
|
||||
|
||||
if(!current) return; /* Not playback nor recording. */
|
||||
|
||||
if(current < 0) /* Playback */
|
||||
{
|
||||
while(nextts == framets)
|
||||
{
|
||||
int tmp,ti;
|
||||
uint8 d;
|
||||
|
||||
if(nextd != -1)
|
||||
{
|
||||
if(nextd&0x80)
|
||||
{
|
||||
//puts("Egads");
|
||||
FCEU_DoSimpleCommand(nextd&0x1F);
|
||||
}
|
||||
else
|
||||
joop[(nextd >> 3)&0x3] ^= 1 << (nextd&0x7);
|
||||
}
|
||||
|
||||
|
||||
tmp = fgetc(slots[-1 - current]);
|
||||
d = tmp;
|
||||
|
||||
if(tmp < 0)
|
||||
{
|
||||
StopPlayback();
|
||||
return;
|
||||
}
|
||||
|
||||
nextts = 0;
|
||||
tmp >>= 5;
|
||||
tmp &= 0x3;
|
||||
ti=0;
|
||||
|
||||
int tmpfix = tmp;
|
||||
while(tmp--) { nextts |= fgetc(slots[-1 - current]) << (ti * 8); ti++; }
|
||||
|
||||
// This fixes a bug in movies recorded before version 0.98.11
|
||||
// It's probably not necessary, but it may keep away CRAZY PEOPLE who recorded
|
||||
// movies on <= 0.98.10 and don't work on playback.
|
||||
if(tmpfix == 1 && !nextts)
|
||||
{nextts |= fgetc(slots[-1 - current])<<8; }
|
||||
else if(tmpfix == 2 && !nextts) {nextts |= fgetc(slots[-1 - current])<<16; }
|
||||
|
||||
framets = 0;
|
||||
nextd = d;
|
||||
}
|
||||
memcpy(js,joop,4);
|
||||
}
|
||||
else /* Recording */
|
||||
{
|
||||
for(x=0;x<4;x++)
|
||||
{
|
||||
if(js[x] != joop[x])
|
||||
{
|
||||
for(y=0;y<8;y++)
|
||||
if((js[x] ^ joop[x]) & (1 << y))
|
||||
DoEncode(x, y, 0);
|
||||
joop[x] = js[x];
|
||||
}
|
||||
else if(framets == ((1<<24)-1)) DoEncode(0,0,1); /* Overflow will happen, so do dummy update. */
|
||||
}
|
||||
}
|
||||
framets++;
|
||||
}
|
||||
|
||||
void FCEUMOV_AddCommand(int cmd)
|
||||
{
|
||||
if(current <= 0) return; /* Return if not recording a movie */
|
||||
//printf("%d\n",cmd);
|
||||
DoEncode((cmd>>3)&0x3,cmd&0x7,1);
|
||||
}
|
||||
|
||||
void FCEUMOV_CheckMovies(void)
|
||||
{
|
||||
FILE *st=NULL;
|
||||
char *fn;
|
||||
int ssel;
|
||||
|
||||
for(ssel=0;ssel<10;ssel++)
|
||||
{
|
||||
st=FCEUD_UTF8fopen(fn=FCEU_MakeFName(FCEUMKF_MOVIE,ssel,0),"rb");
|
||||
free(fn);
|
||||
if(st)
|
||||
{
|
||||
MovieStatus[ssel]=1;
|
||||
fclose(st);
|
||||
}
|
||||
else
|
||||
MovieStatus[ssel]=0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void FCEUI_SelectMovie(int w)
|
||||
{
|
||||
if(w == -1) { MovieShow = 0; return; }
|
||||
FCEUI_SelectState(-1);
|
||||
|
||||
CurrentMovie=w;
|
||||
MovieShow=180;
|
||||
|
||||
if(current > 0)
|
||||
FCEU_DispMessage("-recording movie %d-",current-1);
|
||||
else if (current < 0)
|
||||
FCEU_DispMessage("-playing movie %d-",-1 - current);
|
||||
else
|
||||
FCEU_DispMessage("-select movie-");
|
||||
}
|
||||
|
||||
void FCEU_DrawMovies(uint8 *XBuf)
|
||||
{
|
||||
if(!MovieShow) return;
|
||||
|
||||
FCEU_DrawNumberRow(XBuf,MovieStatus, CurrentMovie);
|
||||
MovieShow--;
|
||||
}
|
||||
|
@ -1,7 +0,0 @@
|
||||
void FCEUMOV_AddJoy(uint8 *);
|
||||
void FCEUMOV_CheckMovies(void);
|
||||
void FCEUMOV_Stop(void);
|
||||
void FCEUMOV_AddCommand(int cmd);
|
||||
void FCEU_DrawMovies(uint8 *);
|
||||
int FCEUMOV_IsPlaying(void);
|
||||
|
@ -29,13 +29,16 @@
|
||||
|
||||
#include "types.h"
|
||||
#include "netplay.h"
|
||||
#include "fceu.h"
|
||||
#include "fceu.h"
|
||||
#include "general.h"
|
||||
#include "state.h"
|
||||
#include "cheat.h"
|
||||
#include "input.h"
|
||||
#include "endian.h"
|
||||
|
||||
extern int FCEUD_SendData(void *data, uint32 len);
|
||||
extern void FCEUD_NetworkClose(void);
|
||||
|
||||
int FCEUnetplay=0;
|
||||
|
||||
static uint8 netjoy[4]; /* Controller cache. */
|
||||
@ -99,7 +102,7 @@ void FCEUI_NetplayText(uint8 *text)
|
||||
{
|
||||
uint32 len;
|
||||
|
||||
len = strlen(text);
|
||||
len = strlen((char *)text);
|
||||
|
||||
if(!FCEUNET_SendCommand(FCEUNPCMD_TEXT,len)) return;
|
||||
|
||||
@ -124,8 +127,8 @@ int FCEUNET_SendFile(uint8 cmd, char *fn)
|
||||
fclose(fp);
|
||||
|
||||
cbuf = malloc(4 + len + len / 1000 + 12);
|
||||
FCEU_en32lsb(cbuf, len);
|
||||
compress2(cbuf + 4, &clen, buf, len, 7);
|
||||
FCEU_en32lsb((uint8 *)cbuf, len);
|
||||
compress2((Bytef *)(cbuf + 4), &clen, (const Bytef *)buf, len, 7);
|
||||
free(buf);
|
||||
|
||||
//printf("Sending file: %s, %d, %d\n",fn,len,clen);
|
||||
@ -150,6 +153,7 @@ int FCEUNET_SendFile(uint8 cmd, char *fn)
|
||||
return(1);
|
||||
}
|
||||
|
||||
#ifdef NETWORK
|
||||
static FILE *FetchFile(uint32 remlen)
|
||||
{
|
||||
uint32 clen = remlen;
|
||||
@ -209,6 +213,7 @@ static FILE *FetchFile(uint32 remlen)
|
||||
free(fn);
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void NetplayUpdate(uint8 *joyp)
|
||||
{
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "sound.h"
|
||||
#include "nsf.h"
|
||||
#include "general.h"
|
||||
#include "memory.h"
|
||||
#include "file.h"
|
||||
#include "fds.h"
|
||||
#include "cart.h"
|
||||
@ -161,7 +160,7 @@ int NSFLoad(FCEUFILE *fp)
|
||||
NSFMaxBank=((NSFSize+(LoadAddr&0xfff)+4095)/4096);
|
||||
NSFMaxBank=uppow2(NSFMaxBank);
|
||||
|
||||
if(!(NSFDATA=(uint8 *)FCEU_malloc(NSFMaxBank*4096)))
|
||||
if(!(NSFDATA=(uint8 *)malloc(NSFMaxBank*4096)))
|
||||
return 0;
|
||||
|
||||
FCEU_fseek(fp,0x80,SEEK_SET);
|
||||
@ -218,9 +217,9 @@ int NSFLoad(FCEUFILE *fp)
|
||||
FCEU_printf(" Starting song: %d / %d\n\n",NSFHeader.StartingSong,NSFHeader.TotalSongs);
|
||||
|
||||
if(NSFHeader.SoundChip&4)
|
||||
ExWRAM=FCEU_gmalloc(32768+8192);
|
||||
ExWRAM=malloc(32768+8192);
|
||||
else
|
||||
ExWRAM=FCEU_gmalloc(8192);
|
||||
ExWRAM=malloc(8192);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -558,8 +557,8 @@ int FCEUI_NSFChange(int amount)
|
||||
/* Returns total songs */
|
||||
int FCEUI_NSFGetInfo(uint8 *name, uint8 *artist, uint8 *copyright, int maxlen)
|
||||
{
|
||||
strncpy(name,NSFHeader.SongName,maxlen);
|
||||
strncpy(artist,NSFHeader.Artist,maxlen);
|
||||
strncpy(copyright,NSFHeader.Copyright,maxlen);
|
||||
strncpy((char *)name,(char *)NSFHeader.SongName,maxlen);
|
||||
strncpy((char *)artist,(char *)NSFHeader.Artist,maxlen);
|
||||
strncpy((char *)copyright,(char *)NSFHeader.Copyright,maxlen);
|
||||
return(NSFHeader.TotalSongs);
|
||||
}
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "sound.h"
|
||||
#include "filter.h"
|
||||
#include "state.h"
|
||||
#include "wave.h"
|
||||
|
||||
static uint32 wlookup1[32];
|
||||
static uint32 wlookup2[203];
|
||||
@ -1024,8 +1023,6 @@ int FlushEmulateSound(void)
|
||||
}
|
||||
inbuf=end;
|
||||
|
||||
FCEU_WriteWaveData(WaveFinal, end); /* This function will just return
|
||||
if sound recording is off. */
|
||||
return(end);
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "fds.h"
|
||||
#include "general.h"
|
||||
#include "state.h"
|
||||
#include "movie.h"
|
||||
#include "memory.h"
|
||||
#include "ppu.h"
|
||||
#include "netplay.h"
|
||||
@ -398,7 +397,7 @@ void AddExState(void *v, uint32 s, int type, char *desc)
|
||||
{
|
||||
if(desc)
|
||||
{
|
||||
SFMDATA[SFEXINDEX].desc=(char *)FCEU_malloc(5);
|
||||
SFMDATA[SFEXINDEX].desc=(char *)malloc(5);
|
||||
strcpy(SFMDATA[SFEXINDEX].desc,desc);
|
||||
}
|
||||
else
|
||||
@ -430,8 +429,6 @@ void FCEUI_LoadState(char *fname)
|
||||
{
|
||||
StateShow=0;
|
||||
|
||||
FCEUMOV_Stop();
|
||||
|
||||
/* For network play, be load the state locally, and then save the state to a temporary file,
|
||||
and send that. This insures that if an older state is loaded that is missing some
|
||||
information expected in newer save states, desynchronization won't occur(at least not
|
||||
|
@ -159,7 +159,7 @@ static int NAME(FCEUFILE *fp)
|
||||
if(!FCEUGameInfo->name)
|
||||
{
|
||||
FCEUGameInfo->name=malloc(strlen(namebuf)+1);
|
||||
strcpy(FCEUGameInfo->name,namebuf);
|
||||
strcpy((char *)FCEUGameInfo->name,namebuf);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
@ -256,7 +256,7 @@ static int LoadPRG(FCEUFILE *fp)
|
||||
if(malloced[z])
|
||||
free(malloced[z]);
|
||||
t=FixRomSize(uchead.info,2048);
|
||||
if(!(malloced[z]=(uint8 *)FCEU_malloc(t)))
|
||||
if(!(malloced[z]=(uint8 *)malloc(t)))
|
||||
return(0);
|
||||
mallocedsizes[z]=t;
|
||||
memset(malloced[z]+uchead.info,0xFF,t-uchead.info);
|
||||
@ -274,7 +274,7 @@ static int LoadPRG(FCEUFILE *fp)
|
||||
|
||||
static int SetBoardName(FCEUFILE *fp)
|
||||
{
|
||||
if(!(boardname=(uint8 *)FCEU_malloc(uchead.info+1)))
|
||||
if(!(boardname=(uint8 *)malloc(uchead.info+1)))
|
||||
return(0);
|
||||
FCEU_fread(boardname,1,uchead.info,fp);
|
||||
boardname[uchead.info]=0;
|
||||
@ -295,7 +295,7 @@ static int LoadCHR(FCEUFILE *fp)
|
||||
if(malloced[16+z])
|
||||
free(malloced[16+z]);
|
||||
t=FixRomSize(uchead.info,8192);
|
||||
if(!(malloced[16+z]=(uint8 *)FCEU_malloc(t)))
|
||||
if(!(malloced[16+z]=(uint8 *)malloc(t)))
|
||||
return(0);
|
||||
mallocedsizes[16+z]=t;
|
||||
memset(malloced[16+z]+uchead.info,0xFF,t-uchead.info);
|
||||
@ -450,7 +450,7 @@ static int InitializeBoard(void)
|
||||
{
|
||||
if(!malloced[16] && (bmap[x].flags&BMCFLAG_CHRROK))
|
||||
{
|
||||
if((UNIFchrrama=(uint8 *)FCEU_malloc(8192)))
|
||||
if((UNIFchrrama=(uint8 *)malloc(8192)))
|
||||
{
|
||||
SetupCartCHRMapping(0,UNIFchrrama,8192,1);
|
||||
AddExState(UNIFchrrama, 8192, 0,"CHRR");
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include "memory.h"
|
||||
#include "crc32.h"
|
||||
#include "state.h"
|
||||
#include "movie.h"
|
||||
#include "palette.h"
|
||||
#include "nsf.h"
|
||||
#include "input.h"
|
||||
@ -54,7 +53,7 @@ int FCEU_InitVirtualVideo(void)
|
||||
if(!XBuf) /* Some driver code may allocate XBuf externally. */
|
||||
/* 256 bytes per scanline, * 240 scanline maximum, +8 for alignment,
|
||||
*/
|
||||
if(!(XBuf= (uint8*) (FCEU_malloc(256 * 256 + 8))))
|
||||
if(!(XBuf= (uint8*) (malloc(256 * 256 + 8))))
|
||||
return 0;
|
||||
xbsave=XBuf;
|
||||
|
||||
@ -86,7 +85,6 @@ void FCEU_PutImageDummy(void)
|
||||
{
|
||||
FCEU_DrawNTSCControlBars(XBuf);
|
||||
FCEU_DrawSaveStates(XBuf);
|
||||
FCEU_DrawMovies(XBuf);
|
||||
}
|
||||
if(howlong) howlong--; /* DrawMessage() */
|
||||
}
|
||||
@ -135,7 +133,6 @@ void FCEU_PutImage(void)
|
||||
if(FCEUGameInfo->type==GIT_VSUNI)
|
||||
FCEU_VSUniDraw(XBuf);
|
||||
FCEU_DrawSaveStates(XBuf);
|
||||
FCEU_DrawMovies(XBuf);
|
||||
FCEU_DrawNTSCControlBars(XBuf);
|
||||
}
|
||||
DrawMessage();
|
||||
@ -204,7 +201,7 @@ int SaveSnapshot(void)
|
||||
uint8 *compmem=NULL;
|
||||
uLongf compmemsize=totallines*263+12;
|
||||
|
||||
if(!(compmem=(uint8 *)FCEU_malloc(compmemsize)))
|
||||
if(!(compmem=(uint8 *)malloc(compmemsize)))
|
||||
return 0;
|
||||
|
||||
for(u=lastu;u<99999;u++)
|
||||
|
@ -1,109 +0,0 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "fceu.h"
|
||||
|
||||
#include "driver.h"
|
||||
#include "sound.h"
|
||||
#include "wave.h"
|
||||
|
||||
static FILE *soundlog=0;
|
||||
static long wsize;
|
||||
|
||||
/* Checking whether the file exists before wiping it out is left up to the
|
||||
reader..err...I mean, the driver code, if it feels so inclined(I don't feel
|
||||
so).
|
||||
*/
|
||||
void FCEU_WriteWaveData(int32 *Buffer, int Count)
|
||||
{
|
||||
int16 temp[Count]; /* Yay. Is this the first use of this "feature" of C in FCE Ultra? */
|
||||
int16 *dest;
|
||||
int x;
|
||||
|
||||
if(!soundlog) return;
|
||||
|
||||
dest=temp;
|
||||
x=Count;
|
||||
|
||||
while(x--)
|
||||
{
|
||||
int16 tmp=*Buffer;
|
||||
|
||||
*(uint8 *)dest=(((uint16)tmp)&255);
|
||||
*(((uint8 *)dest)+1)=(((uint16)tmp)>>8);
|
||||
dest++;
|
||||
Buffer++;
|
||||
}
|
||||
wsize+=fwrite(temp,1,Count*sizeof(int16),soundlog);
|
||||
}
|
||||
|
||||
int FCEUI_EndWaveRecord(void)
|
||||
{
|
||||
long s;
|
||||
|
||||
if(!soundlog) return 0;
|
||||
s=ftell(soundlog)-8;
|
||||
fseek(soundlog,4,SEEK_SET);
|
||||
fputc(s&0xFF,soundlog);
|
||||
fputc((s>>8)&0xFF,soundlog);
|
||||
fputc((s>>16)&0xFF,soundlog);
|
||||
fputc((s>>24)&0xFF,soundlog);
|
||||
|
||||
fseek(soundlog,0x28,SEEK_SET);
|
||||
s=wsize;
|
||||
fputc(s&0xFF,soundlog);
|
||||
fputc((s>>8)&0xFF,soundlog);
|
||||
fputc((s>>16)&0xFF,soundlog);
|
||||
fputc((s>>24)&0xFF,soundlog);
|
||||
|
||||
fclose(soundlog);
|
||||
soundlog=0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int FCEUI_BeginWaveRecord(char *fn)
|
||||
{
|
||||
int r;
|
||||
|
||||
if(!(soundlog=FCEUD_UTF8fopen(fn,"wb")))
|
||||
return 0;
|
||||
wsize=0;
|
||||
|
||||
|
||||
/* Write the header. */
|
||||
fputs("RIFF",soundlog);
|
||||
fseek(soundlog,4,SEEK_CUR); // Skip size
|
||||
fputs("WAVEfmt ",soundlog);
|
||||
|
||||
fputc(0x10,soundlog);
|
||||
fputc(0,soundlog);
|
||||
fputc(0,soundlog);
|
||||
fputc(0,soundlog);
|
||||
|
||||
fputc(1,soundlog); // PCM
|
||||
fputc(0,soundlog);
|
||||
|
||||
fputc(1,soundlog); // Monophonic
|
||||
fputc(0,soundlog);
|
||||
|
||||
r=FSettings.SndRate;
|
||||
fputc(r&0xFF,soundlog);
|
||||
fputc((r>>8)&0xFF,soundlog);
|
||||
fputc((r>>16)&0xFF,soundlog);
|
||||
fputc((r>>24)&0xFF,soundlog);
|
||||
r<<=1;
|
||||
fputc(r&0xFF,soundlog);
|
||||
fputc((r>>8)&0xFF,soundlog);
|
||||
fputc((r>>16)&0xFF,soundlog);
|
||||
fputc((r>>24)&0xFF,soundlog);
|
||||
fputc(2,soundlog);
|
||||
fputc(0,soundlog);
|
||||
fputc(16,soundlog);
|
||||
fputc(0,soundlog);
|
||||
|
||||
fputs("data",soundlog);
|
||||
fseek(soundlog,4,SEEK_CUR);
|
||||
|
||||
return(1);
|
||||
}
|
@ -1 +0,0 @@
|
||||
void FCEU_WriteWaveData(int32 *Buffer, int Count);
|
@ -10,7 +10,6 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "driver.h"
|
||||
#include "drivers/common/config.h"
|
||||
|
||||
/* Message logging(non-netplay messages, usually) for all. */
|
||||
extern int NoWaiting;
|
||||
|
Loading…
Reference in New Issue
Block a user