/*
Copyright (C) 1997-2008 ZSNES Team ( zsKnight, _Demo_, pagefault, Nach )

http://www.zsnes.com
http://sourceforge.net/projects/zsnes
https://zsnes.bountysource.com

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "../types.h" /* IGNORE_RESULT */

#ifdef __UNIXSDL__
#include "../gblhdr.h"
#else
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#ifdef __WIN32__
#include <io.h>
#else
#include <unistd.h>
#endif
#endif
#include "../zmovie.h"
#include "../zpath.h"
#include "procvidc.h"

extern uint8_t newengen;
extern uint32_t nggposng[];
extern uint16_t PrevPicture[64 * 56];
extern uint8_t *vidbuffer, *vidbufferofsb;

void CapturePicture()
{
    const uint16_t* vbuf = (uint16_t*)vidbuffer;
    unsigned short work1, work2, filter;
    unsigned int i, j, offset, pppos = 0;

    if (newengen && ((*nggposng & 0xFF) == 5)) {
        filter = 0x7BDE; // 0111 1011 1101 1110
    } else {
        filter = 0xF7DE; // 1111 0111 1101 1110
    }

    for (j = 0; j < 56; j++) {
        offset = 288 + 16 + j * 288 * 4;

        for (i = 0; i < 64; i++) {
            work1 = ((vbuf[offset] & filter) >> 1) + ((vbuf[offset + 2] & filter) >> 1);
            work2 = ((vbuf[offset + 288] & filter) >> 1) + ((vbuf[offset + 288 + 2] & filter) >> 1);
            PrevPicture[pppos] = ((work1 & filter) >> 1) + ((work2 & filter) >> 1);
            offset += 4;
            pppos++;
        }
    }

    if (newengen && ((*nggposng & 0xFF) == 5)) {
        for (pppos = 0; pppos < 64 * 56; pppos++) {
            PrevPicture[pppos] = ((PrevPicture[pppos] & 0x7FE0) << 1) | (PrevPicture[pppos] & 0x001F);
        } // 0111 1111 1110 0000 and 0000 0000 0001 1111
    }
}

/* size_t in zstate.c, so it has to be size_t here too. */
extern size_t cur_zst_size, v143_zst_size, old_zst_size;

char* zst_name();

void LoadPicture(void)
{
    const unsigned int pic_size = 64 * 56 * 2;
    FILE* fp;
    char* zst_path;

    memset(PrevPicture, 0, pic_size);

    if (MovieInProgress()) {
        mzt_chdir_up();
        zst_path = ZMoviePath;
    }

    else {
        zst_path = ZSStatePath;
    }

    if ((fp = fopen_dir(zst_path, zst_name(), "rb"))) {
        unsigned int file_size;

        fseek(fp, 0, SEEK_END);
        file_size = ftell(fp);

        if ((file_size - pic_size == cur_zst_size) || (file_size - pic_size == v143_zst_size)
            || (file_size - pic_size == old_zst_size)) {
            fseek(fp, -((signed)pic_size), SEEK_END);
            IGNORE_RESULT(fread(PrevPicture, 1, pic_size, fp));
        }

        fclose(fp);
    }
    if (MovieInProgress()) {
        mzt_chdir_down();
    }
}

void Clear2xSaIBuffer(void)
{
    memset(vidbufferofsb, 0xFF, 576 * 256);
}
