mirror of
https://github.com/mkwong98/HDNes.git
synced 2024-05-20 13:07:54 -04:00
3003 lines
95 KiB
C++
3003 lines
95 KiB
C++
#include "stdafx.h"
|
|
#include "sysState.h"
|
|
#include <SDL\SDL_image.h>
|
|
|
|
using namespace std;
|
|
|
|
video::video(void){
|
|
screenSizeOption = 1;
|
|
screenSizeWidth = DISPLAY_WIDTH;
|
|
screenSizeWidth = DISPLAY_HEIGHT;
|
|
usePack = true;
|
|
editRecordingType = 0;
|
|
cutEdgeTiles = false;
|
|
chrRamMatch = false;
|
|
packData = 0;
|
|
editData = 0;
|
|
clockPerFrame = CLOCKS_PER_SEC / 60;
|
|
initColour();
|
|
bgCBufferSize = 190080 * sizeof(GLfloat); //33 tiles * 240 scanline * 6 vertex * 4 values
|
|
capRate = 5;
|
|
}
|
|
|
|
void video::RefreshPackSize(){
|
|
packSize = (romDat->chrPageCount > 0 ? romDat->chrPageCount * 0x200 : romDat->prgPageCount * 0x400);
|
|
}
|
|
|
|
void video::init(){
|
|
SDL_ShowCursor(SDL_DISABLE);
|
|
RefreshPackSize();
|
|
CleanHiResPack();
|
|
ReadHiResPack();
|
|
ReadPackEdit();
|
|
lastClock = clock();
|
|
waitFrame = false;
|
|
switch (screenSizeOption) {
|
|
case SCREEN_SIZE_1X:
|
|
screenSizeWidth = DISPLAY_WIDTH;
|
|
screenSizeHeight = DISPLAY_HEIGHT;
|
|
break;
|
|
case SCREEN_SIZE_2X:
|
|
screenSizeWidth = DISPLAY_WIDTH * 2;
|
|
screenSizeHeight = DISPLAY_HEIGHT * 2;
|
|
break;
|
|
case SCREEN_SIZE_4X:
|
|
screenSizeWidth = DISPLAY_WIDTH * 4;
|
|
screenSizeHeight = DISPLAY_HEIGHT * 4;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if((Surf_Display = SDL_CreateWindow("HDNes", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screenSizeWidth, screenSizeHeight, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL)) == NULL) {
|
|
initState = false;
|
|
writeLog("Cannot create display surface with SDL_SetVideoMode");
|
|
return;
|
|
}
|
|
glcontext = SDL_GL_CreateContext(Surf_Display);
|
|
glewInit();
|
|
|
|
//init resource
|
|
initBuffer();
|
|
initPatternArea();
|
|
for(int i = 0; i < 256; i++){
|
|
flagsTexture[i] = 0;
|
|
}
|
|
|
|
glShadeModel(GL_SMOOTH);
|
|
glEnable (GL_BLEND);
|
|
glEnable (GL_DEPTH_TEST);
|
|
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
|
glClearDepth(1.0f);
|
|
|
|
//bg program
|
|
glVShader = make_shader(GL_VERTEX_SHADER, "hdnesBGV.glsl");
|
|
glPShader = make_shader(GL_FRAGMENT_SHADER, "hdnesBGF.glsl");
|
|
glProgID = make_program(glVShader, glPShader);
|
|
|
|
uniTexture = glGetUniformLocation(glProgID, "textureb");
|
|
uniTextureBase = glGetUniformLocation(glProgID, "texturebBase");
|
|
uniXOffset = glGetUniformLocation(glProgID, "xOffset");
|
|
uniFlagBG = glGetUniformLocation(glProgID, "flags");
|
|
|
|
atrVectCoord = glGetAttribLocation(glProgID, "position");
|
|
atrTextCoord = glGetAttribLocation(glProgID, "textCoord");
|
|
|
|
//sp program 1
|
|
glVShaderSp1 = make_shader(GL_VERTEX_SHADER, "hdnesSPV.glsl");
|
|
glPShaderSp1 = make_shader(GL_FRAGMENT_SHADER, "hdnesSPF1.glsl");
|
|
glProgIDSp1 = make_program(glVShaderSp1, glPShaderSp1);
|
|
|
|
uniTextureSp1 = glGetUniformLocation(glProgIDSp1, "textureb");
|
|
uniTextureBaseSp1 = glGetUniformLocation(glProgIDSp1, "texturebBase");
|
|
uniFlagSp1 = glGetUniformLocation(glProgIDSp1, "flagsSP1");
|
|
atrVectCoordSp1 = glGetAttribLocation(glProgIDSp1, "position");
|
|
atrTextCoordSp1 = glGetAttribLocation(glProgIDSp1, "textCoord");
|
|
|
|
//sp program 2
|
|
glVShaderSp2 = make_shader(GL_VERTEX_SHADER, "hdnesSPV.glsl");
|
|
glPShaderSp2 = make_shader(GL_FRAGMENT_SHADER, "hdnesSPF2.glsl");
|
|
glProgIDSp2 = make_program(glVShaderSp2, glPShaderSp2);
|
|
|
|
uniTextureSp2 = glGetUniformLocation(glProgIDSp2, "textureb");
|
|
uniTextureBaseSp2 = glGetUniformLocation(glProgIDSp2, "texturebBase");
|
|
uniFlagSp2 = glGetUniformLocation(glProgIDSp2, "flagsSP2");
|
|
atrVectCoordSp2 = glGetAttribLocation(glProgIDSp2, "position");
|
|
atrTextCoordSp2 = glGetAttribLocation(glProgIDSp2, "textCoord");
|
|
|
|
//textures
|
|
hdTextureRef = make_texture(packScale * TEXTURE_CACHE_TILE_COL_COUNT * 8, packScale * TEXTURE_CACHE_TILE_ROW_COUNT * 8, hdTextureCache, GL_TEXTURE_2D, 4, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8);
|
|
baseTextureRef = make_texture(TEXTURE_CACHE_TILE_COL_COUNT * 8, TEXTURE_CACHE_TILE_ROW_COUNT * 8, baseTextureCache, GL_TEXTURE_2D, 4, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8);
|
|
|
|
xOffsetTexture = make_texture(256, 1, bgXTexture, GL_TEXTURE_1D, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE);
|
|
flagsTextureT = make_texture(256, 1, flagsTexture, GL_TEXTURE_1D, GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE);
|
|
|
|
sampler = make_sampler();
|
|
baseSampler = make_sampler();
|
|
xOffsetSampler = make_sampler();
|
|
flagSampler = make_sampler();
|
|
|
|
capScreenFlag = false;
|
|
capDataFlag = false;
|
|
initState = true;
|
|
contCapFlag = false;
|
|
contCapCounter = 0;
|
|
|
|
memset(hdPatternInUse, 0xFF, TEXTURE_CACHE_TILE_COUNT);
|
|
memset(basePatternInUse, 0xFF, TEXTURE_CACHE_TILE_COUNT);
|
|
memset(bgHDResult, 0xFF, 4 * 0x3C0 * 2);
|
|
memset(spHDResult, 0xFF, 64 * 2 * 2);
|
|
hdResultInInitState = true;
|
|
minHDIdx = 0;
|
|
minBaseIdx = 0;
|
|
maxHDIdx = 0;
|
|
maxBaseIdx = 0;
|
|
blankHDIdx = 0;
|
|
blankBaseIdx = 0;
|
|
}
|
|
|
|
video::~video(void){
|
|
CleanHiResPack();
|
|
CleanPackEdit();
|
|
}
|
|
|
|
void video::cleanUp(){
|
|
SDL_GL_DeleteContext(glcontext);
|
|
SDL_DestroyWindow(Surf_Display);
|
|
Surf_Display = NULL;
|
|
glDeleteTextures(1, &hdTextureRef);
|
|
glDeleteTextures(1, &baseTextureRef);
|
|
glDeleteTextures(1, &xOffsetTexture);
|
|
glDeleteTextures(1, &flagsTextureT);
|
|
glDeleteShader(glVShader);
|
|
glDeleteShader(glPShader);
|
|
glDeleteProgram(glProgID);
|
|
glDeleteShader(glVShaderSp1);
|
|
glDeleteShader(glPShaderSp1);
|
|
glDeleteProgram(glProgIDSp1);
|
|
glDeleteShader(glVShaderSp2);
|
|
glDeleteShader(glPShaderSp2);
|
|
glDeleteProgram(glProgIDSp2);
|
|
glDeleteBuffers(1, &bgCBufferRef);
|
|
glDeleteBuffers(1, &bgVBufferRef);
|
|
glDeleteBuffers(1, &spCBufferRef);
|
|
glDeleteBuffers(1, &spVBufferRef);
|
|
free(hdTextureCache);
|
|
|
|
guiForm->refreshGraphicsPackGUI();
|
|
}
|
|
|
|
bool video::getInitState(){
|
|
return initState;
|
|
}
|
|
|
|
void video::clearFrame(){
|
|
bgColourID = memDat->bgColourID;
|
|
if(!ppuCore->useGrayscale){
|
|
glClearColor((colourList[bgColourID & 0x3F] >> 24)/ 255.0f, ((colourList[bgColourID & 0x3F] >> 16) & 0xFF)/ 255.0f, ((colourList[bgColourID & 0x3F] >> 8) & 0xFF)/ 255.0f, 1.0f);
|
|
}
|
|
else{
|
|
float v = ((colourList[bgColourID & 0x3F] >> 24) + ((colourList[bgColourID & 0x3F] >> 16) & 0xFF) + ((colourList[bgColourID & 0x3F] >> 8) & 0xFF)) / 3.0f / 255.0f;
|
|
glClearColor(v, v, v, 1.0f);
|
|
}
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
}
|
|
|
|
void video::startFrame(){
|
|
if(editRecordingType != RECORDING_TYPE_NONE){
|
|
screenTiles.clear();
|
|
allScreenTiles.clear();
|
|
}
|
|
spPatCount = 0;
|
|
lastPatID = TEXTURE_CACHE_TILE_COUNT;
|
|
}
|
|
|
|
void video::displayFrame(){
|
|
if((clock() - lastClock < clockPerFrame)){
|
|
waitFrame = true;
|
|
return;
|
|
}
|
|
else{
|
|
waitFrame = false;
|
|
lastClock += clockPerFrame;
|
|
}
|
|
|
|
clearFrame();
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, bgCBufferRef);
|
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, spVBufferRef);
|
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, spCBufferRef);
|
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
|
|
|
//is back sp
|
|
glDepthFunc(GL_LESS);
|
|
glDepthMask(true);
|
|
|
|
glUseProgram(glProgIDSp1);
|
|
update_texture(uniTextureSp1, hdTextureRef, sampler, 512 * packScale, ((minHDIdx >> 3) & 0x1F8) * packScale, (((maxHDIdx >> 3) & 0x1F8) + 8) * packScale, 512 * packScale, hdTextureCache, GL_TEXTURE_2D, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 0);
|
|
update_texture(uniTextureBaseSp1, baseTextureRef, baseSampler, 512, ((minBaseIdx >> 3) & 0x1F8), ((maxBaseIdx >> 3) & 0x1F8) + 8, 512, baseTextureCache, GL_TEXTURE_2D, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 1);
|
|
update_texture(uniFlagSp1, flagsTextureT, flagSampler, 240, 0, 1, 1, flagsTexture, GL_TEXTURE_1D, GL_RED_INTEGER, GL_UNSIGNED_BYTE, 2);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, spVBufferRef);
|
|
glVertexAttribPointer(atrVectCoordSp1, 3, GL_SHORT, GL_FALSE, 0, 0);
|
|
glEnableVertexAttribArray(atrVectCoordSp1);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, spCBufferRef);
|
|
glVertexAttribPointer(atrTextCoordSp1, 4, GL_FLOAT, GL_FALSE, 0, 0);
|
|
glEnableVertexAttribArray(atrTextCoordSp1);
|
|
|
|
glDrawArrays(GL_TRIANGLES, 0, spPatCount * 6);
|
|
|
|
glDisableVertexAttribArray(atrVectCoordSp1);
|
|
glDisableVertexAttribArray(atrTextCoordSp1);
|
|
|
|
glDepthFunc(GL_ALWAYS);
|
|
glDepthMask(false);
|
|
|
|
glUseProgram(glProgID);
|
|
|
|
update_texture(uniTexture, hdTextureRef, sampler, 0, 0, 0, 0, hdTextureCache, GL_TEXTURE_2D, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 3);
|
|
update_texture(uniTextureBase, baseTextureRef, baseSampler, 0, 0, 0, 0, baseTextureCache, GL_TEXTURE_2D, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 4);
|
|
|
|
update_texture(uniXOffset, xOffsetTexture, xOffsetSampler, 240, 0, 1, 1, bgXTexture, GL_TEXTURE_1D, GL_RED_INTEGER, GL_UNSIGNED_BYTE, 5);
|
|
update_texture(uniFlagBG, flagsTextureT, flagSampler, 240, 0, 1, 1, flagsTexture, GL_TEXTURE_1D, GL_RED_INTEGER, GL_UNSIGNED_BYTE, 6);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, bgVBufferRef);
|
|
glVertexAttribPointer(atrVectCoord, 3, GL_SHORT, GL_FALSE, 0, 0);
|
|
glEnableVertexAttribArray(atrVectCoord);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, bgCBufferRef);
|
|
glVertexAttribPointer(atrTextCoord, 4, GL_FLOAT, GL_FALSE, 0, 0);
|
|
glEnableVertexAttribArray(atrTextCoord);
|
|
|
|
glDrawArrays(GL_TRIANGLES, 0, 47520);
|
|
|
|
glDisableVertexAttribArray(atrVectCoord);
|
|
glDisableVertexAttribArray(atrTextCoord);
|
|
|
|
glDepthFunc(GL_LESS);
|
|
glDepthMask(true);
|
|
|
|
glUseProgram(glProgIDSp2);
|
|
|
|
update_texture(uniTextureSp2, hdTextureRef, sampler, 0, 0, 0, 0, hdTextureCache, GL_TEXTURE_2D, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 7);
|
|
update_texture(uniTextureBaseSp2, baseTextureRef, baseSampler, 0, 0, 0, 0, baseTextureCache, GL_TEXTURE_2D, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 8);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, spVBufferRef);
|
|
glVertexAttribPointer(atrVectCoordSp2, 3, GL_SHORT, GL_FALSE, 0, 0);
|
|
glEnableVertexAttribArray(atrVectCoordSp2);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, spCBufferRef);
|
|
glVertexAttribPointer(atrTextCoordSp2, 4, GL_FLOAT, GL_FALSE, 0, 0);
|
|
glEnableVertexAttribArray(atrTextCoordSp2);
|
|
|
|
glDrawArrays(GL_TRIANGLES, 0, spPatCount * 6);
|
|
|
|
glDisableVertexAttribArray(atrVectCoordSp2);
|
|
glDisableVertexAttribArray(atrTextCoordSp2);
|
|
|
|
glUseProgram(0);
|
|
|
|
if(capScreenFlag && !contCapFlag){
|
|
capScreen(false);
|
|
}
|
|
|
|
if (editRecordingType == RECORDING_TYPE_AUTO || capDataFlag) {
|
|
if (screenTiles.size() > 0 || capDataFlag) {
|
|
SavePackEditScreen();
|
|
}
|
|
capDataFlag = false;
|
|
}
|
|
if(contCapFlag && (++contCapCounter >= capRate)){
|
|
contCapCounter = 0;
|
|
capScreen(true);
|
|
}
|
|
|
|
SDL_GL_SwapWindow(Surf_Display);
|
|
|
|
//capScreen(false);
|
|
}
|
|
|
|
void video::clearScreenData(){
|
|
glBindBuffer(GL_ARRAY_BUFFER, bgCBufferRef);
|
|
glBufferData(GL_ARRAY_BUFFER, bgCBufferSize, NULL, GL_WRITE_ONLY);
|
|
bgCBuffer = (GLfloat*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, spVBufferRef);
|
|
spVBuffer = (GLshort*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, spCBufferRef);
|
|
spCBuffer = (GLfloat*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
|
|
|
|
//if(minBgIdx != maxBgIdx){
|
|
// capScreen(true);
|
|
//}
|
|
|
|
if(maxHDIdx < blankHDIdx){
|
|
blankHDIdx = TEXTURE_CACHE_TILE_COUNT;
|
|
}
|
|
else{
|
|
blankHDIdx = maxHDIdx;
|
|
}
|
|
ZeroMemory(hdPatternInUse, blankHDIdx);
|
|
minHDIdx = maxHDIdx;
|
|
|
|
if(maxBaseIdx < blankBaseIdx){
|
|
blankBaseIdx = TEXTURE_CACHE_TILE_COUNT;
|
|
}
|
|
else{
|
|
blankBaseIdx = maxBaseIdx;
|
|
}
|
|
ZeroMemory(basePatternInUse, blankBaseIdx);
|
|
minBaseIdx = maxBaseIdx;
|
|
|
|
spPatCount = 0;
|
|
}
|
|
|
|
GLuint video::make_sampler(){
|
|
GLuint tmpsampler;
|
|
glGenSamplers(1, &tmpsampler);
|
|
glSamplerParameteri(tmpsampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
glSamplerParameteri(tmpsampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
glSamplerParameteri(tmpsampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glSamplerParameteri(tmpsampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
glSamplerParameteri(tmpsampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
|
return tmpsampler;
|
|
}
|
|
|
|
GLuint video::make_buffer(GLenum target, const void *buffer_data, GLsizei buffer_size)
|
|
{
|
|
GLuint buffer;
|
|
glGenBuffers(1, &buffer);
|
|
glBindBuffer(target, buffer);
|
|
glBufferData(target, buffer_size, buffer_data, GL_DYNAMIC_DRAW);
|
|
return buffer;
|
|
}
|
|
|
|
GLuint video::make_texture(GLuint width, GLuint height,void *buffer_data, GLuint type,
|
|
GLint internalFormat, GLenum format, GLenum datatype)
|
|
{
|
|
GLuint txtnumber; // Texture ID
|
|
glGenTextures(1, &txtnumber); // Create 1 Texture
|
|
glBindTexture(type, txtnumber); // Bind The Texture
|
|
switch(type){
|
|
case GL_TEXTURE_2D:
|
|
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, datatype, buffer_data);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
break;
|
|
case GL_TEXTURE_1D:
|
|
glTexImage1D(GL_TEXTURE_1D, 0, internalFormat, width, 0, format, datatype, buffer_data);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
break;
|
|
}
|
|
return txtnumber; // Return The Texture ID
|
|
}
|
|
|
|
GLuint video::make_shader(GLenum type, const char *filename)
|
|
{
|
|
fstream sourcefile;
|
|
GLchar *source;
|
|
GLuint shader;
|
|
GLint shader_ok;
|
|
GLint size;
|
|
|
|
sourcefile.open(setting->progDir + filename, ios::in|ios::binary|ios::ate);
|
|
if(sourcefile.is_open()){
|
|
size = sourcefile.tellg();
|
|
source = new GLchar[size];
|
|
sourcefile.seekg (0, ios::beg);
|
|
sourcefile.read (source, size);
|
|
sourcefile.close();
|
|
}
|
|
else{
|
|
writeLog("Cannot open shader " + string(filename));
|
|
return 0;
|
|
}
|
|
shader = glCreateShader(type);
|
|
glShaderSource(shader, 1, (const GLchar**)&source, &size);
|
|
delete[] source;
|
|
glCompileShader(shader);
|
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok);
|
|
if (!shader_ok) {
|
|
writeLog("Failed to compile shader "+ string(filename));
|
|
GLsizei loglen;
|
|
GLchar logStr[256];
|
|
glGetShaderInfoLog(shader, 256, &loglen, logStr);
|
|
writeLog(string((char*)logStr));
|
|
glDeleteShader(shader);
|
|
return 0;
|
|
}
|
|
return shader;
|
|
}
|
|
|
|
GLuint video::make_program(GLuint vertex_shader, GLuint fragment_shader)
|
|
{
|
|
GLint program_ok;
|
|
|
|
GLuint program = glCreateProgram();
|
|
glAttachShader(program, vertex_shader);
|
|
glAttachShader(program, fragment_shader);
|
|
glLinkProgram(program);
|
|
|
|
glGetProgramiv(program, GL_LINK_STATUS, &program_ok);
|
|
if (!program_ok) {
|
|
writeLog("Failed to link shader program");
|
|
if(fragment_shader == glPShader){
|
|
writeLog("Shaders: hdnesBGV.glsl and hdnesBGF.glsl");
|
|
}
|
|
else if(fragment_shader == glPShaderSp1){
|
|
writeLog("Shaders: hdnesSPV.glsl and hdnesSPF1.glsl");
|
|
}
|
|
else if(fragment_shader == glPShaderSp2){
|
|
writeLog("Shaders: hdnesSPV.glsl and hdnesSPF2.glsl");
|
|
}
|
|
GLsizei loglen;
|
|
GLchar logStr[256];
|
|
glGetProgramInfoLog(program, 256, &loglen, logStr);
|
|
writeLog(string((char*)logStr));
|
|
glDeleteProgram(program);
|
|
return 0;
|
|
}
|
|
return program;
|
|
}
|
|
|
|
void video::update_texture(GLuint uniformID, GLuint textureRef, GLuint samplerRef, GLuint width, GLuint oy, GLuint ny, GLuint maxy, void *buffer_data, GLuint type, GLenum format, GLenum datatype, int textureUnitIndex){
|
|
glUniform1i(uniformID, textureUnitIndex);
|
|
glActiveTexture(GL_TEXTURE0 + textureUnitIndex);
|
|
glBindTexture(type, textureRef);
|
|
if(width > 0){
|
|
if(type == GL_TEXTURE_2D){
|
|
if(ny >= oy){
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, oy, width, ny - oy, format, datatype, (Uint32*)buffer_data + (oy * width));
|
|
}
|
|
else{
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, oy, width, maxy - oy, format, datatype, (Uint32*)buffer_data + (oy * width));
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, ny, format, datatype, buffer_data);
|
|
}
|
|
}
|
|
else{
|
|
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, width, format, datatype, buffer_data);
|
|
}
|
|
}
|
|
glBindSampler(textureUnitIndex, samplerRef);
|
|
}
|
|
|
|
|
|
void video::initColour(){
|
|
Uint8 colourDish[64][3];
|
|
|
|
colourDish[0][0] = 0x80;
|
|
colourDish[0][1] = 0x80;
|
|
colourDish[0][2] = 0x80;
|
|
colourDish[1][0] = 0x00;
|
|
colourDish[1][1] = 0x3D;
|
|
colourDish[1][2] = 0xA6;
|
|
colourDish[2][0] = 0x00;
|
|
colourDish[2][1] = 0x12;
|
|
colourDish[2][2] = 0xB0;
|
|
colourDish[3][0] = 0x44;
|
|
colourDish[3][1] = 0x00;
|
|
colourDish[3][2] = 0x96;
|
|
colourDish[4][0] = 0xA1;
|
|
colourDish[4][1] = 0x00;
|
|
colourDish[4][2] = 0x5E;
|
|
colourDish[5][0] = 0xC7;
|
|
colourDish[5][1] = 0x00;
|
|
colourDish[5][2] = 0x28;
|
|
colourDish[6][0] = 0xBA;
|
|
colourDish[6][1] = 0x06;
|
|
colourDish[6][2] = 0x00;
|
|
colourDish[7][0] = 0x8C;
|
|
colourDish[7][1] = 0x17;
|
|
colourDish[7][2] = 0x00;
|
|
colourDish[8][0] = 0x5C;
|
|
colourDish[8][1] = 0x2F;
|
|
colourDish[8][2] = 0x00;
|
|
colourDish[9][0] = 0x10;
|
|
colourDish[9][1] = 0x45;
|
|
colourDish[9][2] = 0x00;
|
|
colourDish[10][0] = 0x05;
|
|
colourDish[10][1] = 0x4A;
|
|
colourDish[10][2] = 0x00;
|
|
colourDish[11][0] = 0x00;
|
|
colourDish[11][1] = 0x47;
|
|
colourDish[11][2] = 0x2E;
|
|
colourDish[12][0] = 0x00;
|
|
colourDish[12][1] = 0x41;
|
|
colourDish[12][2] = 0x66;
|
|
colourDish[13][0] = 0x00;
|
|
colourDish[13][1] = 0x00;
|
|
colourDish[13][2] = 0x00;
|
|
colourDish[14][0] = 0x05;
|
|
colourDish[14][1] = 0x05;
|
|
colourDish[14][2] = 0x05;
|
|
colourDish[15][0] = 0x05;
|
|
colourDish[15][1] = 0x05;
|
|
colourDish[15][2] = 0x05;
|
|
|
|
colourDish[16][0] = 0xC7;
|
|
colourDish[16][1] = 0xC7;
|
|
colourDish[16][2] = 0xC7;
|
|
colourDish[17][0] = 0x00;
|
|
colourDish[17][1] = 0x77;
|
|
colourDish[17][2] = 0xFF;
|
|
colourDish[18][0] = 0x21;
|
|
colourDish[18][1] = 0x55;
|
|
colourDish[18][2] = 0xFF;
|
|
colourDish[19][0] = 0x82;
|
|
colourDish[19][1] = 0x37;
|
|
colourDish[19][2] = 0xFA;
|
|
colourDish[20][0] = 0xEB;
|
|
colourDish[20][1] = 0x2F;
|
|
colourDish[20][2] = 0xB5;
|
|
colourDish[21][0] = 0xFF;
|
|
colourDish[21][1] = 0x29;
|
|
colourDish[21][2] = 0x50;
|
|
colourDish[22][0] = 0xFF;
|
|
colourDish[22][1] = 0x22;
|
|
colourDish[22][2] = 0x00;
|
|
colourDish[23][0] = 0xD6;
|
|
colourDish[23][1] = 0x32;
|
|
colourDish[23][2] = 0x00;
|
|
colourDish[24][0] = 0xC4;
|
|
colourDish[24][1] = 0x62;
|
|
colourDish[24][2] = 0x00;
|
|
colourDish[25][0] = 0x35;
|
|
colourDish[25][1] = 0x80;
|
|
colourDish[25][2] = 0x00;
|
|
colourDish[26][0] = 0x05;
|
|
colourDish[26][1] = 0x8F;
|
|
colourDish[26][2] = 0x00;
|
|
colourDish[27][0] = 0x00;
|
|
colourDish[27][1] = 0x8A;
|
|
colourDish[27][2] = 0x55;
|
|
colourDish[28][0] = 0x00;
|
|
colourDish[28][1] = 0x99;
|
|
colourDish[28][2] = 0xCC;
|
|
colourDish[29][0] = 0x21;
|
|
colourDish[29][1] = 0x21;
|
|
colourDish[29][2] = 0x21;
|
|
colourDish[30][0] = 0x09;
|
|
colourDish[30][1] = 0x09;
|
|
colourDish[30][2] = 0x09;
|
|
colourDish[31][0] = 0x09;
|
|
colourDish[31][1] = 0x09;
|
|
colourDish[31][2] = 0x09;
|
|
|
|
colourDish[32][0] = 0xFE;
|
|
colourDish[32][1] = 0xFE;
|
|
colourDish[32][2] = 0xFF;
|
|
colourDish[33][0] = 0x0F;
|
|
colourDish[33][1] = 0xD7;
|
|
colourDish[33][2] = 0xFF;
|
|
colourDish[34][0] = 0x69;
|
|
colourDish[34][1] = 0xA2;
|
|
colourDish[34][2] = 0xFF;
|
|
colourDish[35][0] = 0xD4;
|
|
colourDish[35][1] = 0x80;
|
|
colourDish[35][2] = 0xFF;
|
|
colourDish[36][0] = 0xFF;
|
|
colourDish[36][1] = 0x45;
|
|
colourDish[36][2] = 0xF3;
|
|
colourDish[37][0] = 0xFF;
|
|
colourDish[37][1] = 0x61;
|
|
colourDish[37][2] = 0x8B;
|
|
colourDish[38][0] = 0xFF;
|
|
colourDish[38][1] = 0x88;
|
|
colourDish[38][2] = 0x33;
|
|
colourDish[39][0] = 0xFF;
|
|
colourDish[39][1] = 0x9C;
|
|
colourDish[39][2] = 0x12;
|
|
colourDish[40][0] = 0xFA;
|
|
colourDish[40][1] = 0xBC;
|
|
colourDish[40][2] = 0x20;
|
|
colourDish[41][0] = 0x9F;
|
|
colourDish[41][1] = 0xE3;
|
|
colourDish[41][2] = 0x0E;
|
|
colourDish[42][0] = 0x2B;
|
|
colourDish[42][1] = 0xF0;
|
|
colourDish[42][2] = 0x35;
|
|
colourDish[43][0] = 0x0C;
|
|
colourDish[43][1] = 0xF0;
|
|
colourDish[43][2] = 0xA4;
|
|
colourDish[44][0] = 0x05;
|
|
colourDish[44][1] = 0xFB;
|
|
colourDish[44][2] = 0xFF;
|
|
colourDish[45][0] = 0x5E;
|
|
colourDish[45][1] = 0x5E;
|
|
colourDish[45][2] = 0x5E;
|
|
colourDish[46][0] = 0x0D;
|
|
colourDish[46][1] = 0x0D;
|
|
colourDish[46][2] = 0x0D;
|
|
colourDish[47][0] = 0x0D;
|
|
colourDish[47][1] = 0x0D;
|
|
colourDish[47][2] = 0x0D;
|
|
|
|
colourDish[48][0] = 0xFF;
|
|
colourDish[48][1] = 0xFF;
|
|
colourDish[48][2] = 0xFF;
|
|
colourDish[49][0] = 0xA6;
|
|
colourDish[49][1] = 0xFC;
|
|
colourDish[49][2] = 0xFF;
|
|
colourDish[50][0] = 0xB3;
|
|
colourDish[50][1] = 0xEC;
|
|
colourDish[50][2] = 0xFF;
|
|
colourDish[51][0] = 0xDA;
|
|
colourDish[51][1] = 0xAB;
|
|
colourDish[51][2] = 0xEB;
|
|
colourDish[52][0] = 0xFF;
|
|
colourDish[52][1] = 0xA8;
|
|
colourDish[52][2] = 0xF9;
|
|
colourDish[53][0] = 0xFF;
|
|
colourDish[53][1] = 0xAB;
|
|
colourDish[53][2] = 0xB3;
|
|
colourDish[54][0] = 0xFF;
|
|
colourDish[54][1] = 0xD2;
|
|
colourDish[54][2] = 0xB0;
|
|
colourDish[55][0] = 0xFF;
|
|
colourDish[55][1] = 0xEF;
|
|
colourDish[55][2] = 0xA6;
|
|
colourDish[56][0] = 0xFF;
|
|
colourDish[56][1] = 0xF7;
|
|
colourDish[56][2] = 0x9C;
|
|
colourDish[57][0] = 0xD7;
|
|
colourDish[57][1] = 0xE8;
|
|
colourDish[57][2] = 0x95;
|
|
colourDish[58][0] = 0xA6;
|
|
colourDish[58][1] = 0xED;
|
|
colourDish[58][2] = 0xAF;
|
|
colourDish[59][0] = 0xA2;
|
|
colourDish[59][1] = 0xF2;
|
|
colourDish[59][2] = 0xDA;
|
|
colourDish[60][0] = 0x99;
|
|
colourDish[60][1] = 0xFF;
|
|
colourDish[60][2] = 0xFC;
|
|
colourDish[61][0] = 0xDD;
|
|
colourDish[61][1] = 0xDD;
|
|
colourDish[61][2] = 0xDD;
|
|
colourDish[62][0] = 0x11;
|
|
colourDish[62][1] = 0x11;
|
|
colourDish[62][2] = 0x11;
|
|
colourDish[63][0] = 0x11;
|
|
colourDish[63][1] = 0x11;
|
|
colourDish[63][2] = 0x11;
|
|
/*
|
|
colourDish[0][0] = 0x46;
|
|
colourDish[0][1] = 0x46;
|
|
colourDish[0][2] = 0x46;
|
|
colourDish[1][0] = 0x00;
|
|
colourDish[1][1] = 0x06;
|
|
colourDish[1][2] = 0x5A;
|
|
colourDish[2][0] = 0x00;
|
|
colourDish[2][1] = 0x06;
|
|
colourDish[2][2] = 0x78;
|
|
colourDish[3][0] = 0x02;
|
|
colourDish[3][1] = 0x06;
|
|
colourDish[3][2] = 0x73;
|
|
colourDish[4][0] = 0x35;
|
|
colourDish[4][1] = 0x03;
|
|
colourDish[4][2] = 0x4C;
|
|
colourDish[5][0] = 0x57;
|
|
colourDish[5][1] = 0x00;
|
|
colourDish[5][2] = 0x0E;
|
|
colourDish[6][0] = 0x5A;
|
|
colourDish[6][1] = 0x00;
|
|
colourDish[6][2] = 0x00;
|
|
colourDish[7][0] = 0x41;
|
|
colourDish[7][1] = 0x00;
|
|
colourDish[7][2] = 0x00;
|
|
colourDish[8][0] = 0x12;
|
|
colourDish[8][1] = 0x02;
|
|
colourDish[8][2] = 0x00;
|
|
colourDish[9][0] = 0x00;
|
|
colourDish[9][1] = 0x14;
|
|
colourDish[9][2] = 0x00;
|
|
colourDish[10][0] = 0x00;
|
|
colourDish[10][1] = 0x1E;
|
|
colourDish[10][2] = 0x00;
|
|
colourDish[11][0] = 0x00;
|
|
colourDish[11][1] = 0x1E;
|
|
colourDish[11][2] = 0x00;
|
|
colourDish[12][0] = 0x00;
|
|
colourDish[12][1] = 0x15;
|
|
colourDish[12][2] = 0x21;
|
|
colourDish[13][0] = 0x00;
|
|
colourDish[13][1] = 0x00;
|
|
colourDish[13][2] = 0x00;
|
|
colourDish[14][0] = 0x00;
|
|
colourDish[14][1] = 0x00;
|
|
colourDish[14][2] = 0x00;
|
|
colourDish[15][0] = 0x00;
|
|
colourDish[15][1] = 0x00;
|
|
colourDish[15][2] = 0x00;
|
|
|
|
colourDish[16][0] = 0x9D;
|
|
colourDish[16][1] = 0x9D;
|
|
colourDish[16][2] = 0x9D;
|
|
colourDish[17][0] = 0x00;
|
|
colourDish[17][1] = 0x4A;
|
|
colourDish[17][2] = 0xB9;
|
|
colourDish[18][0] = 0x05;
|
|
colourDish[18][1] = 0x30;
|
|
colourDish[18][2] = 0xE1;
|
|
colourDish[19][0] = 0x57;
|
|
colourDish[19][1] = 0x18;
|
|
colourDish[19][2] = 0xDA;
|
|
colourDish[20][0] = 0x9F;
|
|
colourDish[20][1] = 0x07;
|
|
colourDish[20][2] = 0xA7;
|
|
colourDish[21][0] = 0xCC;
|
|
colourDish[21][1] = 0x02;
|
|
colourDish[21][2] = 0x55;
|
|
colourDish[22][0] = 0xCF;
|
|
colourDish[22][1] = 0x0B;
|
|
colourDish[22][2] = 0x00;
|
|
colourDish[23][0] = 0xA4;
|
|
colourDish[23][1] = 0x23;
|
|
colourDish[23][2] = 0x00;
|
|
colourDish[24][0] = 0x5C;
|
|
colourDish[24][1] = 0x3F;
|
|
colourDish[24][2] = 0x00;
|
|
colourDish[25][0] = 0x0B;
|
|
colourDish[25][1] = 0x58;
|
|
colourDish[25][2] = 0x00;
|
|
colourDish[26][0] = 0x00;
|
|
colourDish[26][1] = 0x66;
|
|
colourDish[26][2] = 0x00;
|
|
colourDish[27][0] = 0x00;
|
|
colourDish[27][1] = 0x67;
|
|
colourDish[27][2] = 0x13;
|
|
colourDish[28][0] = 0x00;
|
|
colourDish[28][1] = 0x5E;
|
|
colourDish[28][2] = 0x6E;
|
|
colourDish[29][0] = 0x00;
|
|
colourDish[29][1] = 0x00;
|
|
colourDish[29][2] = 0x00;
|
|
colourDish[30][0] = 0x00;
|
|
colourDish[30][1] = 0x00;
|
|
colourDish[30][2] = 0x00;
|
|
colourDish[31][0] = 0x00;
|
|
colourDish[31][1] = 0x00;
|
|
colourDish[31][2] = 0x00;
|
|
|
|
colourDish[32][0] = 0xFE;
|
|
colourDish[32][1] = 0xFE;
|
|
colourDish[32][2] = 0xFE;
|
|
colourDish[33][0] = 0x1F;
|
|
colourDish[33][1] = 0x9E;
|
|
colourDish[33][2] = 0xFF;
|
|
colourDish[34][0] = 0x53;
|
|
colourDish[34][1] = 0x76;
|
|
colourDish[34][2] = 0xFF;
|
|
colourDish[35][0] = 0x98;
|
|
colourDish[35][1] = 0x65;
|
|
colourDish[35][2] = 0xFF;
|
|
colourDish[36][0] = 0xFC;
|
|
colourDish[36][1] = 0x67;
|
|
colourDish[36][2] = 0xFF;
|
|
colourDish[37][0] = 0xFF;
|
|
colourDish[37][1] = 0x6C;
|
|
colourDish[37][2] = 0xB3;
|
|
colourDish[38][0] = 0xFF;
|
|
colourDish[38][1] = 0x74;
|
|
colourDish[38][2] = 0x66;
|
|
colourDish[39][0] = 0xFF;
|
|
colourDish[39][1] = 0x80;
|
|
colourDish[39][2] = 0x14;
|
|
colourDish[40][0] = 0xC4;
|
|
colourDish[40][1] = 0x9A;
|
|
colourDish[40][2] = 0x00;
|
|
colourDish[41][0] = 0x71;
|
|
colourDish[41][1] = 0xB3;
|
|
colourDish[41][2] = 0x00;
|
|
colourDish[42][0] = 0x28;
|
|
colourDish[42][1] = 0xC4;
|
|
colourDish[42][2] = 0x21;
|
|
colourDish[43][0] = 0x00;
|
|
colourDish[43][1] = 0xCB;
|
|
colourDish[43][2] = 0x74;
|
|
colourDish[44][0] = 0x00;
|
|
colourDish[44][1] = 0xBF;
|
|
colourDish[44][2] = 0xD0;
|
|
colourDish[45][0] = 0x2B;
|
|
colourDish[45][1] = 0x2B;
|
|
colourDish[45][2] = 0x2B;
|
|
colourDish[46][0] = 0x00;
|
|
colourDish[46][1] = 0x00;
|
|
colourDish[46][2] = 0x00;
|
|
colourDish[47][0] = 0x00;
|
|
colourDish[47][1] = 0x00;
|
|
colourDish[47][2] = 0x00;
|
|
|
|
colourDish[48][0] = 0xFF;
|
|
colourDish[48][1] = 0xFF;
|
|
colourDish[48][2] = 0xFF;
|
|
colourDish[49][0] = 0x9E;
|
|
colourDish[49][1] = 0xD5;
|
|
colourDish[49][2] = 0xFF;
|
|
colourDish[50][0] = 0xAF;
|
|
colourDish[50][1] = 0xC0;
|
|
colourDish[50][2] = 0xFF;
|
|
colourDish[51][0] = 0xD0;
|
|
colourDish[51][1] = 0xB8;
|
|
colourDish[51][2] = 0xFF;
|
|
colourDish[52][0] = 0xFE;
|
|
colourDish[52][1] = 0xBF;
|
|
colourDish[52][2] = 0xFF;
|
|
colourDish[53][0] = 0xFF;
|
|
colourDish[53][1] = 0xC0;
|
|
colourDish[53][2] = 0xE0;
|
|
colourDish[54][0] = 0xFF;
|
|
colourDish[54][1] = 0xC3;
|
|
colourDish[54][2] = 0xBD;
|
|
colourDish[55][0] = 0xFF;
|
|
colourDish[55][1] = 0xCA;
|
|
colourDish[55][2] = 0x9C;
|
|
colourDish[56][0] = 0xE7;
|
|
colourDish[56][1] = 0xD5;
|
|
colourDish[56][2] = 0x8B;
|
|
colourDish[57][0] = 0xC5;
|
|
colourDish[57][1] = 0xDF;
|
|
colourDish[57][2] = 0x8E;
|
|
colourDish[58][0] = 0xA6;
|
|
colourDish[58][1] = 0xE6;
|
|
colourDish[58][2] = 0xA3;
|
|
colourDish[59][0] = 0x94;
|
|
colourDish[59][1] = 0xE8;
|
|
colourDish[59][2] = 0xC5;
|
|
colourDish[60][0] = 0x92;
|
|
colourDish[60][1] = 0xE4;
|
|
colourDish[60][2] = 0xEB;
|
|
colourDish[61][0] = 0xA7;
|
|
colourDish[61][1] = 0xA7;
|
|
colourDish[61][2] = 0xA7;
|
|
colourDish[62][0] = 0x00;
|
|
colourDish[62][1] = 0x00;
|
|
colourDish[62][2] = 0x00;
|
|
colourDish[63][0] = 0x00;
|
|
colourDish[63][1] = 0x00;
|
|
colourDish[63][2] = 0x00;
|
|
*/
|
|
for(Uint8 i = 0; i < 64; i++){
|
|
colourList[i] = (colourDish[i][0] << 24) | (colourDish[i][1] << 16) | (colourDish[i][2] << 8) | 0xFF;
|
|
}
|
|
}
|
|
|
|
|
|
void video::initBuffer(){
|
|
GLsizei vSize;
|
|
|
|
//vertex data is fixed
|
|
GLshort vbuffer[142560]; //240*33*6*3
|
|
|
|
for(int i = 0; i < 240; i++){
|
|
for(int j = 0; j < 33; j++){
|
|
vbuffer[(i * 33 + j) * 18] = (GLshort)(j * 8);
|
|
vbuffer[(i * 33 + j) * 18 + 1] = -(GLshort)(i);
|
|
vbuffer[(i * 33 + j) * 18 + 2] = (GLshort)(0);
|
|
|
|
vbuffer[(i * 33 + j) * 18 + 3] = (GLshort)((j + 1) * 8);
|
|
vbuffer[(i * 33 + j) * 18 + 4] = -(GLshort)(i);
|
|
vbuffer[(i * 33 + j) * 18 + 5] = (GLshort)(1);
|
|
|
|
vbuffer[(i * 33 + j) * 18 + 6] = (GLshort)((j + 1) * 8);
|
|
vbuffer[(i * 33 + j) * 18 + 7] = -(GLshort)(i + 1);
|
|
vbuffer[(i * 33 + j) * 18 + 8] = (GLshort)(2);
|
|
|
|
vbuffer[(i * 33 + j) * 18 + 9] = (GLshort)((j + 1) * 8);
|
|
vbuffer[(i * 33 + j) * 18 + 10] = -(GLshort)(i + 1);
|
|
vbuffer[(i * 33 + j) * 18 + 11] = (GLshort)(2);
|
|
|
|
vbuffer[(i * 33 + j) * 18 + 12] = (GLshort)(j * 8);
|
|
vbuffer[(i * 33 + j) * 18 + 13] = -(GLshort)(i + 1);
|
|
vbuffer[(i * 33 + j) * 18 + 14] = (GLshort)(3);
|
|
|
|
vbuffer[(i * 33 + j) * 18 + 15] = (GLshort)(j * 8);
|
|
vbuffer[(i * 33 + j) * 18 + 16] = -(GLshort)(i);
|
|
vbuffer[(i * 33 + j) * 18 + 17] = (GLshort)(0);
|
|
}
|
|
}
|
|
|
|
vSize = 142560 * sizeof(GLshort);
|
|
bgVBufferRef = make_buffer(GL_ARRAY_BUFFER, 0, vSize);
|
|
glBufferSubData(GL_ARRAY_BUFFER, 0, vSize, vbuffer);
|
|
|
|
bgCBufferRef = make_buffer(GL_ARRAY_BUFFER, 0, bgCBufferSize);
|
|
bgCBuffer = (GLfloat*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
|
|
|
|
vSize = 34560 * sizeof(GLshort); //240 * 8 * 6 * 3
|
|
spVBufferRef = make_buffer(GL_ARRAY_BUFFER, 0, vSize);
|
|
spVBuffer = (GLshort*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
|
|
|
|
vSize = 46080 * sizeof(GLfloat); //240 * 8 * 6 * 4
|
|
spCBufferRef = make_buffer(GL_ARRAY_BUFFER, 0, vSize);
|
|
spCBuffer = (GLfloat*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
|
|
|
|
}
|
|
|
|
void video::initPatternArea(){
|
|
spPatCount = 0;
|
|
lastPatID = TEXTURE_CACHE_TILE_COUNT;
|
|
hdTextureCache = (Uint32 *)malloc(packScale * packScale * TEXTURE_CACHE_TILE_COUNT * 4 * 8 * 8);
|
|
}
|
|
|
|
void video::initScanlineData(Uint16 row){
|
|
flagsTexture[row] = 0x00;
|
|
if(ppuCore->showBGOnLeft) flagsTexture[row] = flagsTexture[row] | 0x01;
|
|
if(ppuCore->showSprOnLeft) flagsTexture[row] = flagsTexture[row] | 0x02;
|
|
if(ppuCore->intensifyR) flagsTexture[row] = flagsTexture[row] | 0x04;
|
|
if(ppuCore->intensifyG) flagsTexture[row] = flagsTexture[row] | 0x08;
|
|
if(ppuCore->intensifyB) flagsTexture[row] = flagsTexture[row] | 0x10;
|
|
if(ppuCore->useGrayscale) flagsTexture[row] = flagsTexture[row] | 0x20;
|
|
|
|
if(ppuCore->showBG){
|
|
bgXTexture[row] = ppuCore->offsetX;
|
|
if(row % 8 == 0){
|
|
BgRender[row / 8][33] = ppuCore->offsetX;
|
|
BgRender[row / 8][34] = ppuCore->bgLoadingY;
|
|
}
|
|
}
|
|
lastIsHD = false;
|
|
}
|
|
|
|
void video::setBGStripData(Uint16 row, Uint8 bgID){
|
|
GLfloat decodeX;
|
|
GLfloat decodeY;
|
|
GLfloat brightness;
|
|
Uint32 idx;
|
|
Uint8 patternW[5] = {0, 8, 16, 24, 32};
|
|
bool patternMatch;
|
|
rawPattern patternData;
|
|
colorCombo colors;
|
|
bool isHD;
|
|
GLfloat isHDVal;
|
|
|
|
idx = ((row * 33) + bgID) * 24;
|
|
|
|
if(ppuCore->showBG){
|
|
if(row % 8 == 0){
|
|
BgRender[row / 8][bgID] = ppuCore->bgAddressFretched[bgID];
|
|
}
|
|
colors.color1 = memDat->paletteTable[ppuCore->bgPaletteFretched[bgID]][1];
|
|
colors.color2 = memDat->paletteTable[ppuCore->bgPaletteFretched[bgID]][2];
|
|
colors.color3 = memDat->paletteTable[ppuCore->bgPaletteFretched[bgID]][3];
|
|
prepareTileData(true, ppuCore->bgAddressFretched[bgID], ppuCore->bgTableID[bgID], ppuCore->bgNameTableAddress[bgID], ppuCore->bgLoadingY, colors,
|
|
ppuCore->bgRAMAddress[bgID], decodeX, decodeY, isHD, brightness);
|
|
|
|
isHDVal = (isHD ? 0.0 : 1.0);
|
|
bgCBuffer[idx] = decodeX;
|
|
++idx;
|
|
bgCBuffer[idx] = decodeY;
|
|
++idx;
|
|
bgCBuffer[idx] = brightness;
|
|
++idx;
|
|
bgCBuffer[idx] = isHDVal;
|
|
++idx;
|
|
|
|
bgCBuffer[idx] = decodeX + 1 / (GLfloat)TEXTURE_CACHE_TILE_COL_COUNT;
|
|
++idx;
|
|
bgCBuffer[idx] = decodeY;
|
|
++idx;
|
|
bgCBuffer[idx] = brightness;
|
|
++idx;
|
|
bgCBuffer[idx] = isHDVal;
|
|
++idx;
|
|
|
|
bgCBuffer[idx] = decodeX + 1 / (GLfloat)TEXTURE_CACHE_TILE_COL_COUNT;
|
|
++idx;
|
|
bgCBuffer[idx] = decodeY + 1 / (GLfloat)(TEXTURE_CACHE_TILE_ROW_COUNT * 8);
|
|
++idx;
|
|
bgCBuffer[idx] = brightness;
|
|
++idx;
|
|
bgCBuffer[idx] = isHDVal;
|
|
++idx;
|
|
|
|
//
|
|
bgCBuffer[idx] = decodeX + 1 / (GLfloat)TEXTURE_CACHE_TILE_COL_COUNT;
|
|
++idx;
|
|
bgCBuffer[idx] = decodeY + 1 / (GLfloat)(TEXTURE_CACHE_TILE_ROW_COUNT * 8);
|
|
++idx;
|
|
bgCBuffer[idx] = brightness;
|
|
++idx;
|
|
bgCBuffer[idx] = isHDVal;
|
|
++idx;
|
|
|
|
bgCBuffer[idx] = decodeX;
|
|
++idx;
|
|
bgCBuffer[idx] = decodeY + 1 / (GLfloat)(TEXTURE_CACHE_TILE_ROW_COUNT * 8);
|
|
++idx;
|
|
bgCBuffer[idx] = brightness;
|
|
++idx;
|
|
bgCBuffer[idx] = isHDVal;
|
|
++idx;
|
|
|
|
bgCBuffer[idx] = decodeX;
|
|
++idx;
|
|
bgCBuffer[idx] = decodeY;
|
|
++idx;
|
|
bgCBuffer[idx] = brightness;
|
|
++idx;
|
|
bgCBuffer[idx] = isHDVal;
|
|
++idx;
|
|
}
|
|
else{
|
|
bgXTexture[row] = 255;
|
|
}
|
|
|
|
|
|
if(editRecordingType != RECORDING_TYPE_NONE && ppuCore->frameCount > 20 && (chrRamMatch || romDat->chrPageCount > 0)){
|
|
if ((row >=8 && row < 224) || (row < 232 && !cutEdgeTiles)) {
|
|
if(ppuCore->showBG){
|
|
//look up the tile
|
|
//only for top row of the tile
|
|
if(ppuCore->bgLoadingY == 0){
|
|
//bg tiles
|
|
int tileX = (bgID * 8) - ppuCore->offsetX;
|
|
if((tileX >= 8 && tileX <= 240) || ((tileX >= 0 && tileX <= 248) && !cutEdgeTiles)){
|
|
int index = ppuCore->bgAddressFretched[bgID];
|
|
if(index != BAD_ADDRESS){
|
|
TileData t;
|
|
//0 for bg
|
|
t.defaultID = 0;
|
|
t.patternAddress = index;
|
|
|
|
int packID = -1;
|
|
int packID2 = -1;
|
|
|
|
if(romDat->chrPageCount == 0){
|
|
patternData = *((rawPattern*)(&(romDat->chrRAM[ppuCore->bgRAMAddress[bgID]])));
|
|
}
|
|
|
|
if (editData[index] != BAD_ADDRESS){
|
|
TileData* pt;
|
|
pt = &(etiledata[editData[index]]);
|
|
for (unsigned int idx = 0; idx < pt->bitmapP.size(); ++idx)
|
|
{
|
|
if (pt->bitmapP[idx].colors.colorValues == colors.colorValues){
|
|
if(romDat->chrPageCount > 0){
|
|
patternMatch = true;
|
|
}
|
|
else{
|
|
patternMatch = (patternData.pixStrip1 == pt->bitmapP[idx].rawDat.pixStrip1
|
|
&& patternData.pixStrip2 == pt->bitmapP[idx].rawDat.pixStrip2
|
|
&& patternData.pixStrip3 == pt->bitmapP[idx].rawDat.pixStrip3
|
|
&& patternData.pixStrip4 == pt->bitmapP[idx].rawDat.pixStrip4);
|
|
}
|
|
if(patternMatch){
|
|
packID = idx;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (packID == -1){
|
|
for (unsigned int idx = 0; idx < screenTiles.size(); ++idx)
|
|
{
|
|
if (screenTiles[idx].patternAddress == ppuCore->bgAddressFretched[bgID]
|
|
&& screenTiles[idx].colors.colorValues == colors.colorValues){
|
|
if(romDat->chrPageCount > 0){
|
|
patternMatch = true;
|
|
}
|
|
else{
|
|
patternMatch = (patternData.pixStrip1 == screenTiles[idx].rawDat.pixStrip1
|
|
&& patternData.pixStrip2 == screenTiles[idx].rawDat.pixStrip2
|
|
&& patternData.pixStrip3 == screenTiles[idx].rawDat.pixStrip3
|
|
&& patternData.pixStrip4 == screenTiles[idx].rawDat.pixStrip4);
|
|
}
|
|
if(patternMatch){
|
|
packID = idx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (allEditData[index] == BAD_ADDRESS){
|
|
t = etiledata[editData[index]];
|
|
}
|
|
}
|
|
else{
|
|
editData[index] = etiledata.size();
|
|
etiledata.push_back(t);
|
|
}
|
|
|
|
if (allEditData[index] == BAD_ADDRESS){
|
|
allEditData[index] = allEtiledata.size();
|
|
allEtiledata.push_back(t);
|
|
}
|
|
if (packID != -1){
|
|
for (unsigned int idx = 0; idx < allScreenTiles.size(); ++idx){
|
|
if (allScreenTiles[idx].patternAddress == ppuCore->bgAddressFretched[bgID]
|
|
&& allScreenTiles[idx].colors.colorValues == colors.colorValues){
|
|
if(romDat->chrPageCount > 0){
|
|
patternMatch = true;
|
|
}
|
|
else{
|
|
patternMatch = (patternData.pixStrip1 == allScreenTiles[idx].rawDat.pixStrip1
|
|
&& patternData.pixStrip2 == allScreenTiles[idx].rawDat.pixStrip2
|
|
&& patternData.pixStrip3 == allScreenTiles[idx].rawDat.pixStrip3
|
|
&& patternData.pixStrip4 == allScreenTiles[idx].rawDat.pixStrip4);
|
|
}
|
|
if(patternMatch){
|
|
packID2 = idx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (packID == -1 || packID2 == -1){
|
|
screenTile st;
|
|
st.isBg = true;
|
|
st.patternAddress = ppuCore->bgAddressFretched[bgID];
|
|
st.colors = colors;
|
|
if(romDat->chrPageCount == 0){
|
|
st.rawDat = patternData;
|
|
}
|
|
st.x = tileX;
|
|
st.y = row;
|
|
st.tileName = "";
|
|
if(packID == -1){
|
|
screenTiles.push_back(st);
|
|
}
|
|
if(packID2 == -1){
|
|
allScreenTiles.push_back(st);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void video::setSPStripData(Uint16 row, Uint16 col, Uint8 spID){
|
|
GLfloat decodeX;
|
|
GLfloat decodeY;
|
|
GLfloat brightness;
|
|
Uint32 idx;
|
|
Uint32 idxc;
|
|
Uint8 patternW[5] = {0, 8, 16, 24, 32};
|
|
bool isHD;
|
|
GLfloat isHDVal;
|
|
|
|
GLshort spZ;
|
|
GLfloat spY1;
|
|
GLfloat spY2;
|
|
GLfloat spX1;
|
|
GLfloat spX2;
|
|
bool patternMatch;
|
|
rawPattern patternData;
|
|
colorCombo colors;
|
|
|
|
idx = spPatCount * 18;
|
|
idxc = spPatCount * 24;
|
|
|
|
if((ppuCore->tmpSprRAM2[spID * 4 + 1] != 0xff || ppuCore->tmpSprRAM2[spID * 4 + 2] != 0xff || ppuCore->tmpSprRAM2[spID * 4 + 3] != 0xff) && (ppuCore->spRowFretched[spID] < ppuCore->sprHeight) && ppuCore->showSpr){
|
|
colors.color1 = memDat->paletteTable[(ppuCore->tmpSprRAM2[spID * 4 + 2] & 0x03) | 0x04][1];
|
|
colors.color2 = memDat->paletteTable[(ppuCore->tmpSprRAM2[spID * 4 + 2] & 0x03) | 0x04][2];
|
|
colors.color3 = memDat->paletteTable[(ppuCore->tmpSprRAM2[spID * 4 + 2] & 0x03) | 0x04][3];
|
|
|
|
prepareTileData(false, ppuCore->spAddressFretched[spID], 0, ppuCore->spEvalAddress[spID] + (ppuCore->spEvalIsTopTile[spID] == 0 ? 0 : 64), ppuCore->spRowFretched[spID], colors,
|
|
ppuCore->spRAMAddress[spID], decodeX, decodeY, isHD, brightness);
|
|
|
|
//check is back
|
|
spZ = (GLshort)((((ppuCore->tmpSprRAM2[spID * 4 + 2] >> 5) & 0x01) != 0? 11 : 1) + spID);
|
|
spVBuffer[idx] = (GLshort)(col);
|
|
++idx;
|
|
spVBuffer[idx] = -(GLshort)(row);
|
|
++idx;
|
|
spVBuffer[idx] = spZ;
|
|
++idx;
|
|
|
|
spVBuffer[idx] = (GLshort)(col + 8);
|
|
++idx;
|
|
spVBuffer[idx] = -(GLshort)(row);
|
|
++idx;
|
|
spVBuffer[idx] = spZ;
|
|
++idx;
|
|
|
|
spVBuffer[idx] = (GLshort)(col + 8);
|
|
++idx;
|
|
spVBuffer[idx] = -(GLshort)(row + 1);
|
|
++idx;
|
|
spVBuffer[idx] = spZ;
|
|
++idx;
|
|
|
|
spVBuffer[idx] = (GLshort)(col + 8);
|
|
++idx;
|
|
spVBuffer[idx] = -(GLshort)(row + 1);
|
|
++idx;
|
|
spVBuffer[idx] = spZ;
|
|
++idx;
|
|
|
|
spVBuffer[idx] = (GLshort)(col);
|
|
++idx;
|
|
spVBuffer[idx] = -(GLshort)(row + 1);
|
|
++idx;
|
|
spVBuffer[idx] = spZ;
|
|
++idx;
|
|
|
|
spVBuffer[idx] = (GLshort)(col);
|
|
++idx;
|
|
spVBuffer[idx] = -(GLshort)(row);
|
|
++idx;
|
|
spVBuffer[idx] = spZ;
|
|
++idx;
|
|
|
|
|
|
//check v flip
|
|
isHDVal = (isHD ? 0.0 : 1.0);
|
|
if(ppuCore->tmpSprRAM2[spID * 4 + 2] >> 7 == 0){
|
|
spY1 = decodeY;
|
|
spY2 = decodeY + 1 / (GLfloat)(TEXTURE_CACHE_TILE_ROW_COUNT * 8);
|
|
}
|
|
else{
|
|
spY1 = decodeY + 1 / (GLfloat)(TEXTURE_CACHE_TILE_ROW_COUNT * 8);
|
|
spY2 = decodeY;
|
|
}
|
|
|
|
if(((ppuCore->tmpSprRAM2[spID * 4 + 2] >> 6) & 0x01) == 0){
|
|
spX1 = decodeX;
|
|
spX2 = decodeX + 1 / (GLfloat)TEXTURE_CACHE_TILE_COL_COUNT;
|
|
}
|
|
else{
|
|
spX1 = decodeX + 1 / (GLfloat)TEXTURE_CACHE_TILE_COL_COUNT;
|
|
spX2 = decodeX;
|
|
}
|
|
|
|
spCBuffer[idxc] = spX1;
|
|
++idxc;
|
|
spCBuffer[idxc] = spY1;
|
|
++idxc;
|
|
spCBuffer[idxc] = brightness;
|
|
++idxc;
|
|
spCBuffer[idxc] = isHDVal;
|
|
++idxc;
|
|
|
|
spCBuffer[idxc] = spX2;
|
|
++idxc;
|
|
spCBuffer[idxc] = spY1;
|
|
++idxc;
|
|
spCBuffer[idxc] = brightness;
|
|
++idxc;
|
|
spCBuffer[idxc] = isHDVal;
|
|
++idxc;
|
|
|
|
spCBuffer[idxc] = spX2;
|
|
++idxc;
|
|
spCBuffer[idxc] = spY2;
|
|
++idxc;
|
|
spCBuffer[idxc] = brightness;
|
|
++idxc;
|
|
spCBuffer[idxc] = isHDVal;
|
|
++idxc;
|
|
|
|
spCBuffer[idxc] = spX2;
|
|
++idxc;
|
|
spCBuffer[idxc] = spY2;
|
|
++idxc;
|
|
spCBuffer[idxc] = brightness;
|
|
++idxc;
|
|
spCBuffer[idxc] = isHDVal;
|
|
++idxc;
|
|
|
|
spCBuffer[idxc] = spX1;
|
|
++idxc;
|
|
spCBuffer[idxc] = spY2;
|
|
++idxc;
|
|
spCBuffer[idxc] = brightness;
|
|
++idxc;
|
|
spCBuffer[idxc] = isHDVal;
|
|
++idxc;
|
|
|
|
spCBuffer[idxc] = spX1;
|
|
++idxc;
|
|
spCBuffer[idxc] = spY1;
|
|
++idxc;
|
|
spCBuffer[idxc] = brightness;
|
|
++idxc;
|
|
spCBuffer[idxc] = isHDVal;
|
|
++idxc;
|
|
|
|
spPatCount++;
|
|
}
|
|
|
|
if(editRecordingType != RECORDING_TYPE_NONE && ppuCore->frameCount > 20 && (chrRamMatch || romDat->chrPageCount > 0)){
|
|
if ((row >= 8 && row < 224) || (row < 232 && !cutEdgeTiles)) {
|
|
if(ppuCore->showSpr){
|
|
if(ppuCore->tmpSprRAM2[spID * 4] != 0xff){
|
|
if(((col >= 16 && col <= 248) || (col >= 8 && !cutEdgeTiles))
|
|
&& (ppuCore->spRowFretched[spID] == (ppuCore->tmpSprRAM2[spID * 4 + 2] >> 7 == 0 ? 0 : 7)
|
|
|| ppuCore->spRowFretched[spID] == (ppuCore->tmpSprRAM2[spID * 4 + 2] >> 7 == 0 ? 8 : 15))){
|
|
int index = ppuCore->spAddressFretched[spID];
|
|
if(index != BAD_ADDRESS){
|
|
TileData t;
|
|
t.defaultID = 1;
|
|
t.patternAddress = index;
|
|
|
|
int packID = -1;
|
|
int packID2 = -1;
|
|
|
|
if(romDat->chrPageCount == 0){
|
|
patternData = *((rawPattern*)(&(romDat->chrRAM[ppuCore->spRAMAddress[spID]])));
|
|
}
|
|
if (editData[index] != BAD_ADDRESS){
|
|
TileData* pt;
|
|
pt = &(etiledata[editData[index]]);
|
|
for (unsigned int idx = 0; idx < pt->bitmapP.size(); ++idx){
|
|
if (pt->bitmapP[idx].colors.colorValues == colors.colorValues){
|
|
if(romDat->chrPageCount > 0){
|
|
patternMatch = true;
|
|
}
|
|
else{
|
|
patternMatch = (patternData.pixStrip1 == pt->bitmapP[idx].rawDat.pixStrip1
|
|
&& patternData.pixStrip2 == pt->bitmapP[idx].rawDat.pixStrip2
|
|
&& patternData.pixStrip3 == pt->bitmapP[idx].rawDat.pixStrip3
|
|
&& patternData.pixStrip4 == pt->bitmapP[idx].rawDat.pixStrip4);
|
|
}
|
|
if(patternMatch){
|
|
packID = idx;
|
|
}
|
|
}
|
|
}
|
|
if (packID == -1){
|
|
//check data found in current frame
|
|
for (unsigned int idx = 0; idx < screenTiles.size(); ++idx)
|
|
{
|
|
if (screenTiles[idx].patternAddress == ppuCore->spAddressFretched[spID]
|
|
&& screenTiles[idx].colors.colorValues == colors.colorValues){
|
|
if(romDat->chrPageCount > 0){
|
|
patternMatch = true;
|
|
}
|
|
else{
|
|
patternMatch = (patternData.pixStrip1 == screenTiles[idx].rawDat.pixStrip1
|
|
&& patternData.pixStrip2 == screenTiles[idx].rawDat.pixStrip2
|
|
&& patternData.pixStrip3 == screenTiles[idx].rawDat.pixStrip3
|
|
&& patternData.pixStrip4 == screenTiles[idx].rawDat.pixStrip4);
|
|
}
|
|
if(patternMatch){
|
|
packID = idx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (allEditData[index] == BAD_ADDRESS){
|
|
t = etiledata[editData[index]];
|
|
}
|
|
}
|
|
else{
|
|
editData[index] = etiledata.size();
|
|
etiledata.push_back(t);
|
|
}
|
|
|
|
if (allEditData[index] == BAD_ADDRESS){
|
|
allEditData[index] = allEtiledata.size();
|
|
allEtiledata.push_back(t);
|
|
}
|
|
|
|
if (packID != -1){
|
|
for (unsigned int idx = 0; idx < allScreenTiles.size(); ++idx){
|
|
if (allScreenTiles[idx].patternAddress == ppuCore->spAddressFretched[spID]
|
|
&& allScreenTiles[idx].colors.colorValues == colors.colorValues){
|
|
if(romDat->chrPageCount > 0){
|
|
patternMatch = true;
|
|
}
|
|
else{
|
|
patternMatch = (patternData.pixStrip1 == allScreenTiles[idx].rawDat.pixStrip1
|
|
&& patternData.pixStrip2 == allScreenTiles[idx].rawDat.pixStrip2
|
|
&& patternData.pixStrip3 == allScreenTiles[idx].rawDat.pixStrip3
|
|
&& patternData.pixStrip4 == allScreenTiles[idx].rawDat.pixStrip4);
|
|
}
|
|
if(patternMatch){
|
|
packID2 = idx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (packID == -1 || packID2 == -1){
|
|
screenTile st;
|
|
st.isBg = false;
|
|
st.patternAddress = ppuCore->spAddressFretched[spID];
|
|
st.colors = colors;
|
|
if(romDat->chrPageCount == 0){
|
|
st.rawDat = patternData;
|
|
}
|
|
st.x = col;
|
|
st.y = row;
|
|
st.tileName = "";
|
|
if(packID == -1){
|
|
screenTiles.push_back(st);
|
|
}
|
|
if(packID2 == -1){
|
|
allScreenTiles.push_back(st);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void video::initHDResult(){
|
|
if(!hdResultInInitState){
|
|
memset(bgHDResult, 0xFF, 4 * 0x3C0 * 2);
|
|
memset(spHDResult, 0xFF, 64 * 2 * 2);
|
|
hdResultInInitState = true;
|
|
}
|
|
}
|
|
|
|
void video::prepareTileData(bool isBg, Uint32 patternAddress, Uint8 tableID, Uint16 nameTableAddress, Uint8 row,
|
|
colorCombo colors, Uint32 ramAddress, GLfloat& decodedX, GLfloat& decodedY, bool& isHD, GLfloat& brightness){
|
|
bool hasWork = true;
|
|
|
|
Uint32 idx;
|
|
Uint16* hdResult;
|
|
Uint16 resultSize;
|
|
|
|
bool blankFound = false;
|
|
Uint8 pix;
|
|
Uint32 picPos;
|
|
|
|
Uint16 readResult;
|
|
bool hasHD;
|
|
Uint32 picPos2;
|
|
bitmapF packbmp;
|
|
|
|
bool patternMatch;
|
|
rawPattern patternData;
|
|
Uint16 tilePatternX;
|
|
Uint16 tilePatternY;
|
|
|
|
if(isBg){
|
|
hdResult = (Uint16*)bgHDResult;
|
|
resultSize = 0x3C0;
|
|
}
|
|
else{
|
|
hdResult = (Uint16*)spHDResult;
|
|
resultSize = 0;
|
|
if(row >= 8) row -= 8;
|
|
}
|
|
//look up index
|
|
if(patternAddress != BAD_ADDRESS){
|
|
Uint8 lookupIdx = (patternAddress & 0x00FF);
|
|
|
|
if(romDat->chrPageCount == 0){
|
|
patternData = *((rawPattern*)(&(romDat->chrRAM[ramAddress])));
|
|
}
|
|
|
|
//check for repeating tiles
|
|
if(lastIsHD){
|
|
if(hdPatternData[lastPatID].patternAddress == patternAddress
|
|
&& hdPatternData[lastPatID].colors.colorValues == colors.colorValues){
|
|
if(romDat->chrPageCount > 0){
|
|
patternMatch = true;
|
|
}
|
|
else{
|
|
patternMatch = (patternData.pixStrip1 == hdPatternData[lastPatID].rawDat.pixStrip1
|
|
&& patternData.pixStrip2 == hdPatternData[lastPatID].rawDat.pixStrip2
|
|
&& patternData.pixStrip3 == hdPatternData[lastPatID].rawDat.pixStrip3
|
|
&& patternData.pixStrip4 == hdPatternData[lastPatID].rawDat.pixStrip4);
|
|
}
|
|
if(patternMatch){
|
|
hasWork = false;
|
|
decodedX = ((lastPatID) & 0x3F) / (GLfloat)TEXTURE_CACHE_TILE_COL_COUNT;
|
|
decodedY = ((((lastPatID) >> TEXTURE_CACHE_TILE_COL_SHIFT) & 0x01F8) + row) / (GLfloat)(TEXTURE_CACHE_TILE_ROW_COUNT * 8);
|
|
brightness = hdPatternData[lastPatID].brightness;
|
|
hdPatternInUse[lastPatID] = 1;
|
|
isHD = true;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
if(basePatternData[lastPatID].patternAddress == patternAddress
|
|
&& basePatternData[lastPatID].colors.colorValues == colors.colorValues){
|
|
if(romDat->chrPageCount > 0){
|
|
patternMatch = true;
|
|
}
|
|
else{
|
|
patternMatch = (patternData.pixStrip1 == basePatternData[lastPatID].rawDat.pixStrip1
|
|
&& patternData.pixStrip2 == basePatternData[lastPatID].rawDat.pixStrip2
|
|
&& patternData.pixStrip3 == basePatternData[lastPatID].rawDat.pixStrip3
|
|
&& patternData.pixStrip4 == basePatternData[lastPatID].rawDat.pixStrip4);
|
|
}
|
|
if(patternMatch){
|
|
hasWork = false;
|
|
decodedX = ((lastPatID) & 0x3F) / (GLfloat)TEXTURE_CACHE_TILE_COL_COUNT;
|
|
decodedY = ((((lastPatID) >> TEXTURE_CACHE_TILE_COL_SHIFT) & 0x01F8) + row) / (GLfloat)(TEXTURE_CACHE_TILE_ROW_COUNT * 8);
|
|
brightness = 1.0;
|
|
basePatternInUse[lastPatID] = 1;
|
|
isHD = false;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
//look for matching pattern
|
|
size_t e = hdList[lookupIdx].size();
|
|
if(e > 0){
|
|
const Uint32* lastInt = &hdList[lookupIdx][e - 1];
|
|
Uint32* i = &hdList[lookupIdx][0];
|
|
for( ; i <= lastInt; ++i){
|
|
if(hdPatternData[*i].patternAddress == patternAddress
|
|
&& hdPatternData[*i].colors.colorValues == colors.colorValues){
|
|
if(romDat->chrPageCount > 0){
|
|
patternMatch = true;
|
|
}
|
|
else{
|
|
patternMatch = (patternData.pixStrip1 == hdPatternData[*i].rawDat.pixStrip1
|
|
&& patternData.pixStrip2 == hdPatternData[*i].rawDat.pixStrip2
|
|
&& patternData.pixStrip3 == hdPatternData[*i].rawDat.pixStrip3
|
|
&& patternData.pixStrip4 == hdPatternData[*i].rawDat.pixStrip4);
|
|
}
|
|
if(patternMatch){
|
|
hasWork = false;
|
|
decodedX = ((*i) & 0x3F) / (GLfloat)TEXTURE_CACHE_TILE_COL_COUNT;
|
|
decodedY = ((((*i) >> TEXTURE_CACHE_TILE_COL_SHIFT) & 0x01F8) + row) / (GLfloat)(TEXTURE_CACHE_TILE_ROW_COUNT * 8);
|
|
brightness = hdPatternData[*i].brightness;
|
|
hdPatternInUse[*i] = 1;
|
|
lastIsHD = true;
|
|
lastPatID = *i;
|
|
isHD = true;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
e = baseList[lookupIdx].size();
|
|
if(e > 0){{
|
|
const Uint32* lastInt = &baseList[lookupIdx][e - 1];
|
|
Uint32* i = &baseList[lookupIdx][0];
|
|
for( ; i <= lastInt; ++i){
|
|
if(basePatternData[*i].patternAddress == patternAddress
|
|
&& basePatternData[*i].colors.colorValues == colors.colorValues){
|
|
if(romDat->chrPageCount > 0){
|
|
patternMatch = true;
|
|
}
|
|
else{
|
|
patternMatch = (patternData.pixStrip1 == basePatternData[*i].rawDat.pixStrip1
|
|
&& patternData.pixStrip2 == basePatternData[*i].rawDat.pixStrip2
|
|
&& patternData.pixStrip3 == basePatternData[*i].rawDat.pixStrip3
|
|
&& patternData.pixStrip4 == basePatternData[*i].rawDat.pixStrip4);
|
|
}
|
|
if(patternMatch){
|
|
hasWork = false;
|
|
decodedX = ((*i) & 0x3F) / (GLfloat)TEXTURE_CACHE_TILE_COL_COUNT;
|
|
decodedY = ((((*i) >> TEXTURE_CACHE_TILE_COL_SHIFT) & 0x01F8) + row) / (GLfloat)(TEXTURE_CACHE_TILE_ROW_COUNT * 8);
|
|
brightness = 1.0;
|
|
basePatternInUse[*i] = 1;
|
|
lastIsHD = false;
|
|
lastPatID = *i;
|
|
isHD = false;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
hasHD = false;
|
|
if(usePack){
|
|
//check the tile has HD version
|
|
if((chrRamMatch || romDat->chrPageCount > 0) && patternAddress != BAD_ADDRESS){
|
|
readResult = hdResult[tableID * resultSize + nameTableAddress];
|
|
if((readResult != HD_TILE_NOT_CHECKED)){
|
|
if(readResult == HD_TILE_NO_MATCH){
|
|
hasHD = false;
|
|
}
|
|
else{
|
|
TileData* t;
|
|
hasHD = true;
|
|
t = &(tdata[packData[patternAddress]]);
|
|
packbmp = t->bitmapP[readResult];
|
|
}
|
|
}
|
|
else{
|
|
hdResultInInitState = false;
|
|
hdResult[tableID * resultSize + nameTableAddress] = HD_TILE_NO_MATCH;
|
|
if (packData[patternAddress] != BAD_ADDRESS){
|
|
TileData* t;
|
|
int packID = -1;
|
|
t = &(tdata[packData[patternAddress]]);
|
|
for (unsigned int tidx = 0; tidx < t->bitmapP.size(); ++tidx){
|
|
if (t->bitmapP[tidx].colors.colorValues == colors.colorValues){
|
|
if(romDat->chrPageCount > 0){
|
|
patternMatch = true;
|
|
}
|
|
else{
|
|
patternMatch = (patternData.pixStrip1 == t->bitmapP[tidx].rawDat.pixStrip1
|
|
&& patternData.pixStrip2 == t->bitmapP[tidx].rawDat.pixStrip2
|
|
&& patternData.pixStrip3 == t->bitmapP[tidx].rawDat.pixStrip3
|
|
&& patternData.pixStrip4 == t->bitmapP[tidx].rawDat.pixStrip4);
|
|
}
|
|
if(patternMatch){
|
|
packID = tidx;
|
|
hasHD = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (packID == -1 && t->defaultID != -1){
|
|
packID = t->defaultID;
|
|
hasHD = true;
|
|
}
|
|
if(hasHD){
|
|
//get scale from hd pack
|
|
packbmp = t->bitmapP[packID];
|
|
hdResult[tableID * resultSize + nameTableAddress] = packID;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//look for blank space
|
|
if(hasHD){
|
|
idx = maxHDIdx;
|
|
while(!blankFound){
|
|
if(!blankFound && hdPatternInUse[idx] != 1){
|
|
blankFound = true;
|
|
}
|
|
else{
|
|
++idx;
|
|
if(idx >= TEXTURE_CACHE_TILE_COUNT){
|
|
idx = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
tilePatternX = ((idx & 0x3F) << 3) * packScale;
|
|
tilePatternY = ((idx >> TEXTURE_CACHE_TILE_COL_SHIFT) & 0x01F8) * packScale;
|
|
}
|
|
else{
|
|
idx = maxBaseIdx;
|
|
while(!blankFound){
|
|
if(!blankFound && basePatternInUse[idx] != 1){
|
|
blankFound = true;
|
|
}
|
|
else{
|
|
++idx;
|
|
if(idx >= TEXTURE_CACHE_TILE_COUNT){
|
|
idx = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
tilePatternX = (idx & 0x3F) << 3;
|
|
tilePatternY = (idx >> TEXTURE_CACHE_TILE_COL_SHIFT) & 0x01F8;
|
|
}
|
|
decodedX = (idx & 0x3F) / (GLfloat)TEXTURE_CACHE_TILE_COL_COUNT;
|
|
decodedY = (((idx >> TEXTURE_CACHE_TILE_COL_SHIFT) & 0x01F8) + row) / (GLfloat)(TEXTURE_CACHE_TILE_ROW_COUNT * 8);
|
|
|
|
|
|
lastPatID = idx;
|
|
lastIsHD = hasHD;
|
|
isHD = hasHD;
|
|
if(!hasHD){
|
|
brightness = 1.0f;
|
|
//decode
|
|
picPos = tilePatternY * 512 + tilePatternX;
|
|
|
|
if(romDat->chrPageCount > 0){
|
|
patternData = *((rawPattern*)(&(romDat->chrROM[patternAddress << 4])));
|
|
}
|
|
Uint8 patternByte0;
|
|
Uint8 patternByte1;
|
|
Uint8* patternBytes = (Uint8*)&patternData;
|
|
Uint8* patternBytes1 = patternBytes + 8;
|
|
for(int j = 0; j < 8; ++j){
|
|
patternByte0 = *patternBytes;
|
|
++patternBytes;
|
|
patternByte1 = *patternBytes1;
|
|
++patternBytes1;
|
|
for(int i = 7; i >= 0; --i){
|
|
pix = ((patternByte0 >> i) & 0x01) | (((patternByte1 >> i) & 0x01) << 1);
|
|
switch(pix){
|
|
case 0:
|
|
baseTextureCache[picPos] = 0;
|
|
break;
|
|
case 1:
|
|
baseTextureCache[picPos] = colourList[colors.color1 & 0x3F];
|
|
break;
|
|
case 2:
|
|
baseTextureCache[picPos] = colourList[colors.color2 & 0x3F];
|
|
break;
|
|
case 3:
|
|
baseTextureCache[picPos] = colourList[colors.color3 & 0x3F];
|
|
break;
|
|
}
|
|
picPos++;
|
|
}
|
|
picPos += 504;
|
|
}
|
|
maxBaseIdx = idx + 1;
|
|
if(maxBaseIdx >= TEXTURE_CACHE_TILE_COUNT){
|
|
maxBaseIdx = 0;
|
|
}
|
|
if(basePatternInUse[idx] == 0){
|
|
//if previous used then remove the previous record
|
|
baseList[basePatternData[idx].lookupIdx].erase(baseList[basePatternData[idx].lookupIdx].begin() + basePatternData[idx].index);
|
|
//shift remaining entries
|
|
if(baseList[basePatternData[idx].lookupIdx].size() > basePatternData[idx].index){
|
|
for(std::vector<Uint32>::const_iterator i = baseList[basePatternData[idx].lookupIdx].begin() + basePatternData[idx].index; i != baseList[basePatternData[idx].lookupIdx].end(); i++){
|
|
basePatternData[*i].index = basePatternData[*i].index - 1;
|
|
}
|
|
}
|
|
}
|
|
basePatternInUse[idx] = 1;
|
|
basePatternData[idx].patternAddress = patternAddress;
|
|
basePatternData[idx].colors = colors;
|
|
basePatternData[idx].rawDat = patternData;
|
|
basePatternData[idx].lookupIdx = lookupIdx;
|
|
basePatternData[idx].index = baseList[lookupIdx].size();
|
|
basePatternData[idx].brightness = brightness;
|
|
baseList[lookupIdx].push_back(idx);
|
|
}
|
|
else{
|
|
brightness = packbmp.brightness;
|
|
picPos = tilePatternY * 512 * packScale + tilePatternX;
|
|
picPos2 = (packbmp.y * bmpInfos[packbmp.bitmapID].width + packbmp.x) * 4;
|
|
|
|
scale4Pattern* sp4;
|
|
scale4Pattern* rb4;
|
|
scale2Pattern* sp2;
|
|
scale2Pattern* rb2;
|
|
scale1Pattern* sp1;
|
|
scale1Pattern* rb1;
|
|
|
|
for(int j = 0; j < 8; ++j){
|
|
switch (packScale) {
|
|
case 4:
|
|
|
|
sp4 = (scale4Pattern*)&(hdTextureCache[picPos]);
|
|
rb4 = (scale4Pattern*)&((rawBits[packbmp.bitmapID])[picPos2]);
|
|
sp4[0] = rb4[0];
|
|
|
|
picPos += 2048;
|
|
picPos2 += (bmpInfos[packbmp.bitmapID].width * 4);
|
|
sp4 = (scale4Pattern*)&(hdTextureCache[picPos]);
|
|
rb4 = (scale4Pattern*)&((rawBits[packbmp.bitmapID])[picPos2]);
|
|
sp4[0] = rb4[0];
|
|
|
|
picPos += 2048;
|
|
picPos2 += (bmpInfos[packbmp.bitmapID].width * 4);
|
|
sp4 = (scale4Pattern*)&(hdTextureCache[picPos]);
|
|
rb4 = (scale4Pattern*)&((rawBits[packbmp.bitmapID])[picPos2]);
|
|
sp4[0] = rb4[0];
|
|
|
|
picPos += 2048;
|
|
picPos2 += (bmpInfos[packbmp.bitmapID].width * 4);
|
|
sp4 = (scale4Pattern*)&(hdTextureCache[picPos]);
|
|
rb4 = (scale4Pattern*)&((rawBits[packbmp.bitmapID])[picPos2]);
|
|
sp4[0] = rb4[0];
|
|
|
|
picPos += 2048;
|
|
picPos2 += (bmpInfos[packbmp.bitmapID].width * 4);
|
|
break;
|
|
case 2:
|
|
sp2 = (scale2Pattern*)&(hdTextureCache[picPos]);
|
|
rb2 = (scale2Pattern*)&((rawBits[packbmp.bitmapID])[picPos2]);
|
|
sp2[0] = rb2[0];
|
|
|
|
picPos += 1024;
|
|
picPos2 += (bmpInfos[packbmp.bitmapID].width * 4);
|
|
sp2 = (scale2Pattern*)&(hdTextureCache[picPos]);
|
|
rb2 = (scale2Pattern*)&((rawBits[packbmp.bitmapID])[picPos2]);
|
|
sp2[0] = rb2[0];
|
|
|
|
picPos += 1024;
|
|
picPos2 += (bmpInfos[packbmp.bitmapID].width * 4);
|
|
break;
|
|
|
|
default:
|
|
sp1 = (scale1Pattern*)&(hdTextureCache[picPos]);
|
|
rb1 = (scale1Pattern*)&((rawBits[packbmp.bitmapID])[picPos2]);
|
|
sp1[0] = rb1[0];
|
|
|
|
picPos += 512;
|
|
picPos2 += (bmpInfos[packbmp.bitmapID].width * 4);
|
|
break;
|
|
}
|
|
}
|
|
maxHDIdx = idx + 1;
|
|
if(maxHDIdx >= TEXTURE_CACHE_TILE_COUNT){
|
|
maxHDIdx = 0;
|
|
}
|
|
if(hdPatternInUse[idx] == 0){
|
|
//if previous used then remove the previous record
|
|
hdList[hdPatternData[idx].lookupIdx].erase(hdList[hdPatternData[idx].lookupIdx].begin() + hdPatternData[idx].index);
|
|
//shift remaining entries
|
|
if(hdList[hdPatternData[idx].lookupIdx].size() > hdPatternData[idx].index){
|
|
for(std::vector<Uint32>::const_iterator i = hdList[hdPatternData[idx].lookupIdx].begin() + hdPatternData[idx].index; i != hdList[hdPatternData[idx].lookupIdx].end(); i++){
|
|
hdPatternData[*i].index = hdPatternData[*i].index - 1;
|
|
}
|
|
}
|
|
}
|
|
hdPatternInUse[idx] = 1;
|
|
hdPatternData[idx].patternAddress = patternAddress;
|
|
hdPatternData[idx].colors = colors;
|
|
hdPatternData[idx].rawDat = patternData;
|
|
hdPatternData[idx].lookupIdx = lookupIdx;
|
|
hdPatternData[idx].index = hdList[lookupIdx].size();
|
|
hdPatternData[idx].brightness = brightness;
|
|
hdList[lookupIdx].push_back(idx);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void video::capScreen(bool useNative){
|
|
char buffer [80];
|
|
char frameCntBuffer[15];
|
|
time_t timer;
|
|
struct tm * timeinfo;
|
|
string filename;
|
|
|
|
//cpuCore->runLog = !cpuCore->runLog;
|
|
time(&timer);
|
|
timeinfo = localtime (&timer);
|
|
strftime (buffer,80,"%Y%m%d%H%M%S",timeinfo);
|
|
sprintf (frameCntBuffer, "X%013d", ppuCore->frameCount);
|
|
filename = setting->exeDir + "\\screen\\" + buffer + frameCntBuffer + ".png";
|
|
|
|
saveScreenToPath(filename, useNative);
|
|
|
|
////save graphic strips
|
|
SaveGraphics(setting->exeDir + "\\screen\\" + buffer + to_string((long double)ppuCore->frameCount));
|
|
|
|
////save buffers
|
|
//SaveBuffers(setting->exeDir + "\\screen\\" + buffer + to_string((long double)ppuCore->frameCount));
|
|
|
|
////save sprite
|
|
//ppuCore->saveSprObjects(setting->exeDir + "\\screen\\" + buffer + to_string((long double)ppuCore->frameCount));
|
|
//ppuCore->saveVRam(setting->exeDir + "\\screen\\" + buffer + to_string((long double)ppuCore->frameCount));
|
|
//saveBG(setting->exeDir + "\\screen\\" + buffer + to_string((long double)ppuCore->frameCount));
|
|
|
|
|
|
capScreenFlag = false;
|
|
}
|
|
|
|
void video::saveScreenToPath(string path, bool useNative){
|
|
int capWidth;
|
|
int capHeight;
|
|
int idxX[DISPLAY_WIDTH];
|
|
int idxY[DISPLAY_HEIGHT];
|
|
|
|
if (useNative) {
|
|
capWidth = DISPLAY_WIDTH;
|
|
capHeight = DISPLAY_HEIGHT;
|
|
for(unsigned int tmpy = 0; tmpy < DISPLAY_HEIGHT; ++tmpy){
|
|
idxY[tmpy] = screenSizeHeight * tmpy / capHeight;
|
|
}
|
|
for(unsigned int tmpx = 0; tmpx < DISPLAY_WIDTH; ++tmpx){
|
|
idxX[tmpx] = screenSizeWidth * tmpx / capWidth;
|
|
}
|
|
}
|
|
else{
|
|
capWidth = screenSizeWidth;
|
|
capHeight = screenSizeHeight;
|
|
}
|
|
|
|
GLubyte *data = (GLubyte *)malloc(4 * screenSizeWidth * screenSizeHeight);
|
|
if(data) {
|
|
glReadPixels(0, 0, screenSizeWidth, screenSizeHeight, GL_RGB, GL_UNSIGNED_BYTE, data);
|
|
|
|
SDL_Surface * sc = SDL_CreateRGBSurface(SDL_SWSURFACE, capWidth, capHeight, 24, 0x0000FF, 0x00FF00, 0xFF0000, 0);
|
|
if(sc){
|
|
int i;
|
|
int j;
|
|
int y;
|
|
int runy;
|
|
SDL_LockSurface(sc);
|
|
for(y = capHeight - 1, runy = 0; y >= 0; --y, ++runy){
|
|
Uint8 *p = (Uint8 *)sc->pixels + y * sc->pitch;
|
|
j = 0;
|
|
for(unsigned int x = 0; x < capWidth; ++x){
|
|
if (useNative){
|
|
i = 3 * (screenSizeWidth * idxY[runy] + idxX[x]);
|
|
}
|
|
else{
|
|
i = 3 * (screenSizeWidth * runy + x);
|
|
}
|
|
p[j] = data[i];
|
|
i++;
|
|
j++;
|
|
p[j] = data[i];
|
|
i++;
|
|
j++;
|
|
p[j] = data[i];
|
|
j++;
|
|
}
|
|
}
|
|
SDL_UnlockSurface(sc);
|
|
SDL_SaveBMP(sc, (path + ".bmp").c_str());
|
|
SDL_FreeSurface(sc);
|
|
}
|
|
|
|
capScreenQueue.push_back(path);
|
|
SDL_Thread* gh;
|
|
gh = SDL_CreateThread(video::convertScreenCapToPNG, NULL, NULL);
|
|
|
|
}
|
|
else{
|
|
return;
|
|
}
|
|
|
|
free(data);
|
|
}
|
|
|
|
int video::convertScreenCapToPNG(void* data){
|
|
string path;
|
|
wxImage objimg;
|
|
while(vid->capScreenQueue.size() > 0){
|
|
path = vid->capScreenQueue[vid->capScreenQueue.size() - 1];
|
|
vid->capScreenQueue.pop_back();
|
|
objimg = wxImage(wxString((path + ".bmp").c_str(), wxConvUTF8));
|
|
objimg.SaveFile(wxString(path.c_str(), wxConvUTF8));
|
|
remove((path + ".bmp").c_str());
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void video::SaveHiResPack(){
|
|
char rawPalette[192];
|
|
if(packData == 0) return;
|
|
|
|
//get directory and check exists
|
|
string path = getHDPackPath();
|
|
_mkdir(path.c_str());
|
|
DWORD ftyp = GetFileAttributesA(path.c_str());
|
|
if (ftyp & FILE_ATTRIBUTE_DIRECTORY){
|
|
string filename;
|
|
fstream logfile;
|
|
|
|
filename = path + "\\hires.txt";
|
|
logfile.open(filename, ios::out | ios::trunc);
|
|
if (logfile.is_open()){
|
|
logfile << "<ver>2\n";
|
|
logfile << "<scale>" + to_string((long double)packScale) + "\n";
|
|
for(unsigned int i = 0; i < bmpInfos.size(); i++){
|
|
logfile << "<img>" + bmpInfos[i].filename + "\n";
|
|
}
|
|
|
|
for(unsigned int i = 0; i < packSize; i++){
|
|
if(packData[i] != BAD_ADDRESS){
|
|
for(unsigned int j = 0; j < tdata[packData[i]].bitmapP.size(); j++){
|
|
bitmapF b = tdata[packData[i]].bitmapP[j];
|
|
logfile << "<tile>" + to_string((long double)i) + ","
|
|
+ to_string((long double)b.bitmapID) + ","
|
|
+ to_string((long double)b.colors.color1) + ","
|
|
+ to_string((long double)b.colors.color2) + ","
|
|
+ to_string((long double)b.colors.color3) + ","
|
|
+ to_string((long double)b.x) + ","
|
|
+ to_string((long double)b.y) + ","
|
|
+ to_string((long double)b.brightness) + ","
|
|
+ (tdata[packData[i]].defaultID == j ? "Y" : "N");
|
|
|
|
if(romDat->chrPageCount == 0){
|
|
for(int i = 0; i < 16; i++){
|
|
logfile << ", " + to_string((long double)(*((Uint8*)(&(b.rawDat)) + i)));
|
|
}
|
|
}
|
|
|
|
logfile << "\n";
|
|
}
|
|
}
|
|
}
|
|
for(unsigned int i = 0; i < metaSprites.size(); i++){
|
|
metaSprite metaspr = metaSprites[i];
|
|
|
|
logfile << "<metas>" + metaspr.name + ","
|
|
+ to_string((long double)metaspr.bitmapID) + ","
|
|
+ to_string((long double)metaspr.brightness) + ","
|
|
+ to_string((long double)metaspr.priority) + ","
|
|
+ (metaspr.useLargeSpr ? "Y" : "N");
|
|
logfile << "\n";
|
|
|
|
for(unsigned int j = 0; j < metaspr.parts.size(); j++){
|
|
metaSpritePart metaPart = metaspr.parts[j];
|
|
|
|
logfile << "<metasp>" + to_string((long double)metaPart.patternAddress) + ","
|
|
+ to_string((long double)metaPart.colors.color1) + ","
|
|
+ to_string((long double)metaPart.colors.color2) + ","
|
|
+ to_string((long double)metaPart.colors.color3) + ","
|
|
+ to_string((long double)metaPart.relativeX) + ","
|
|
+ to_string((long double)metaPart.relativeY) + ","
|
|
+ (metaPart.relativeHFlip ? "Y" : "N") + ","
|
|
+ (metaPart.relativeVFlip ? "Y" : "N") + ","
|
|
+ (metaPart.isSecond ? "Y" : "N");
|
|
if(romDat->chrPageCount == 0){
|
|
for(int i = 0; i < 16; i++){
|
|
logfile << ", " + to_string((long double)(*((Uint8*)(&(metaPart.rawDat)) + i)));
|
|
}
|
|
}
|
|
logfile << "\n";
|
|
}
|
|
}
|
|
logfile.close();
|
|
}
|
|
filename = path + "\\palette.dat";
|
|
logfile.open(filename, ios::out | ios::binary | ios::trunc);
|
|
if (logfile.is_open()){
|
|
for (int i = 0; i < 64; i++) {
|
|
rawPalette[i * 3] = (colourList[i] >> 24) & 0xff;
|
|
rawPalette[i * 3 + 1] = (colourList[i] >> 16) & 0xff;
|
|
rawPalette[i * 3 + 2] = (colourList[i] >> 8) & 0xff;
|
|
}
|
|
logfile.write((char *)(rawPalette), 192);
|
|
logfile.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void video::ReadHiResPack(){
|
|
int packVersion = 0;
|
|
int readIdx;
|
|
packData = (Uint32*) malloc(packSize * sizeof(Uint32));
|
|
for(unsigned int i = 0; i < packSize; i++){
|
|
packData[i] = BAD_ADDRESS;
|
|
}
|
|
packScale = 2;
|
|
packVersion = 0;
|
|
initColour();
|
|
|
|
//get directory and check exists
|
|
string path = getHDPackPath();
|
|
DWORD ftyp = GetFileAttributesA(path.c_str());
|
|
if (ftyp & FILE_ATTRIBUTE_DIRECTORY){
|
|
|
|
//read the file
|
|
fstream inifile;
|
|
string line;
|
|
|
|
inifile.open(path + "\\hires.txt", ios::in);
|
|
if (inifile.is_open()){
|
|
|
|
while ( inifile.good() ){
|
|
std::getline(inifile, line);
|
|
if(line.substr(0, 5) == "<ver>"){
|
|
//read version number
|
|
packVersion = stoi(line.substr(5, string::npos));
|
|
}
|
|
else if(line.substr(0, 5) == "<img>"){
|
|
//read a png file
|
|
string bmpName = line.substr(5, string::npos);
|
|
AddHiResImg(bmpName);
|
|
}
|
|
else if(line.substr(0, 6) == "<tile>"){
|
|
vector<string> lineTokens;
|
|
|
|
split(line.substr(6, string::npos), ',', lineTokens);
|
|
if (lineTokens.size() >= 8) {
|
|
int index = stoi(lineTokens[0]);
|
|
if (packData[index] == BAD_ADDRESS){
|
|
packData[index] = tdata.size();
|
|
TileData t;
|
|
t.patternAddress = index;
|
|
tdata.push_back(t);
|
|
tdata.back().defaultID = -1;
|
|
}
|
|
bitmapF b;
|
|
b.bitmapID = stoi(lineTokens[1]);
|
|
b.colors.color1 = stoi(lineTokens[2]);
|
|
b.colors.color2 = stoi(lineTokens[3]);
|
|
b.colors.color3 = stoi(lineTokens[4]);
|
|
b.x = stoi(lineTokens[5]);
|
|
b.y = stoi(lineTokens[6]);
|
|
|
|
readIdx = 7;
|
|
if (packVersion > 0) {
|
|
b.brightness = stof(lineTokens[readIdx]);
|
|
readIdx++;
|
|
}
|
|
else{
|
|
b.brightness = 1.0f;
|
|
}
|
|
|
|
if(lineTokens[readIdx] == "Y"){
|
|
tdata[packData[index]].defaultID = tdata[packData[index]].bitmapP.size();
|
|
readIdx++;
|
|
}
|
|
readIdx++;
|
|
if(romDat->chrPageCount == 0){
|
|
for(int i = 0; i < 16; i++){
|
|
*((Uint8*)(&(b.rawDat)) + i) = stoi(lineTokens[readIdx]);
|
|
readIdx++;
|
|
}
|
|
}
|
|
|
|
tdata[packData[index]].bitmapP.push_back(b);
|
|
}
|
|
|
|
}
|
|
else if(line.substr(0, 7) == "<scale>"){
|
|
packScale = stoi(line.substr(7, string::npos));
|
|
}
|
|
else if(line.substr(0, 7) == "<metas>"){
|
|
vector<string> lineTokens;
|
|
|
|
split(line.substr(7, string::npos), ',', lineTokens);
|
|
if (lineTokens.size() >= 5) {
|
|
metaSprite metaspr;
|
|
metaspr.id = metaSprites.size();
|
|
metaspr.name = lineTokens[0];
|
|
metaspr.bitmapID = stoi(lineTokens[1]);
|
|
metaspr.brightness = stof(lineTokens[2]);
|
|
metaspr.priority = stoi(lineTokens[3]);
|
|
metaspr.useLargeSpr = (lineTokens[4] == "Y");
|
|
metaSprites.push_back(metaspr);
|
|
}
|
|
}
|
|
else if(line.substr(0, 8) == "<metasp>"){
|
|
vector<string> lineTokens;
|
|
|
|
split(line.substr(8, string::npos), ',', lineTokens);
|
|
if (lineTokens.size() >= 9) {
|
|
metaSpritePart metapat;
|
|
metapat.patternAddress = stoi(lineTokens[0]);
|
|
metapat.colors.color1 = stoi(lineTokens[1]);
|
|
metapat.colors.color2 = stoi(lineTokens[2]);
|
|
metapat.colors.color3 = stoi(lineTokens[3]);
|
|
metapat.relativeX = stoi(lineTokens[4]);
|
|
metapat.relativeY = stoi(lineTokens[5]);
|
|
metapat.relativeHFlip = (lineTokens[6] == "Y");
|
|
metapat.relativeVFlip = (lineTokens[7] == "Y");
|
|
metapat.isSecond = (lineTokens[8] == "Y");
|
|
if(romDat->chrPageCount == 0){
|
|
for(int i = 9; i < 25; i++){
|
|
*((Uint8*)(&(metapat.rawDat)) + i) = stoi(lineTokens[i]);
|
|
}
|
|
}
|
|
metaSprite metaspr = metaSprites[metaSprites.size() - 1];
|
|
metaspr.parts.push_back(metapat);
|
|
metaSprites[metaSprites.size() - 1] = metaspr;
|
|
}
|
|
}
|
|
}
|
|
inifile.close();
|
|
|
|
if(packVersion > 1){
|
|
ReadPalette(path + "\\palette.dat");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void video::CleanHiResPack(){
|
|
if(packData){
|
|
free(packData);
|
|
for(unsigned int i = 0; i < rawBits.size(); i++) {
|
|
free(rawBits[i]);
|
|
}
|
|
tdata.clear();
|
|
rawBits.clear();
|
|
bmpInfos.clear();
|
|
metaSprites.clear();
|
|
}
|
|
}
|
|
|
|
void video::AddHiResImg(string filename){
|
|
SDL_Surface * pngs;
|
|
pngs = IMG_Load((getHDPackPath() + "\\" + filename).c_str());
|
|
Uint8* bits = (Uint8*) malloc(pngs->w * pngs->h * 4);
|
|
SDL_LockSurface(pngs);
|
|
int i = 0;
|
|
for(int y = 0; y < pngs->h; y++){
|
|
for(int x = 0; x < pngs->w; x++){
|
|
Uint8 *p = (Uint8 *)pngs->pixels + y * pngs->pitch + x * 4;
|
|
bits[i] = p[3];
|
|
i++;
|
|
bits[i] = p[2];
|
|
i++;
|
|
bits[i] = p[1];
|
|
i++;
|
|
bits[i] = p[0];
|
|
i++;
|
|
}
|
|
}
|
|
bmpInfo bsize;
|
|
bsize.width = pngs->w;
|
|
bsize.height = pngs->h;
|
|
bsize.filename = filename;
|
|
bmpInfos.push_back(bsize);
|
|
|
|
SDL_UnlockSurface(pngs);
|
|
SDL_FreeSurface(pngs);
|
|
rawBits.push_back(bits);
|
|
}
|
|
|
|
void video::RemoveHiResImg(unsigned int pID){
|
|
bmpInfos.erase(bmpInfos.begin() + pID);
|
|
}
|
|
|
|
void video::AddDarkMapping(){
|
|
bool hasMatch;
|
|
TileData* t;
|
|
TileData e;
|
|
bitmapF newD;
|
|
//go through each HD tile
|
|
for(unsigned int i = 0; i < packSize; i++){
|
|
if(packData[i] != BAD_ADDRESS){
|
|
t = &(tdata[packData[i]]);
|
|
if(t->defaultID == -1){
|
|
for(unsigned int j = 0; j < t->bitmapP.size(); j++){
|
|
bitmapF b = t->bitmapP[j];
|
|
if(b.brightness == 1.0f){
|
|
if (editData[i] != BAD_ADDRESS){
|
|
//do not add if it has a default
|
|
|
|
|
|
e = etiledata[editData[i]];
|
|
//search for a palette of that tile with no HD replacement
|
|
for(unsigned int k = 0; k < e.bitmapP.size(); k++){
|
|
//only do it when that palette is different from the original
|
|
if (e.bitmapP[k].colors.colorValues != b.colors.colorValues) {
|
|
hasMatch = false;
|
|
for(unsigned int l = 0; l < t->bitmapP.size(); l++){
|
|
if (t->bitmapP[l].colors.colorValues == e.bitmapP[k].colors.colorValues){
|
|
if(romDat->chrPageCount > 0){
|
|
hasMatch = true;
|
|
}
|
|
else{
|
|
hasMatch = (e.bitmapP[k].rawDat.pixStrip1 == t->bitmapP[l].rawDat.pixStrip1
|
|
&& e.bitmapP[k].rawDat.pixStrip2 == t->bitmapP[l].rawDat.pixStrip2
|
|
&& e.bitmapP[k].rawDat.pixStrip3 == t->bitmapP[l].rawDat.pixStrip3
|
|
&& e.bitmapP[k].rawDat.pixStrip4 == t->bitmapP[l].rawDat.pixStrip4);
|
|
}
|
|
if(hasMatch){
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
if(!hasMatch) {
|
|
//check that palette is a darker version of the HD tile
|
|
if(IsDarkerPalette(e.bitmapP[k].colors, b.colors)){
|
|
//add a mapping to it and calculate a brightness value for the palette
|
|
newD = b;
|
|
newD.brightness = CalBrightnessValue(e.bitmapP[k].colors, b.colors);
|
|
newD.colors = e.bitmapP[k].colors;
|
|
newD.isBg = e.bitmapP[k].isBg;
|
|
t->bitmapP.push_back(newD);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
string video::GetPaletteString(colorCombo color){
|
|
char tmpStr[10];
|
|
sprintf_s(tmpStr,"%02x,%02x,%02x", color.color1, color.color2, color.color3);
|
|
return string(tmpStr);
|
|
}
|
|
|
|
|
|
GLfloat video::CalBrightnessValue(colorCombo color, colorCombo refColor){
|
|
Uint16 b1;
|
|
Uint16 b2;
|
|
|
|
b1 = ((colourList[color.color1] >> 24) & 0x00FF) + ((colourList[color.color1] >> 16) & 0x00FF) + ((colourList[color.color1] >> 8) & 0x00FF)
|
|
+ ((colourList[color.color2] >> 24) & 0x00FF) + ((colourList[color.color2] >> 16) & 0x00FF) + ((colourList[color.color2] >> 8) & 0x00FF)
|
|
+ ((colourList[color.color3] >> 24) & 0x00FF) + ((colourList[color.color3] >> 16) & 0x00FF) + ((colourList[color.color3] >> 8) & 0x00FF);
|
|
b2 = ((colourList[refColor.color1] >> 24) & 0x00FF) + ((colourList[refColor.color1] >> 16) & 0x00FF) + ((colourList[refColor.color1] >> 8) & 0x00FF)
|
|
+ ((colourList[refColor.color2] >> 24) & 0x00FF) + ((colourList[refColor.color2] >> 16) & 0x00FF) + ((colourList[refColor.color2] >> 8) & 0x00FF)
|
|
+ ((colourList[refColor.color3] >> 24) & 0x00FF) + ((colourList[refColor.color3] >> 16) & 0x00FF) + ((colourList[refColor.color3] >> 8) & 0x00FF);
|
|
if (b2 > 0) {
|
|
return (float)((b1 * 100) / b2) / 100.0f;
|
|
}
|
|
else{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
bool video::IsDarkerPalette(colorCombo color, colorCombo refColor){
|
|
return IsDarkerColor(color.color1, refColor.color1) && IsDarkerColor(color.color2, refColor.color2) && IsDarkerColor(color.color3, refColor.color3);
|
|
}
|
|
|
|
bool video::IsDarkerColor(Uint16 color, Uint16 refColor){
|
|
if(color == refColor){
|
|
return true;
|
|
}
|
|
else if(colourList[color] == 0x000000FF){
|
|
//return true for new color is pure black
|
|
return true;
|
|
}
|
|
else if(colourList[refColor] == 0x000000FF){
|
|
//return false for old color is pure black
|
|
return false;
|
|
}
|
|
else if(((color & 0x000F) == 0x0000) || ((color & 0x000F) == 0x000D)){
|
|
//monochrome matching
|
|
if(((refColor & 0x000F) == 0x0000) || ((refColor & 0x000F) == 0x000D)){
|
|
return (colourList[refColor] >= colourList[color]);
|
|
}
|
|
else{
|
|
return false;
|
|
}
|
|
}
|
|
else{
|
|
//color matching
|
|
if(((refColor & 0x000F) == 0x0000) || ((refColor & 0x000F) == 0x000D)){
|
|
return false;
|
|
}
|
|
else{
|
|
Uint16 row1;
|
|
Uint16 row2;
|
|
Uint16 hue1;
|
|
Uint16 hue2;
|
|
Uint16 hueDif;
|
|
|
|
row1 = (color & 0x00F0) >> 4;
|
|
row2 = (refColor & 0x00F0) >> 4;
|
|
if (row2 > row1){
|
|
hue1 = (color & 0x000F);
|
|
hue2 = (refColor & 0x000F);
|
|
if (hue1 > hue2) {
|
|
hueDif = hue1 - hue2;
|
|
}
|
|
else{
|
|
hueDif = hue2 - hue1;
|
|
}
|
|
if((row2 - row1) <=2) {
|
|
if(hueDif <= 1 || hueDif == 11){
|
|
return true;
|
|
}
|
|
else{
|
|
return false;
|
|
}
|
|
}
|
|
else{
|
|
if(hueDif <= 2 || hueDif >= 10){
|
|
return true;
|
|
}
|
|
else{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void video::ReadPackEdit(){
|
|
editData = (Uint32*) malloc(packSize * sizeof(Uint32));
|
|
allEditData = (Uint32*) malloc(packSize * sizeof(Uint32));
|
|
for(unsigned int i = 0; i < packSize; i++){
|
|
editData[i] = BAD_ADDRESS;
|
|
allEditData[i] = BAD_ADDRESS;
|
|
}
|
|
//get directory and check exists
|
|
string path = getEditPackPath();
|
|
_mkdir(path.c_str());
|
|
|
|
DWORD ftyp = GetFileAttributesA(path.c_str());
|
|
if (ftyp & FILE_ATTRIBUTE_DIRECTORY){
|
|
|
|
//read the file
|
|
fstream inifile;
|
|
fstream inifile2;
|
|
string line;
|
|
|
|
screenNameList.clear();
|
|
screenFileNameList.clear();
|
|
etiledata.clear();
|
|
allEtiledata.clear();
|
|
|
|
inifile.open(path + "screen.dat", ios::in);
|
|
if (inifile.is_open()){
|
|
while ( inifile.good() ){
|
|
std::getline(inifile, line);
|
|
vector<string> lineTokens;
|
|
|
|
split(line, ';', lineTokens);
|
|
if(lineTokens.size() == 2){
|
|
screenFileNameList.push_back(lineTokens[0]);
|
|
screenNameList.push_back(lineTokens[1]);
|
|
inifile2.open(path + lineTokens[0] + ".dat", ios::in);
|
|
if (inifile2.is_open()){
|
|
while ( inifile2.good() ){
|
|
std::getline(inifile2, line);
|
|
vector<string> lineTokens2;
|
|
|
|
split(line, ',', lineTokens2);
|
|
if(lineTokens2.size() >= 7){
|
|
int index = stoi(lineTokens2[1]);
|
|
|
|
if (editData[index] == BAD_ADDRESS){
|
|
TileData t;
|
|
if(lineTokens2[0] == "Y"){
|
|
t.defaultID = 0;
|
|
}
|
|
else{
|
|
t.defaultID = 1;
|
|
}
|
|
t.patternAddress = index;
|
|
editData[index] = etiledata.size();
|
|
etiledata.push_back(t);
|
|
}
|
|
|
|
bitmapF b;
|
|
b.isBg = (lineTokens2[0] == "Y");
|
|
b.bitmapID = screenFileNameList.size() - 1;
|
|
b.colors.color1 = stoi(lineTokens2[2]);
|
|
b.colors.color2 = stoi(lineTokens2[3]);
|
|
b.colors.color3 = stoi(lineTokens2[4]);
|
|
b.x = stoi(lineTokens2[5]);
|
|
b.y = stoi(lineTokens2[6]);
|
|
if(romDat->chrPageCount == 0){
|
|
for(int i = 0; i < 16; i++){
|
|
*((Uint8*)(&(b.rawDat)) + i) = stoi(lineTokens2[7 + i]);
|
|
}
|
|
}
|
|
etiledata[editData[index]].bitmapP.push_back(b);
|
|
|
|
}
|
|
}
|
|
}
|
|
inifile2.close();
|
|
inifile2.open(path + lineTokens[0] + "_a.dat", ios::in);
|
|
if (inifile2.is_open()){
|
|
while ( inifile2.good() ){
|
|
std::getline(inifile2, line);
|
|
vector<string> lineTokens2;
|
|
|
|
split(line, ',', lineTokens2);
|
|
if(lineTokens2.size() >= 7){
|
|
int index = stoi(lineTokens2[1]);
|
|
|
|
if (allEditData[index] == BAD_ADDRESS){
|
|
TileData t;
|
|
if(lineTokens2[0] == "Y"){
|
|
t.defaultID = 0;
|
|
}
|
|
else{
|
|
t.defaultID = 1;
|
|
}
|
|
t.patternAddress = index;
|
|
allEditData[index] = allEtiledata.size();
|
|
allEtiledata.push_back(t);
|
|
}
|
|
|
|
bitmapF b;
|
|
b.isBg = (lineTokens2[0] == "Y");
|
|
b.bitmapID = screenFileNameList.size() - 1;
|
|
b.colors.color1 = stoi(lineTokens2[2]);
|
|
b.colors.color2 = stoi(lineTokens2[3]);
|
|
b.colors.color3 = stoi(lineTokens2[4]);
|
|
b.x = stoi(lineTokens2[5]);
|
|
b.y = stoi(lineTokens2[6]);
|
|
if(romDat->chrPageCount == 0){
|
|
for(int i = 0; i < 16; i++){
|
|
*((Uint8*)(&(b.rawDat)) + i) = stoi(lineTokens2[7 + i]);
|
|
}
|
|
}
|
|
|
|
allEtiledata[allEditData[index]].bitmapP.push_back(b);
|
|
}
|
|
|
|
}
|
|
}
|
|
inifile2.close();
|
|
}
|
|
}
|
|
inifile.close();
|
|
guiForm->refreshGraphicsPackGUI();
|
|
}
|
|
}
|
|
}
|
|
|
|
void video::CleanPackEdit(){
|
|
if(editData){
|
|
free(editData);
|
|
}
|
|
}
|
|
|
|
void video::readConfig(string value){
|
|
vector<string> lineTokens;
|
|
|
|
split(value, ',', lineTokens);
|
|
if (lineTokens[0].compare("screensize") == 0) {
|
|
screenSizeOption = stoi(lineTokens[1]);
|
|
screenSizeWidth = stoi(lineTokens[2]);
|
|
screenSizeHeight = stoi(lineTokens[3]);
|
|
}
|
|
if (lineTokens[0].compare("usepack") == 0) {
|
|
usePack = (lineTokens[1].compare("Y") == 0);
|
|
}
|
|
if (lineTokens[0].compare("editrecordtype") == 0) {
|
|
editRecordingType = stoi(lineTokens[1]);
|
|
}
|
|
if (lineTokens[0].compare("edgetile") == 0) {
|
|
cutEdgeTiles = (lineTokens[1].compare("Y") != 0);
|
|
}
|
|
if (lineTokens[0].compare("chrRamMatch") == 0) {
|
|
chrRamMatch = (lineTokens[1].compare("Y") == 0);
|
|
}
|
|
if (lineTokens[0].compare("caprate") == 0) {
|
|
capRate = stoi(lineTokens[1]);
|
|
}
|
|
|
|
}
|
|
|
|
void video::saveConfig(fstream* inifile){
|
|
(*inifile) << "video:screensize," + to_string((long double)screenSizeOption) + "," + to_string((long double)screenSizeWidth) + "," + to_string((long double)screenSizeHeight) + "\n";
|
|
(*inifile) << "video:usepack," + string(usePack ? "Y":"N") + "\n";
|
|
(*inifile) << "video:editrecordtype," + to_string((long double)editRecordingType) + "\n";
|
|
(*inifile) << "video:edgetile," + string(!cutEdgeTiles ? "Y":"N") + "\n";
|
|
(*inifile) << "video:chrRamMatch," + string(chrRamMatch ? "Y":"N") + "\n";
|
|
(*inifile) << "video:caprate," + to_string((long double)capRate) + "\n";
|
|
}
|
|
|
|
void video::SavePackEditScreen(){
|
|
//check for directory
|
|
string path = getEditPackPath();
|
|
|
|
_mkdir(path.c_str());
|
|
DWORD ftyp = GetFileAttributesA(path.c_str());
|
|
if (ftyp & FILE_ATTRIBUTE_DIRECTORY){
|
|
char buffer[80];
|
|
char frameCntBuffer[15];
|
|
time_t timer;
|
|
struct tm * timeinfo;
|
|
string filename;
|
|
|
|
//save screen shot first
|
|
time(&timer);
|
|
timeinfo = localtime (&timer);
|
|
strftime (buffer,80,"%Y%m%d%H%M%S",timeinfo);
|
|
sprintf (frameCntBuffer, "X%013d", ppuCore->frameCount);
|
|
filename = path + buffer + frameCntBuffer + ".png";
|
|
saveScreenToPath(filename, TRUE);
|
|
|
|
//save screen file log
|
|
fstream logfile;
|
|
|
|
filename = path + buffer + frameCntBuffer + ".dat";
|
|
logfile.open(filename, ios::out | ios::trunc);
|
|
if (logfile.is_open()){
|
|
for(unsigned int i = 0; i < screenTiles.size(); i++){
|
|
screenTile st = screenTiles[i];
|
|
logfile << (st.isBg ? "Y" : "N") + string(", ") + to_string((long double)st.patternAddress) + ", " + to_string((long double)st.colors.color1) + ", " + to_string((long double)st.colors.color2) + ", " + to_string((long double)st.colors.color3) + ", " + to_string((long double)st.x) + ", " + to_string((long double)st.y);
|
|
if(romDat->chrPageCount == 0){
|
|
for(int i = 0; i < 16; i++){
|
|
logfile << ", " + to_string((long double)(*((Uint8*)(&(st.rawDat)) + i)));
|
|
}
|
|
}
|
|
logfile << "\n";
|
|
|
|
//chalk it off
|
|
bitmapF b;
|
|
b.bitmapID = screenFileNameList.size();
|
|
b.colors = st.colors;
|
|
b.rawDat = st.rawDat;
|
|
b.isBg = st.isBg;
|
|
b.x = st.x;
|
|
b.y = st.y;
|
|
etiledata[editData[st.patternAddress]].bitmapP.push_back(b);
|
|
|
|
}
|
|
logfile.close();
|
|
}
|
|
|
|
filename = path + buffer + frameCntBuffer + "_a.dat";
|
|
logfile.open(filename, ios::out | ios::trunc);
|
|
if (logfile.is_open()){
|
|
for(unsigned int i = 0; i < allScreenTiles.size(); i++){
|
|
screenTile st = allScreenTiles[i];
|
|
logfile << (st.isBg ? "Y" : "N") + string(", ") + to_string((long double)st.patternAddress) + ", " + to_string((long double)st.colors.color1) + ", " + to_string((long double)st.colors.color2) + ", " + to_string((long double)st.colors.color3) + ", " + to_string((long double)st.x) + ", " + to_string((long double)st.y);
|
|
if(romDat->chrPageCount == 0){
|
|
for(int i = 0; i < 16; i++){
|
|
logfile << ", " + to_string((long double)(*((Uint8*)(&(st.rawDat)) + i)));
|
|
}
|
|
}
|
|
logfile << "\n";
|
|
|
|
//chalk it off
|
|
bitmapF b;
|
|
b.bitmapID = screenFileNameList.size();
|
|
b.colors = st.colors;
|
|
b.rawDat = st.rawDat;
|
|
b.isBg = st.isBg;
|
|
b.x = st.x;
|
|
b.y = st.y;
|
|
allEtiledata[allEditData[st.patternAddress]].bitmapP.push_back(b);
|
|
|
|
}
|
|
logfile.close();
|
|
}
|
|
|
|
filename = path + buffer + frameCntBuffer + "_ppu.dat";
|
|
logfile.open(filename, ios::out | ios::binary | ios::trunc);
|
|
if (logfile.is_open()){
|
|
memDat->savePPUData(&logfile);
|
|
logfile.close();
|
|
}
|
|
|
|
//save screen list
|
|
filename = string(buffer) + frameCntBuffer;
|
|
screenNameList.push_back("/");
|
|
screenFileNameList.push_back(filename);
|
|
|
|
SavePackEditScreenList();
|
|
|
|
|
|
//save graphic strips
|
|
//SaveGraphics(path + buffer + to_string((long double)ppuCore->frameCount));
|
|
|
|
//save buffers
|
|
//SaveBuffers(path + buffer + to_string((long double)ppuCore->frameCount));
|
|
}
|
|
|
|
}
|
|
|
|
void video::SavePackEditScreenList(){
|
|
string path = getEditPackPath();
|
|
string filename;
|
|
fstream logfile;
|
|
|
|
filename = path + "screen.dat";
|
|
logfile.open(filename, ios::out | ios::trunc);
|
|
if (logfile.is_open()){
|
|
for(unsigned int i = 0; i < screenFileNameList.size(); i++){
|
|
logfile << screenFileNameList[i] + ";" + screenNameList[i] + "\n";
|
|
}
|
|
logfile.close();
|
|
}
|
|
}
|
|
|
|
void video::SaveGraphics(string path){
|
|
SDL_Surface * sc = SDL_CreateRGBSurface(SDL_SWSURFACE, 512, 512, 24, 0x0000FF, 0x00FF00, 0xFF0000, 0);
|
|
if(sc){
|
|
int i = 0;
|
|
SDL_LockSurface(sc);
|
|
for(int y = 0; y < 512; ++y){
|
|
for(int x = 0; x < 512; ++x){
|
|
Uint8 *p = (Uint8 *)sc->pixels + y * sc->pitch + x * 3;
|
|
for(int c = 0; c < 3; ++c){
|
|
p[c] = (baseTextureCache[i] >> ((3 - c) * 8)) & 0x0000FF;
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
SDL_UnlockSurface(sc);
|
|
SDL_SaveBMP(sc, (path + "base.bmp").c_str());
|
|
SDL_FreeSurface(sc);
|
|
}
|
|
wxImage objimg = wxImage(wxString((path + "base.bmp").c_str(), wxConvUTF8));
|
|
objimg.SaveFile(wxString((path + "base.png").c_str(), wxConvUTF8));
|
|
remove((path + "base.bmp").c_str());
|
|
|
|
//sc = SDL_CreateRGBSurface(SDL_SWSURFACE, 2048, 128, 24, 0x0000FF, 0x00FF00, 0xFF0000, 0);
|
|
//if(sc){
|
|
// int i = 0;
|
|
// SDL_LockSurface(sc);
|
|
// for(int y = 128 - 1; y >= 0; --y){
|
|
// for(int x = 0; x < 2048; ++x){
|
|
// Uint8 *p = (Uint8 *)sc->pixels + y * sc->pitch + x * 3;
|
|
// for(int c = 0; c < 3; ++c){
|
|
// p[c] = (spGraphics[i] >> ((3 - c) * 8)) & 0x0000FF;
|
|
// }
|
|
// i++;
|
|
// }
|
|
// }
|
|
// SDL_UnlockSurface(sc);
|
|
// SDL_SaveBMP(sc, (path + "SP.bmp").c_str());
|
|
// SDL_FreeSurface(sc);
|
|
//}
|
|
//wxImage objimg2 = wxImage(wxString((path + "SP.bmp").c_str(), wxConvUTF8));
|
|
//objimg2.SaveFile(wxString((path + "SP.png").c_str(), wxConvUTF8));
|
|
//remove((path + "SP.bmp").c_str());
|
|
}
|
|
|
|
void video::SaveBuffers(string path){
|
|
//save screen file log
|
|
fstream logfile;
|
|
|
|
logfile.open(path + "Buffer.dat", ios::out | ios::trunc);
|
|
if (logfile.is_open()){
|
|
for(unsigned int i = 0; i < spPatCount; i++){
|
|
|
|
logfile << to_string((long double)spVBuffer[i * 12])
|
|
+ ", " + to_string((long double)spVBuffer[i * 12 + 1])
|
|
+ ", " + to_string((long double)spVBuffer[i * 12 + 2])
|
|
+ "; " + to_string((long double)spVBuffer[i * 12 + 3])
|
|
+ ", " + to_string((long double)spVBuffer[i * 12 + 4])
|
|
+ ", " + to_string((long double)spVBuffer[i * 12 + 5])
|
|
+ "; " + to_string((long double)spVBuffer[i * 12 + 6])
|
|
+ ", " + to_string((long double)spVBuffer[i * 12 + 7])
|
|
+ ", " + to_string((long double)spVBuffer[i * 12 + 8])
|
|
+ "; " + to_string((long double)spVBuffer[i * 12 + 9])
|
|
+ ", " + to_string((long double)spVBuffer[i * 12 + 10])
|
|
+ ", " + to_string((long double)spVBuffer[i * 12 + 11])
|
|
+ "; " + to_string((long double)spCBuffer[i * 8])
|
|
+ ", " + to_string((long double)spCBuffer[i * 8 + 1])
|
|
+ ", " + to_string((long double)spCBuffer[i * 8 + 2])
|
|
+ ", " + to_string((long double)spCBuffer[i * 8 + 3])
|
|
+ ", " + to_string((long double)spCBuffer[i * 8 + 4])
|
|
+ ", " + to_string((long double)spCBuffer[i * 8 + 5])
|
|
+ ", " + to_string((long double)spCBuffer[i * 8 + 6])
|
|
+ ", " + to_string((long double)spCBuffer[i * 8 + 7]) + "\n";
|
|
}
|
|
logfile.close();
|
|
}
|
|
}
|
|
|
|
void video::saveBG(string path){
|
|
//save screen file log
|
|
fstream logfile;
|
|
char tps[64];
|
|
|
|
logfile.open(path + "Bg.dat", ios::out | ios::trunc);
|
|
if (logfile.is_open()){
|
|
for(int j = 0; j < DISPLAY_HEIGHT / 8; j++){
|
|
logfile << "Line " + to_string((long double)j)
|
|
+ ", x=" + to_string((long double)BgRender[j][33])
|
|
+ ", y=" + to_string((long double)BgRender[j][34]) + "\n ";
|
|
for(int i = 0; i < 33; i++){
|
|
sprintf(tps, "%02X;", BgRender[j][i]);
|
|
logfile << tps;
|
|
}
|
|
logfile << "\n";
|
|
}
|
|
logfile.close();
|
|
}
|
|
}
|
|
|
|
void video::OptimizePackEdit(){
|
|
bool tHasWork = true;
|
|
bool tileFound;
|
|
int tScreenIndex = 0;
|
|
int tTileIndex;
|
|
bool patternMatch;
|
|
bitmapF tTile;
|
|
bitmapF tTile2;
|
|
|
|
while(tHasWork){
|
|
tHasWork = false;
|
|
//for each screen shot
|
|
tileFound = true;
|
|
for (unsigned int j = 0; j < etiledata.size(); j++) {
|
|
for (unsigned int k = 0; k < etiledata[j].bitmapP.size(); k++) {
|
|
tTile = etiledata[j].bitmapP[k];
|
|
if (tTile.bitmapID == tScreenIndex){
|
|
//go through each unique tiles and look for them in other screen shots
|
|
tileFound = false;
|
|
|
|
if (allEditData[etiledata[j].patternAddress] != BAD_ADDRESS){
|
|
if(etiledata[j].patternAddress == 13890){
|
|
tileFound = false;
|
|
}
|
|
int aj = allEditData[etiledata[j].patternAddress];
|
|
for (unsigned int ak = 0; ak < allEtiledata[aj].bitmapP.size(); ak++) {
|
|
tTile2 = allEtiledata[aj].bitmapP[ak];
|
|
if (tTile2.bitmapID != tScreenIndex) {
|
|
if (tTile2.colors.colorValues == tTile.colors.colorValues){
|
|
if(romDat->chrPageCount > 0){
|
|
patternMatch = true;
|
|
}
|
|
else{
|
|
patternMatch = (tTile2.rawDat.pixStrip1 == tTile.rawDat.pixStrip1
|
|
&& tTile2.rawDat.pixStrip2 == tTile.rawDat.pixStrip2
|
|
&& tTile2.rawDat.pixStrip3 == tTile.rawDat.pixStrip3
|
|
&& tTile2.rawDat.pixStrip4 == tTile.rawDat.pixStrip4);
|
|
}
|
|
if(patternMatch){
|
|
tileFound = true;
|
|
}
|
|
}
|
|
if (tileFound) break;
|
|
}
|
|
}
|
|
}
|
|
//has one unique tile which can't be found in other screenshots, so we must keep this shot
|
|
if (!tileFound) break;
|
|
}
|
|
}
|
|
//has one unique tile which can't be found in other screenshots, so we must keep this shot
|
|
if (!tileFound) break;
|
|
}
|
|
if (tileFound){
|
|
//all tiles are found in other shots, we can remove this shot
|
|
//first transfer all unique to other shots
|
|
for (unsigned int j = 0; j < etiledata.size(); j++) {
|
|
for (unsigned int k = 0; k < etiledata[j].bitmapP.size(); k++) {
|
|
tTile = etiledata[j].bitmapP[k];
|
|
if (tTile.bitmapID == tScreenIndex){
|
|
//go through each unique tiles and look for them in other screen shots
|
|
tileFound = false;
|
|
if (allEditData[etiledata[j].patternAddress] != BAD_ADDRESS){
|
|
if(etiledata[j].patternAddress == 13890){
|
|
tileFound = false;
|
|
}
|
|
int aj = allEditData[etiledata[j].patternAddress];
|
|
for (unsigned int ak = 0; ak < allEtiledata[aj].bitmapP.size(); ak++) {
|
|
tTile2 = allEtiledata[aj].bitmapP[ak];
|
|
if (tTile2.bitmapID != tScreenIndex) {
|
|
if (tTile2.colors.colorValues == tTile.colors.colorValues){
|
|
if(romDat->chrPageCount > 0){
|
|
patternMatch = true;
|
|
}
|
|
else{
|
|
patternMatch = (tTile2.rawDat.pixStrip1 == tTile.rawDat.pixStrip1
|
|
&& tTile2.rawDat.pixStrip2 == tTile.rawDat.pixStrip2
|
|
&& tTile2.rawDat.pixStrip3 == tTile.rawDat.pixStrip3
|
|
&& tTile2.rawDat.pixStrip4 == tTile.rawDat.pixStrip4);
|
|
}
|
|
if(patternMatch){
|
|
tileFound = true;
|
|
//copy it to unique tiles
|
|
etiledata[j].bitmapP.push_back(tTile2);
|
|
}
|
|
}
|
|
if (tileFound) break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//then remove all tiles from this shot
|
|
for (unsigned int j = 0; j < etiledata.size(); j++) {
|
|
tTileIndex = 0;
|
|
while (tTileIndex < etiledata[j].bitmapP.size()) {
|
|
if (etiledata[j].bitmapP[tTileIndex].bitmapID == tScreenIndex){
|
|
etiledata[j].bitmapP.erase(etiledata[j].bitmapP.begin() + tTileIndex);
|
|
}
|
|
else{
|
|
tTileIndex++;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (unsigned int j = 0; j < allEtiledata.size(); ++j) {
|
|
tTileIndex = 0;
|
|
while (tTileIndex < allEtiledata[j].bitmapP.size()) {
|
|
if (allEtiledata[j].bitmapP[tTileIndex].bitmapID == tScreenIndex){
|
|
allEtiledata[j].bitmapP.erase(allEtiledata[j].bitmapP.begin() + tTileIndex);
|
|
}
|
|
else{
|
|
++tTileIndex;
|
|
}
|
|
}
|
|
}
|
|
|
|
//remove the shot
|
|
screenFileNameList.erase(screenFileNameList.begin() + tScreenIndex);
|
|
|
|
//adjust bmp id for all other tiles
|
|
for (unsigned int j = 0; j < etiledata.size(); j++) {
|
|
for (unsigned int k = 0; k < etiledata[j].bitmapP.size(); k++) {
|
|
if (etiledata[j].bitmapP[k].bitmapID > tScreenIndex){
|
|
etiledata[j].bitmapP[k].bitmapID--;
|
|
}
|
|
}
|
|
}
|
|
for (unsigned int j = 0; j < allEtiledata.size(); j++) {
|
|
for (unsigned int k = 0; k < allEtiledata[j].bitmapP.size(); k++) {
|
|
if (allEtiledata[j].bitmapP[k].bitmapID > tScreenIndex){
|
|
allEtiledata[j].bitmapP[k].bitmapID--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
tScreenIndex++;
|
|
}
|
|
tHasWork = (tScreenIndex < screenFileNameList.size());
|
|
}
|
|
}
|
|
|
|
|
|
void video::RewritePackEdit(){
|
|
//first rewrite the screen list
|
|
SavePackEditScreenList();
|
|
|
|
string path = getEditPackPath();
|
|
|
|
_mkdir(path.c_str());
|
|
DWORD ftyp = GetFileAttributesA(path.c_str());
|
|
if (ftyp & FILE_ATTRIBUTE_DIRECTORY){
|
|
string filename;
|
|
//save screen file log
|
|
fstream logfile;
|
|
//over write each screen
|
|
for(int i = 0; i < screenFileNameList.size(); i++){
|
|
filename = path + screenFileNameList[i] + ".dat";
|
|
logfile.open(filename, ios::out | ios::trunc);
|
|
if (logfile.is_open()){
|
|
for (unsigned int j = 0; j < etiledata.size(); j++) {
|
|
for (unsigned int k = 0; k < etiledata[j].bitmapP.size(); k++) {
|
|
if (etiledata[j].bitmapP[k].bitmapID == i){
|
|
|
|
logfile << (etiledata[j].bitmapP[k].isBg ? "Y" : "N") + string(", ")
|
|
+ to_string((long double)etiledata[j].patternAddress)
|
|
+ ", " + to_string((long double)etiledata[j].bitmapP[k].colors.color1)
|
|
+ ", " + to_string((long double)etiledata[j].bitmapP[k].colors.color2)
|
|
+ ", " + to_string((long double)etiledata[j].bitmapP[k].colors.color3)
|
|
+ ", " + to_string((long double)etiledata[j].bitmapP[k].x)
|
|
+ ", " + to_string((long double)etiledata[j].bitmapP[k].y);
|
|
if(romDat->chrPageCount == 0){
|
|
for(int i = 0; i < 16; i++){
|
|
logfile << ", " + to_string((long double)(*((Uint8*)(&(etiledata[j].bitmapP[k].rawDat)) + i)));
|
|
}
|
|
}
|
|
logfile << "\n";
|
|
}
|
|
}
|
|
}
|
|
logfile.close();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void video::ReadPalette(string path){
|
|
fstream palettefile;
|
|
char rawPalette[192];
|
|
palettefile.open(path, ios::in | ios::binary);
|
|
if (palettefile.is_open()){
|
|
palettefile.read(rawPalette, 192);
|
|
palettefile.close();
|
|
for(int i = 0; i < 64; i++){
|
|
colourList[i] = ((rawPalette[i * 3] << 24) & 0xFF000000) | ((rawPalette[i * 3 + 1] << 16) & 0x00FF0000) | ((rawPalette[i * 3 + 2] << 8) & 0x0000FF00) | 0xFF;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
Note:
|
|
packSize = CHR ROM or PRG ROM size
|
|
HD images: info in bmpInfos and pixel data in rawBits
|
|
|
|
packData[ROM address] stores the index of this address in array tdata
|
|
tdata is an array of TileData
|
|
TileData has an array of bitmapF and the default
|
|
bitmapF has an index of HD image, x and y coordinate in that image, the brightness and the palette
|
|
|
|
|
|
*/
|
|
|
|
|
|
/*
|
|
meta sprite check
|
|
If a sprite tile is unmatched then
|
|
check that it matches any sprite in any meta sprite
|
|
if has meta sprite then
|
|
check for the origin sprite
|
|
if origin sprite matches then
|
|
use origin sprite to match all others
|
|
if all matches then
|
|
udpate match result to sprites
|
|
endif
|
|
end if
|
|
end if
|
|
end if
|
|
*/ |