Switch graphic & key management to OpenGL/GLFW3, correct sprite behaviour, still not perfect, but way better (no more issue with overlapping and overflow is correctly handled now)

->PPU still need a complete rewrite.
 Bump version to 0.7!
This commit is contained in:
Godzil 2016-12-29 18:21:39 +01:00
parent 866dcfa969
commit cc9fe51828
49 changed files with 1171 additions and 946 deletions

View File

@ -9,8 +9,16 @@
# $HeadURL$ # $HeadURL$
# $Revision$ # $Revision$
cmake_minimum_required (VERSION 3.6)
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
add_subdirectory("external/glfw")
find_package(OpenGL REQUIRED)
include_directories(${OPENGL_INCLUDE_DIR})
cmake_minimum_required (VERSION 2.6)
project (TINES) project (TINES)
add_subdirectory (src) add_subdirectory (src)

View File

@ -2,15 +2,13 @@
# TI-NES CMake # TI-NES CMake
# #
# Created by Manoel TRAPIER. # Created by Manoel TRAPIER.
# Copyright (c) 2003-2008 986Corp. All rights reserved. # Copyright (c) 2003-2016 986-Studio. All rights reserved.
# #
# $LastChangedDate$ # $LastChangedDate$
# $Author$ # $Author$
# $HeadURL$ # $HeadURL$
# $Revision$ # $Revision$
include_directories($(TINES_SOURCE_DIR)/include)
########################## ##########################
# Configurations variables # Configurations variables
########################## ##########################
@ -22,17 +20,7 @@ set(DETECT_BUS_CONFLICT OFF CACHE BOOL "Activate the bus conflit detector? (Coul
set(USE_EFENCE OFF CACHE BOOL "Use electricfence memory debugger?") set(USE_EFENCE OFF CACHE BOOL "Use electricfence memory debugger?")
set(USE_PROFILING OFF CACHE BOOL "Use profiling tools? (Will slow down a lot.)") set(USE_PROFILING OFF CACHE BOOL "Use profiling tools? (Will slow down a lot.)")
set(USE_ALLEGRO ON CACHE BOOL "Use Allegro backend" FORCE) set(USE_ALLEGRO ON CACHE BOOL "Use Allegro backend")
IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE Debug CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE)
if (APPLE)
SET (CMAKE_FIND_FRAMEWORK LAST)
endif (APPLE)
########################## ##########################
# Link & Compile flags # Link & Compile flags
@ -41,9 +29,7 @@ endif (APPLE)
set (CMAKE_C_FLAGS "-Wall -Wextra -Wno-unused-parameter -Werror ${PLATFORM_FLAGS}") set (CMAKE_C_FLAGS "-Wall -Wextra -Wno-unused-parameter -Werror ${PLATFORM_FLAGS}")
set (CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused-parameter -Werror ${PLATFORM_FLAGS}") set (CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused-parameter -Werror ${PLATFORM_FLAGS}")
add_definitions (-DNO_DECIMAL -DFAST_RDOP) add_definitions (-DNO_DECIMAL)
SET ( CMAKE_EXE_LINKER_FLAGS "-mmacosx-version-min=10.4")
if (PPU_ISPAL) if (PPU_ISPAL)
add_definitions (-DISPAL) add_definitions (-DISPAL)
@ -63,15 +49,6 @@ if (DETECT_BUS_CONFLICT)
add_definitions (-DDETECT_BUS_CONFLICT) add_definitions (-DDETECT_BUS_CONFLICT)
endif (DETECT_BUS_CONFLICT) endif (DETECT_BUS_CONFLICT)
if (USE_EFENCE)
if (CMAKE_BUILD_TYPE MATCHES Release)
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Debug info is forced" FORCE)
else(CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE Debug CACHE STRING "Debug info is forced" FORCE)
endif(CMAKE_BUILD_TYPE)
endif (USE_EFENCE)
if (USE_PROFILING) if (USE_PROFILING)
if (CMAKE_BUILD_TYPE MATCHES Rel) if (CMAKE_BUILD_TYPE MATCHES Rel)
SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Debug info is forced" FORCE) SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Debug info is forced" FORCE)
@ -82,18 +59,7 @@ if (USE_PROFILING)
set(CMAKE_C_FLAGS -pg) set(CMAKE_C_FLAGS -pg)
endif (USE_PROFILING) endif (USE_PROFILING)
if (APPLE) include_directories(include)
include_directories(BEFORE /usr/include)
endif (APPLE)
#if the CPU is LSB set the define
if (CMAKE_SYSTEM_PROCESSOR MATCHES i386 OR CMAKE_SYSTEM_PROCESSOR MATCHES [aA][rR][mM])
add_definitions (-DLSB_FIRST)
endif (CMAKE_SYSTEM_PROCESSOR MATCHES i386 OR CMAKE_SYSTEM_PROCESSOR MATCHES [aA][rR][mM])
#Add release mode extra C Flags
set (CMAKE_C_FLAGS_RELEASE "-fomit-frame-pointer -funroll-loops -Wall ${CMAKE_C_FLAGS_RELEASE}")
set (CMAKE_C_FLAGS_RELWITHDEBINFO "-fomit-frame-pointer -funroll-loops -Wall ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
add_subdirectory(apu) add_subdirectory(apu)
add_subdirectory(corecpu) add_subdirectory(corecpu)
@ -105,36 +71,13 @@ add_subdirectory(ppu)
if (TARGET_TI68k) if (TARGET_TI68k)
add_subdirectory(os/ti68k) add_subdirectory(os/ti68k)
elseif (APPLE AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") elseif (WIN32)
add_subdirectory(os/macos)
elseif (UNIX)
add_subdirectory(os/unix)
else (TARGET_TI68k)
#So we target UNIX like OS
add_subdirectory(os/win32) add_subdirectory(os/win32)
else (TARGET_TI68k)
add_subdirectory(os/unix)
endif (TARGET_TI68k) endif (TARGET_TI68k)
add_library (main main.c paddle.c NESCarts.c)
add_executable(tines main.c)
set(CMAKE_FIND_FRAMEWORK LAST)
find_library(ALLEGROLIB allegro)
find_library(PTHREADLIB pthread) find_library(PTHREADLIB pthread)
if (USE_EFENCE) add_executable(tines main.c paddle.c NESCarts.c)
find_library(EFENCELIB efence) target_link_libraries(tines apu corecpu mappermanager memorymanager pluginsmanager ppu oslib ${PTHREADLIB})
target_link_libraries(tines ${EFENCELIB})
endif (USE_EFENCE)
if (USE_ALLEGRO)
target_link_libraries(tines debug alld-main)
# target_link_libraries(tines)
if (APPLE)
find_library(COCOALIB Cocoa)
target_link_libraries(tines ${COCOALIB})
endif (APPLE)
endif (USE_ALLEGRO)
target_link_libraries(tines main apu corecpu mappermanager memorymanager pluginsmanager ppu oslib ${ALLEGROLIB} ${PTHREADLIB})

View File

@ -3,7 +3,7 @@
* NESCart.c * NESCart.c
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -2,7 +2,7 @@
# TI-NES CMake # TI-NES CMake
# #
# Created by Manoel TRAPIER. # Created by Manoel TRAPIER.
# Copyright (c) 2003-2008 986Corp. All rights reserved. # Copyright (c) 2003-2016 986-Studio. All rights reserved.
# #
# $LastChangedDate$ # $LastChangedDate$
# $Author$ # $Author$

View File

@ -10,7 +10,7 @@
/** commercially. Please, notify me, if you make any **/ /** commercially. Please, notify me, if you make any **/
/** changes to this file. **/ /** changes to this file. **/
/*************************************************************/ /*************************************************************/
#include "Sound.h" //#include "Sound.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
@ -20,7 +20,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <os_dependent.h> #include <os_dependent.h>
#if 0
#ifdef SUN_AUDIO #ifdef SUN_AUDIO
#include <sys/audioio.h> #include <sys/audioio.h>
@ -553,3 +553,4 @@ void UnixDrum(int Type,int Force)
{ {
/* This function is currently empty */ /* This function is currently empty */
} }
#endif

View File

@ -3,7 +3,7 @@
* NESCart.h * NESCart.h
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -1,9 +1,9 @@
/** /**
* ANSI Color definitiont - The Quick6502 Project * ANSI Color definition - The Quick6502 Project
* include/color.h * include/color.h
* *
* Created by Manoel Trapier on 25/06/10 * Created by Manoel Trapier on 25/06/10
* Copyright 2010 986 Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate:$ * $LastChangedDate:$
* $Author:$ * $Author:$

View File

@ -3,7 +3,7 @@
* corecpu.h * corecpu.h
* *
* Created by Manoel Trapier on 24/02/08 * Created by Manoel Trapier on 24/02/08
* Copyright 2008 986 Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -3,7 +3,7 @@
* include/log.h * include/log.h
* *
* Created by Manoel Trapier on 19/05/10 * Created by Manoel Trapier on 19/05/10
* Copyright 2010 986 Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate:$ * $LastChangedDate:$
* $Author:$ * $Author:$

View File

@ -3,7 +3,7 @@
* os_dependent.h * os_dependent.h
* *
* Created by Manoel TRAPIER on 08/05/08. * Created by Manoel TRAPIER on 08/05/08.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$
@ -15,11 +15,21 @@
#ifndef OS_DEPENDENT_H #ifndef OS_DEPENDENT_H
#define OS_DEPENDENT_H #define OS_DEPENDENT_H
#include <stdint.h>
/* File related functions */ /* File related functions */
/* Graphics related functions */ /* Graphics related functions */
int graphics_init(); int graphics_init();
int graphics_drawpixel(long x, long y, long color); int graphics_drawpixel(long x, long y, long color);
int graphics_blit(long x, long y, long w, long h); int graphics_blit(long x, long y, long w, long h);
int graphics_drawline(long x, long y, long x1, long y1, long color);
typedef struct Palette_t
{
uint8_t r,g,b,a;
} Palette;
int getKeyStatus(int key);
/* Sound related functions */ /* Sound related functions */
@ -37,7 +47,6 @@ typedef enum ConsoleLevel_t
Console_Debug, Console_Debug,
} ConsoleLevel; } ConsoleLevel;
int console_init(ConsoleLevel DefaultLevel); int console_init(ConsoleLevel DefaultLevel);
int console_printf(const ConsoleLevel level, const char *format, ...); int console_printf(const ConsoleLevel level, const char *format, ...);
int console_printf_d(const char *format, ...); int console_printf_d(const char *format, ...);

View File

@ -3,7 +3,7 @@
* paddle.h * paddle.h
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -6,7 +6,7 @@
* $Revision$ * $Revision$
*/ */
PALETTE basicPalette = { Palette basicPalette[] = {
{ 0x1E, 0x1E, 0x1E, 0x07 }, { 0x1E, 0x1E, 0x1E, 0x07 },
{ 0x03, 0x09, 0x28, 0xB7 }, { 0x03, 0x09, 0x28, 0xB7 },
{ 0x0A, 0x04, 0x2B, 0x0D }, { 0x0A, 0x04, 0x2B, 0x0D },

View File

@ -5,7 +5,7 @@
* Define and emulate the PPU (Picture Processing Unit) of the real NES * Define and emulate the PPU (Picture Processing Unit) of the real NES
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$
@ -21,10 +21,10 @@
typedef struct PPU_Sprite_ typedef struct PPU_Sprite_
{ {
byte y; uint8_t y;
byte tileid; uint8_t tileid;
byte flags; uint8_t flags;
byte x; uint8_t x;
} PPU_Sprite; } PPU_Sprite;
/* /*
@ -32,13 +32,13 @@ PPU must be initialized after memory initialisation..
*/ */
int ppu_init(); int ppu_init();
int ppu_hblank(int scanline); int ppu_hblank(uint16_t scanline);
byte ppu_readReg(byte id); uint8_t ppu_readReg(uint8_t id);
void ppu_writeReg(byte id, byte val); void ppu_writeReg(uint8_t id, uint8_t val);
void ppu_fillSprRamDMA(byte value); void ppu_fillSprRamDMA(uint8_t value);
#define PPU_MIRROR_HORIZTAL 0 #define PPU_MIRROR_HORIZTAL 0
#define PPU_MIRROR_VERTICAL 1 #define PPU_MIRROR_VERTICAL 1
@ -52,15 +52,15 @@ void ppu_fillSprRamDMA(byte value);
#define PPU_SCMODE_NORMAL 1 #define PPU_SCMODE_NORMAL 1
#define PPU_SCMODE_FOURSC 2 #define PPU_SCMODE_FOURSC 2
void ppu_setMirroring(byte direction); void ppu_setMirroring(uint8_t direction);
void ppu_setSingleScreen(byte screen); void ppu_setSingleScreen(uint8_t screen);
void ppu_setScreenMode(byte mode); void ppu_setScreenMode(uint8_t mode);
PPU_Sprite ppu_getSprite(unsigned short i); PPU_Sprite ppu_getSprite(uint16_t i);
unsigned char ppu_memoryRead(byte page, byte addr); unsigned char ppu_memoryRead(uint8_t page, uint8_t addr);
void ppu_memoryWrite(byte page, byte addr, byte value); void ppu_memoryWrite(uint8_t page, uint8_t addr, uint8_t value);
void ppu_debugSprites(); void ppu_debugSprites();
void ppu_debugColor(); void ppu_debugColor();

View File

@ -3,7 +3,7 @@
* types.h - Taken from the Quick6502 project * types.h - Taken from the Quick6502 project
* *
* Created by Manoel Trapier on 18/09/06. * Created by Manoel Trapier on 18/09/06.
* Copyright 2003-2008 986 Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$
@ -15,12 +15,14 @@
#ifndef TYPES_H #ifndef TYPES_H
#define TYPES_H #define TYPES_H
#include <stdint.h>
#ifndef BYTE_TYPE_DEFINED #ifndef BYTE_TYPE_DEFINED
#define BYTE_TYPE_DEFINED #define BYTE_TYPE_DEFINED
typedef unsigned char byte; typedef uint8_t byte;
#endif #endif
typedef unsigned char bool; typedef uint8_t bool;
#define true (0) #define true (0)
#define false (!true) #define false (!true)

View File

@ -3,7 +3,7 @@
* main.c * main.c
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2012 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$
@ -20,21 +20,15 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/time.h> #include <sys/time.h>
#include <time.h> #include <time.h>
#include <ctype.h> #include <ctype.h>
/* Allegro includes */ #include <GLFW/glfw3.h>
#ifdef __APPLE__
#define USE_CONSOLE
#include <Allegro/allegro.h>
#else
#define USE_CONSOLE
#include <allegro.h>
#endif
#else #else
@ -61,23 +55,11 @@
#include <Sound.h> #include <Sound.h>
#endif #endif
#include <palette.h>
/* PAL support is broken, so force NTSC mode */
#if ISPAL || ISNTSC
#undef ISPAL
#undef ISNTSC
#endif
#define ISNTSC 1
#if ISPAL && !ISNTSC #if ISPAL && !ISNTSC
int VBLANK_TIME = 70; int VBLANK_TIME = 70;
int HBLANK_TIME = 140; int HBLANK_TIME = 103;
double APU_BASEFREQ = 1.7734474; double APU_BASEFREQ = 1.7734474;
#elif !ISPAL && ISNTSC #elif !ISPAL && ISNTSC
int VBLANK_TIME = 20; int VBLANK_TIME = 20;
int HBLANK_TIME = 113; int HBLANK_TIME = 113;
double APU_BASEFREQ = 1.7897725; double APU_BASEFREQ = 1.7897725;
@ -91,13 +73,16 @@ double APU_BASEFREQ = 1.7897725;
/* TI-NESulator Version */ /* TI-NESulator Version */
#define V_MAJOR 0 #define V_MAJOR 0
#define V_MINOR 40 #define V_MINOR 70
#ifdef USE_SOUND
#undef USE_SOUND
#endif
/* SVN specific values */ /* SVN specific values */
#define VS_ID "$Id$"
#define VS_REVISION "$Revision$" #define VS_REVISION "$Revision$"
#define VS_LASTCHANGEDDATE "$LastChangedDate$" #define VS_LASTCHANGEDDATE "$LastChangedDate$"
#define VS_HEADURL "$HeadURL$"
#define VS_AUTHOR "$Author$" #define VS_AUTHOR "$Author$"
/* /*
@ -113,10 +98,6 @@ NesCart *Cart;
byte *FDSRom; byte *FDSRom;
byte *FDSRam; byte *FDSRam;
/* Allegro main screen */
BITMAP *Buffer;
/* Command line options */ /* Command line options */
byte START_DEBUG = 0; byte START_DEBUG = 0;
byte START_WITH_FDS = 0; byte START_WITH_FDS = 0;
@ -139,8 +120,6 @@ struct timeval timeEnd;
volatile unsigned long FPS, IPS; volatile unsigned long FPS, IPS;
PALETTE pal;
short IRQScanHit = -1; short IRQScanHit = -1;
short SZHit = -1; short SZHit = -1;
@ -166,15 +145,6 @@ void CloseHook(void)
WantClosing = 1; WantClosing = 1;
} }
void ips_fps_counter(void)
{
FPS = frame;
IPS = ccount;
frame = 0;
ccount = 0;
}
END_OF_FUNCTION(ips_fps_counter);
void SaveSaveRam(char *name) void SaveSaveRam(char *name)
{ {
FILE *fp; FILE *fp;
@ -216,7 +186,7 @@ void LoadSaveRam(char *name)
} }
void LoadPalette(char *filename, PALETTE pal) void LoadPalette(char *filename, Palette *pal)
{ {
FILE *fp; FILE *fp;
int ret; int ret;
@ -380,6 +350,7 @@ byte Page40[256];
void WrHook4000Multiplexer(byte addr, byte value) void WrHook4000Multiplexer(byte addr, byte value)
{ {
#ifdef USE_SOUND
static byte SQ1V = 0; static byte SQ1V = 0;
static byte SQ2V = 0; static byte SQ2V = 0;
static byte NOIV = 0; static byte NOIV = 0;
@ -400,6 +371,8 @@ void WrHook4000Multiplexer(byte addr, byte value)
static byte Sq2_reg3 = 0; static byte Sq2_reg3 = 0;
double SQ = 0.0; double SQ = 0.0;
#endif
switch(addr) switch(addr)
{ {
#ifdef USE_SOUND #ifdef USE_SOUND
@ -655,14 +628,9 @@ int main(int argc, char *argv[])
/* Print the banner */ /* Print the banner */
console_printf(Console_Default, "--------------------------------------------------------------------------------\n" console_printf(Console_Default, "--------------------------------------------------------------------------------\n"
"Welcome to TI-NESulator v%d.%d - by Godzil\n" "Welcome to TI-NESulator v%d.%d - by Godzil\n"
"Copyright 2003-2012 TRAPIER Manoel (godzil@godzil.net)\n" "Copyright 2003-2016 TRAPIER Manoel (godzil@godzil.net)\n"
"%s\n%s\n%s\n"
"--------------------------------------------------------------------------------\n\n", "--------------------------------------------------------------------------------\n\n",
V_MAJOR, V_MAJOR, V_MINOR);
V_MINOR,
VS_REVISION,
VS_LASTCHANGEDDATE,
VS_AUTHOR);
console_printf(Console_Default, "Install signal handlers...\t["); console_printf(Console_Default, "Install signal handlers...\t[");
signal(SIGABRT, signalhandler); signal(SIGABRT, signalhandler);
@ -929,22 +897,6 @@ int main(int argc, char *argv[])
InitPaddle(&P1); InitPaddle(&P1);
console_printf(Console_Default, "Initializing Allegro...\t\t");
allegro_init();
install_timer();
install_keyboard();
console_printf(Console_Default, "[ OK ]\n");
console_printf(Console_Default, "Set graphic mode...\t\t");
set_color_depth(8);
set_gfx_mode(GFX_AUTODETECT_WINDOWED, 512 + 256, 480, 512 + 256, 480);
Buffer = create_bitmap(512 + 256, 480);
clear_to_color(Buffer, 0x0D);
//set_close_button_callback(CloseHook);
//set_window_title("TI-NESulator");
console_printf(Console_Default, "[ OK ]\n");
console_printf(Console_Default, "Init PPU...\n"); console_printf(Console_Default, "Init PPU...\n");
if (ppu_init() != 0) if (ppu_init() != 0)
@ -970,15 +922,7 @@ int main(int argc, char *argv[])
return -1; return -1;
console_printf(Console_Default, "[ OK ]\n"); console_printf(Console_Default, "[ OK ]\n");
if (PALETTE_FILENAME == NULL) // set_palette(basicPalette);
{
set_palette(basicPalette);
}
else
{
LoadPalette(PALETTE_FILENAME, pal);
set_palette(pal);
}
#ifdef USE_SOUND #ifdef USE_SOUND
InitSound(44400,!0); InitSound(44400,!0);
@ -990,7 +934,7 @@ int main(int argc, char *argv[])
#endif #endif
// Actually no real debugguer... // Actually no real debugguer...
//console_printf(Console_Default, "Press ESC to pause emulation and jump to debugguer\n"); //console_printf(Console_Default, "Press ESC to pause emulation and jump to debugguer\n");
install_int(ips_fps_counter, 1000);
ScanLine = 0; ScanLine = 0;
/* Initialize the CPU */ /* Initialize the CPU */
@ -1027,7 +971,6 @@ int main(int argc, char *argv[])
} }
return 0; return 0;
} }
END_OF_MAIN()
/* Access directly to Memory pages *HACKISH* */ /* Access directly to Memory pages *HACKISH* */
extern byte *memory_pages[0xFF]; extern byte *memory_pages[0xFF];
@ -1079,7 +1022,7 @@ void MemoryPageZeroWrite (unsigned short Addr, byte Value)
void Loop6502(quick6502_cpu *R) void Loop6502(quick6502_cpu *R)
{ {
byte ret; byte ret;
short skey; // short skey;
long WaitTime; long WaitTime;
static long delta=0; static long delta=0;
@ -1122,7 +1065,7 @@ void Loop6502(quick6502_cpu *R)
#endif #endif
/* If we press Page Up, we want to accelerate "time" */ /* If we press Page Up, we want to accelerate "time" */
if ((!key[KEY_PGUP]) && (!key[KEY_Y])) if (!getKeyStatus('Y'))
if ((WaitTime >= 0) && (WaitTime < 100000)) if ((WaitTime >= 0) && (WaitTime < 100000))
usleep(WaitTime); usleep(WaitTime);
@ -1148,13 +1091,12 @@ void Loop6502(quick6502_cpu *R)
ScanLine++; ScanLine++;
//console_printf(Console_Default, "SL:%d HBT:%d VbT:%d\n", ScanLine, HBLANK_TIME, VBLANK_TIME); //console_printf(Console_Default, "SL:%d HBT:%d VbT:%d\n", ScanLine, HBLANK_TIME, VBLANK_TIME);
if (keypressed())
{
skey = (readkey() & 0xFF);
// TODO: NO DEBUGER
/* if (skey == 27)
R->Trace = 1;*/
// TODO: NO DEBUGER
if (getKeyStatus(GLFW_KEY_ESCAPE))
exit(0);
#if 0
if (skey == '9') if (skey == '9')
{ {
VBLANK_TIME += 2; VBLANK_TIME += 2;
@ -1178,17 +1120,16 @@ void Loop6502(quick6502_cpu *R)
HBLANK_TIME -= 1; HBLANK_TIME -= 1;
console_printf(Console_Default, "HBLT: %d\n", HBLANK_TIME); console_printf(Console_Default, "HBLT: %d\n", HBLANK_TIME);
} }
#endif
if ((skey == 'r') || (skey == 'R')) if (getKeyStatus('r') || getKeyStatus('R'))
{ {
/* Force the PPU to stop NMIs */ /* Force the PPU to stop NMIs */
MemoryWrite(0x2000, 0x00); MemoryWrite(0x2000, 0x00);
quick6502_reset(R); quick6502_reset(R);
} }
plugin_keypress(skey); // plugin_keypress(skey);
}
if (ret != 0) if (ret != 0)
quick6502_int(R, ret); quick6502_int(R, ret);

View File

@ -2,7 +2,7 @@
# TI-NES CMake # TI-NES CMake
# #
# Created by Manoel TRAPIER. # Created by Manoel TRAPIER.
# Copyright (c) 2003-2008 986Corp. All rights reserved. # Copyright (c) 2003-2016 986-Studio. All rights reserved.
# #
# $LastChangedDate$ # $LastChangedDate$
# $Author$ # $Author$

View File

@ -3,7 +3,7 @@
* manager.c * manager.c
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -3,7 +3,7 @@
* aorom.c * aorom.c
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$
@ -55,7 +55,7 @@ void aorom_MapperWriteHook(register byte Addr, register byte Value)
aorom_load_bank = BankNb; aorom_load_bank = BankNb;
console_printf(Console_Default, "aorom: Asking bank %d - NT is 0x%04X\n",BankNb,(Value&0x10)?0x2400:0x2000); //console_printf(Console_Default, "aorom: Asking bank %d - NT is 0x%04X\n",BankNb,(Value&0x10)?0x2400:0x2000);
set_prom_bank_32k(0x8000,BankNb); set_prom_bank_32k(0x8000,BankNb);
} }

View File

@ -3,7 +3,7 @@
* aorom.h * aorom.h
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -3,7 +3,7 @@
* cnrom.c * cnrom.c
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -3,7 +3,7 @@
* cnrom.h * cnrom.h
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -3,7 +3,7 @@
* iremh3001.c * iremh3001.c
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -3,7 +3,7 @@
* iremh3001.h * iremh3001.h
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -3,7 +3,7 @@
* mmc1.h * mmc1.h
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -3,7 +3,7 @@
* mmc1.h * mmc1.h
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -3,7 +3,7 @@
* mmc3.h * mmc3.h
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -3,7 +3,7 @@
* mmc3.h * mmc3.h
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -3,7 +3,7 @@
* mmc4.h * mmc4.h
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2007-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -3,7 +3,7 @@
* mmc4.h * mmc4.h
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2007-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -3,7 +3,7 @@
* norom.c * norom.c
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -3,7 +3,7 @@
* norom.c * norom.c
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -3,7 +3,7 @@
* unrom.h * unrom.h
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -3,7 +3,7 @@
* unrom.h * unrom.h
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -3,7 +3,7 @@
* mappers_list.h * mappers_list.h
* *
* Created by Manoel TRAPIER on 25/10/07. * Created by Manoel TRAPIER on 25/10/07.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -3,7 +3,7 @@
* mappers.c * mappers.c
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -2,7 +2,7 @@
# TI-NES CMake # TI-NES CMake
# #
# Created by Manoel TRAPIER. # Created by Manoel TRAPIER.
# Copyright (c) 2003-2008 986Corp. All rights reserved. # Copyright (c) 2003-2016 986-Studio. All rights reserved.
# #
# $LastChangedDate$ # $LastChangedDate$
# $Author$ # $Author$

View File

@ -3,7 +3,7 @@
* memory.c - Taken from the Quick6502 project * memory.c - Taken from the Quick6502 project
* *
* Created by Manoel Trapier on 18/09/06. * Created by Manoel Trapier on 18/09/06.
* Copyright 2003-2008 986 Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -2,7 +2,7 @@
# TI-NES CMake # TI-NES CMake
# #
# Created by Manoel TRAPIER. # Created by Manoel TRAPIER.
# Copyright (c) 2003-2008 986Corp. All rights reserved. # Copyright (c) 2003-2016 986-Studio. All rights reserved.
# #
# $LastChangedDate$ # $LastChangedDate$
# $Author$ # $Author$
@ -10,3 +10,5 @@
# $Revision$ # $Revision$
add_library(oslib loadfile.c graphics.c sound.c io.c) add_library(oslib loadfile.c graphics.c sound.c io.c)
target_link_libraries(oslib glfw ${OPENGL_glu_LIBRARY})

View File

@ -3,7 +3,7 @@
* os/macos/graphics.c * os/macos/graphics.c
* *
* Created by Manoel TRAPIER on 08/05/08. * Created by Manoel TRAPIER on 08/05/08.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$
@ -11,19 +11,426 @@
* $Revision$ * $Revision$
* *
*/ */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <os_dependent.h> #include <os_dependent.h>
#include <GLFW/glfw3.h>
#include <OpenGL/glext.h>
#include <palette.h>
typedef struct GLWindow_t GLWindow;
struct KeyArray
{
unsigned char lastState;
unsigned char curState;
unsigned char debounced;
GLFWwindow* window;
};
struct GLWindow_t
{
struct KeyArray keyArray[512];
GLFWwindow* windows;
unsigned char *videoMemory;
GLint videoTexture;
int WIDTH;
int HEIGHT;
};
#ifndef GL_TEXTURE_RECTANGLE_EXT
#define GL_TEXTURE_RECTANGLE_EXT GL_TEXTURE_RECTANGLE_NV
#endif
static int window_num = 0;
void GLWindowInitEx(GLWindow *g, int w, int h)
{
g->WIDTH = w;
g->HEIGHT = h;
g->videoTexture = window_num++;
}
void GLWindowInit(GLWindow *g)
{
GLWindowInitEx(g, 100, 100);
}
void ShowScreen(GLWindow *g, int w, int h)
{
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, g->videoTexture);
// glTexSubImage2D is faster when not using a texture range
glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, w, h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, g->videoMemory);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(-1.0f,1.0f);
glTexCoord2f(0.0f, h);
glVertex2f(-1.0f, -1.0f);
glTexCoord2f(w, h);
glVertex2f(1.0f, -1.0f);
glTexCoord2f(w, 0.0f);
glVertex2f(1.0f, 1.0f);
glEnd();
glFlush();
}
void setupGL(GLWindow *g, int w, int h)
{
g->videoMemory = (unsigned char*)malloc(w*h*sizeof(unsigned int));
memset(g->videoMemory, 0,w*h*sizeof(unsigned int));
//Tell OpenGL how to convert from coordinates to pixel values
glViewport(0, 0, w, h);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glClearColor(1.0f, 0.f, 1.0f, 1.0f);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_RECTANGLE_EXT);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, g->videoTexture);
// glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_NV_EXT, 0, NULL);
// glTexParameteri(GL_TEXTURE_RECTANGLE_NV_EXT, GL_TEXTURE_STORAGE_HINT_APPLE , GL_STORAGE_CACHED_APPLE);
// glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, w,
h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, g->videoMemory);
glDisable(GL_DEPTH_TEST);
}
void restoreGL(GLWindow *g, int w, int h)
{
//Tell OpenGL how to convert from coordinates to pixel values
glViewport(0, 0, w, h);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glClearColor(1.0f, 0.f, 1.0f, 1.0f);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_RECTANGLE_EXT);
glDisable(GL_DEPTH_TEST);
}
void kbHandler(GLFWwindow* window, int key, int scan, int action, int mod )
{
struct KeyArray *keyArray;
keyArray = (struct KeyArray*) glfwGetWindowUserPointer(window);
keyArray[key].lastState=keyArray[key].curState;
if (action==GLFW_RELEASE)
{
keyArray[key].curState=GLFW_RELEASE;
}
else
{
keyArray[key].curState=GLFW_PRESS;
}
keyArray[key].debounced |= (keyArray[key].lastState==GLFW_RELEASE)&&(keyArray[key].curState==GLFW_PRESS);
keyArray[key].window = window;
}
void sizeHandler(GLFWwindow* window,int xs,int ys)
{
glfwMakeContextCurrent(window);
glViewport(0, 0, xs, ys);
}
void initDisplay(GLWindow *g)
{
int h = g->HEIGHT;
int w = g->WIDTH;
/// Initialize GLFW
glfwInit();
// Open screen OpenGL window
if( !(g->windows=glfwCreateWindow( g->WIDTH, g->HEIGHT, "Main", NULL, NULL)) )
{
glfwTerminate();
fprintf(stderr, "Window creation error...\n");
return;
}
glfwMakeContextCurrent(g->windows);
setupGL(g, g->WIDTH, g->HEIGHT);
glfwSwapInterval(0); // Disable VSYNC
glfwGetWindowSize(g->windows, &w, &h);
glfwSetWindowUserPointer(g->windows, g->keyArray);
glfwSetKeyCallback(g->windows, kbHandler);
glfwSetWindowSizeCallback(g->windows, sizeHandler);
}
void drawPixel(GLWindow *gw, int x, int y, uint32_t colour)
{
uint8_t r,g,b,a;
uint32_t offset = (y*gw->WIDTH*4)+4*x;
if ((x < 0) || (x > gw->WIDTH) || (y < 0) || (y > gw->HEIGHT))
return;
b = colour & 0xFF;
g = (colour >> 8) & 0xFF;
r = (colour >> 16) & 0xFF;
a = (colour >> 24) & 0xFF;
gw->videoMemory[offset + 0] = a;
gw->videoMemory[offset + 1] = r;
gw->videoMemory[offset + 2] = g;
gw->videoMemory[offset + 3] = b;
}
void drawLine(GLWindow *g, int x0, int y0, int x1, int y1, uint32_t colour)
{
int d, dx, dy, aincr, bincr, xincr, yincr, x, y;
if (abs(x1 - x0) < abs(y1 - y0))
{
/* parcours par l'axe vertical */
if (y0 > y1)
{
drawLine(g, x1, y1, x0, y0, colour);
goto exit;
}
xincr = x1 > x0 ? 1 : -1;
dy = y1 - y0;
dx = abs(x1 - x0);
d = 2 * dx - dy;
aincr = 2 * (dx - dy);
bincr = 2 * dx;
x = x0;
y = y0;
drawPixel(g, x, y, colour);
for (y = y0+1; y <= y1; y++)
{
if (d >= 0)
{
x += xincr;
d += aincr;
}
else
{
d += bincr;
}
drawPixel(g, x, y, colour);
}
}
else
{
/* parcours par l'axe horizontal */
if (x0 > x1)
{
drawLine(g, x1, y1, x0, y0, colour);
goto exit;
}
yincr = y1 > y0 ? 1 : -1;
dx = x1 - x0;
dy = abs(y1 - y0);
d = 2 * dy - dx;
aincr = 2 * (dy - dx);
bincr = 2 * dy;
x = x0;
y = y0;
drawPixel(g, x, y, colour);
for (x = x0+1; x <= x1; ++x)
{
if (d >= 0)
{
y += yincr;
d += aincr;
}
else
{
d += bincr;
}
drawPixel(g, x, y, colour);
}
}
exit:
return;
}
void drawCircle(GLWindow *g, int xc, int yc, int radius, uint32_t colour)
{
int f = 1 - radius;
int ddF_x = 0;
int ddF_y = -2 * radius;
int x = 0;
int y = radius;
int pX, pY;
pX = xc; pY = yc + radius;
drawPixel(g, pX, pY, colour);
pY -= (2*radius);
drawPixel(g, pX, pY, colour);
pY += radius; pX += radius;
drawPixel(g, pX, pY, colour);
pX -= (2*radius);
drawPixel(g, pX, pY, colour);
while(x < y)
{
if(f >= 0)
{
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x + 1;
pX = xc+x ; pY = yc+y;
drawPixel(g, pX, pY, colour);
pX = xc-x ; pY = yc+y;
drawPixel(g, pX, pY, colour);
pX = xc+x ; pY = yc-y;
drawPixel(g, pX, pY, colour);
pX = xc-x ; pY = yc-y;
drawPixel(g, pX, pY, colour);
pX = xc+y ; pY = yc+x;
drawPixel(g, pX, pY, colour);
pX = xc-y ; pY = yc+x;
drawPixel(g, pX, pY, colour);
pX = xc+y ; pY = yc-x;
drawPixel(g, pX, pY, colour);
pX = xc-y ; pY = yc-x;
drawPixel(g, pX, pY, colour);
}
return;
}
void drawRect(GLWindow *g, int x0, int y0, int w, int h, uint32_t colour)
{
drawLine(g, x0 , y0 , x0 + w, y0 , colour);
drawLine(g, x0 + w, y0 , x0 + w, y0 + h, colour);
drawLine(g, x0 + w, y0 + h, x0 , y0 + h, colour);
drawLine(g, x0 , y0 + h, x0 , y0 , colour);
}
void drawFillrect(GLWindow *g, int x0, int y0, int w, int h, uint32_t colour)
{
int i;
for(i = 0; i < h; i++)
drawLine(g, x0, y0+i, x0+w, y0+i, colour);
}
void clearScreen(GLWindow *g)
{
memset(g->videoMemory, 0, sizeof(uint8_t) * g->WIDTH * g->HEIGHT * 4);
}
void updateScreen(GLWindow *g)
{
/*Update windows code */
glfwMakeContextCurrent(g->windows);
ShowScreen(g, g->WIDTH, g->HEIGHT);
glfwSwapBuffers(g->windows);
glfwPollEvents();
}
void updateScreenAndWait(GLWindow *g)
{
while (glfwGetKey(g->windows,GLFW_KEY_ESCAPE) != GLFW_PRESS)
{
updateScreen(g);
glfwPollEvents();
}
while(glfwGetKey(g->windows,GLFW_KEY_ESCAPE) != GLFW_RELEASE)
{
glfwPollEvents();
}
}
GLWindow mainWindow;
int graphics_init() int graphics_init()
{ {
GLWindowInitEx(&mainWindow, 256, 240);
initDisplay(&mainWindow);
clearScreen(&mainWindow);
updateScreen(&mainWindow);
return 0; return 0;
} }
static unsigned long getColour(long color)
{
Palette *pal = &basicPalette[color];
uint8_t r, g, b, a;
r = pal->r;
b = pal->b;
g = pal->g;
a = 255;//pal->a;
return (b << 24) | (g << 16) | (r << 8) | a;
}
int graphics_drawpixel(long x, long y, long color) int graphics_drawpixel(long x, long y, long color)
{ {
drawPixel(&mainWindow, x, y, getColour(color));
return 0;
}
int graphics_drawline(long x, long y, long x1, long y1, long color)
{
drawLine(&mainWindow, x, y, x1, y1, getColour(color));
return 0; return 0;
} }
int graphics_blit(long x, long y, long w, long h) int graphics_blit(long x, long y, long w, long h)
{ {
updateScreen(&mainWindow);
return 0; return 0;
} }
int getKeyStatus(int key)
{
return mainWindow.keyArray[key].curState;
}

View File

@ -3,7 +3,7 @@
* os/macos/graphics.c * os/macos/graphics.c
* *
* Created by Manoël Trapier on 04/01/09. * Created by Manoël Trapier on 04/01/09.
* Copyright (c) 2003-2009 986 Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -1,3 +1,6 @@
/*
* Copyright (c) 2003-2016 986-Studio. All rights reserved.
*/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>

View File

@ -3,7 +3,7 @@
* paddle.c * paddle.c
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$
@ -12,14 +12,8 @@
* *
*/ */
/* Allegro includes */ #include <os_dependent.h>
#ifdef __APPLE__
#define USE_CONSOLE
#include <Allegro/allegro.h>
#else
#define USE_CONSOLE
#include <allegro.h>
#endif
#include "paddle.h" #include "paddle.h"
void InitPaddle(Paddle *pdl) void InitPaddle(Paddle *pdl)
@ -36,93 +30,65 @@ void WritePaddle(Paddle *pdl, unsigned char val)
pdl->LastWrite = val; pdl->LastWrite = val;
} }
unsigned char ReadPaddle(Paddle *pdl) unsigned char ReadPaddle(Paddle *pdl)
{ {
switch(pdl->Bit++) switch(pdl->Bit++)
{ {
case 1: case 1:
if (key[KEY_Z]) if ( getKeyStatus('O') )
return 0x41; return 0x41;
break; break;
case 2: case 2:
if ( getKeyStatus('P') )
if (key[KEY_X])
return 0x41; return 0x41;
break; break;
case 3: case 3:
if ( getKeyStatus('I') )
if (key[KEY_P])
return 0x41; return 0x41;
break; break;
case 4: case 4:
if ( getKeyStatus('U') )
if (key[KEY_ENTER])
return 0x41; return 0x41;
break; break;
case 5: case 5:
if ( getKeyStatus('W') )
if (key[KEY_UP])
return 0x41; return 0x41;
break; break;
case 6: case 6:
if ( getKeyStatus('S') )
if (key[KEY_DOWN])
return 0x41; return 0x41;
break; break;
case 7: case 7:
if ( getKeyStatus('A') )
if (key[KEY_LEFT])
return 0x41; return 0x41;
break; break;
case 8: case 8:
if ( getKeyStatus('D') )
if (key[KEY_RIGHT])
return 0x41; return 0x41;
break; break;
case 20: case 20:
return 0x40; return 0x40;
break; break;
case 24: case 24:
pdl->Bit = 1; pdl->Bit = 1;
return 0x40; return 0x40;
default: default:
return 0x40; return 0x40;
break; break;
} }
return 0x40;
return 0x40;
} }

View File

@ -2,7 +2,7 @@
# TI-NES CMake # TI-NES CMake
# #
# Created by Manoel TRAPIER. # Created by Manoel TRAPIER.
# Copyright (c) 2003-2008 986Corp. All rights reserved. # Copyright (c) 2003-2016 986-Studio. All rights reserved.
# #
# $LastChangedDate$ # $LastChangedDate$
# $Author$ # $Author$

View File

@ -3,7 +3,7 @@
* plugins.c * plugins.c
* *
* Created by Manoel TRAPIER on 02/04/07. * Created by Manoel TRAPIER on 02/04/07.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -3,7 +3,7 @@
* gamegenie.c: Hack your games with unlimited lives of add new powers! * gamegenie.c: Hack your games with unlimited lives of add new powers!
* *
* Created by Manoel Trapier. * Created by Manoel Trapier.
* Copyright 2003-2008 986 Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$
@ -24,6 +24,7 @@
#include <memory/manager.h> #include <memory/manager.h>
#include <types.h> #include <types.h>
#if 0
/* Allegro includes */ /* Allegro includes */
#ifdef __APPLE__ #ifdef __APPLE__
#define USE_CONSOLE #define USE_CONSOLE
@ -824,3 +825,4 @@ int gg_Deinit()
{ {
return 0; return 0;
} }
#endif

View File

@ -3,7 +3,7 @@
* gamegenie.h * gamegenie.h
* *
* Created by Manoel Trapier. * Created by Manoel Trapier.
* Copyright 2003-2008 986 Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$

View File

@ -3,7 +3,7 @@
* plugins_list.h * plugins_list.h
* *
* Created by Manoel Trapier. * Created by Manoel Trapier.
* Copyright 2003-2008 986 Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$
@ -17,7 +17,7 @@
#include "plugins/gamegenie.h" #include "plugins/gamegenie.h"
Plugin Plugins[] = { Plugin Plugins[] = {
{ "Game Genie", gg_Init, gg_Deinit }, // { "Game Genie", gg_Init, gg_Deinit },
/* EOL tag */ /* EOL tag */
{ NULL, NULL, NULL } { NULL, NULL, NULL }

View File

@ -5,7 +5,7 @@
* Define and emulate the PPU (Picture Processing Unit) of the real NES * Define and emulate the PPU (Picture Processing Unit) of the real NES
* *
* Created by Manoel TRAPIER. * Created by Manoel TRAPIER.
* Copyright (c) 2003-2008 986Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$
@ -14,20 +14,14 @@
* *
*/ */
/* Allegro includes */
#ifdef __APPLE__
#define USE_CONSOLE
#include <Allegro/allegro.h>
#else
#define USE_CONSOLE
#include <allegro.h>
#endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <os_dependent.h>
#define __TINES_PPU_INTERNAL__ #define __TINES_PPU_INTERNAL__
#include <ppu/ppu.h> #include <ppu/ppu.h>
#include <ppu/ppu.memory.h> #include <ppu/ppu.memory.h>
#include <ppu/ppu.debug.h> #include <ppu/ppu.debug.h>
@ -37,12 +31,11 @@
#include <os_dependent.h> #include <os_dependent.h>
#define __TINES_PLUGINS__ #define __TINES_PLUGINS__
#include <plugins/manager.h> #include <plugins/manager.h>
extern int VBLANK_TIME; extern int VBLANK_TIME;
extern BITMAP *Buffer;
volatile extern int frame; volatile extern int frame;
volatile extern unsigned long IPS, FPS; volatile extern unsigned long IPS, FPS;
@ -50,115 +43,93 @@ extern unsigned long ColorPalette[ 9 * 63 ];
extern short IRQScanHit; extern short IRQScanHit;
extern short SZHit; extern short SZHit;
BITMAP *VideoBuffer; /* The ppu will only write pixel to this, and then bliting typedef struct spriteData
this on the screen "surface" */ {
uint8_t palette;
uint8_t flip_h;
uint8_t flip_v;
uint8_t priority;
uint8_t tile;
uint8_t bank;
uint8_t y;
uint8_t x;
uint8_t rel_y;
uint8_t inUse;
} spriteData;
/* PPU sprite sorted by scanline */
/* Work as follow:
3322 2222 2222 1111 1111 1100 0000 0000
1098 7654 3210 9876 5432 1098 7654 3210
---------------------------------------
AAAA AAAA TTTT TTTT xxxx XXXX YYYY YYYY
---------------------------------------
8421 8421 8421 8421 8421 8421 8421 8421
A = Sprite Attributes
x = reserved
T = Tile ID
X = X relative position
Y = Y absolute position
x = for future use
*/
unsigned long PPU_SpriteByScanLine[241][9]; /* There is 240 scanline and 8 sprite per scanline */
unsigned long PPU_NbSpriteByScanLine[241]; /* There is 240 scanline and 8 sprite per scanline */
unsigned long PPU_NbSpriteByScanLineOverFlow[241]; /* There is 240 scanline and 8 sprite per scanline */
#define PPU_SCANLINESPRITE_GET_ATTRS(sprt) (((sprt)&0xFF000000) >> 24)
#define PPU_SCANLINESPRITE_GET_TILIDX(sprt) (((sprt)&0x00FF0000) >> 16)
#define PPU_SCANLINESPRITE_GET_RELY(sprt) (((sprt)&0x00000F00) >> 8)
#define PPU_SCANLINESPRITE_GET_X(sprt) ((sprt)&0x000000FF)
#define PPU_SCANLINESPRITE_SET_ATTRS(sprt, v) sprt = (((sprt)&0x00FFFFFF) | (( (v) & 0xFF) << 24))
#define PPU_SCANLINESPRITE_SET_TILIDX(sprt, v) sprt = (((sprt)&0xFF00FFFF) | (( (v) & 0xFF) << 16))
#define PPU_SCANLINESPRITE_SET_RELY(sprt, v) sprt = (((sprt)&0xFFFFF0FF) | (( (v) & 0x0F) << 8))
#define PPU_SCANLINESPRITE_SET_X(sprt, v) sprt = (((sprt)&0xFFFFFF00) | ( (v) & 0xFF ))
/* PPU registers */ /* PPU registers */
/* NT: Name Table */ /* NT: Name Table */
byte PPU_Reg_NT; uint8_t PPU_Reg_NT;
/* AT: Attribute/Color Table */ /* AT: Attribute/Color Table */
byte PPU_Reg_AT; uint8_t PPU_Reg_AT;
/* FV: Fine Vertical Scroll latch/counter */ /* FV: Fine Vertical Scroll latch/counter */
byte PPU_Reg_FV; uint8_t PPU_Reg_FV;
/* HV: Fine Horizontal Scroll latch/counter */ /* HV: Fine Horizontal Scroll latch/counter */
byte PPU_Reg_FH; uint8_t PPU_Reg_FH;
/* VT: Vertical Tile indev latch/counter */ /* VT: Vertical Tile indev latch/counter */
byte PPU_Reg_VT; uint8_t PPU_Reg_VT;
/* HT: Horizontal Tile indev latch/counter */ /* HT: Horizontal Tile indev latch/counter */
byte PPU_Reg_HT; uint8_t PPU_Reg_HT;
/* V: Vertical Name Table Selection latch/counter */ /* V: Vertical Name Table Selection latch/counter */
byte PPU_Reg_V; uint8_t PPU_Reg_V;
/* H: Horizontal Name Table Selection latch/counter */ /* H: Horizontal Name Table Selection latch/counter */
byte PPU_Reg_H; uint8_t PPU_Reg_H;
/* S: Playfield pattern table selection latch */ /* S: Playfield pattern table selection latch */
unsigned short PPU_Reg_S; unsigned short PPU_Reg_S;
/* PAR: Picture Address Register */ /* PAR: Picture Address Register */
byte PPU_Reg_PAR; uint8_t PPU_Reg_PAR;
/* AR: Tile Attribute (palette select) value latch */ /* AR: Tile Attribute (palette select) value latch */
byte PPU_Reg_AR; uint8_t PPU_Reg_AR;
unsigned short PPU_Reg_Counter; unsigned short PPU_Reg_Counter;
/* PPU Memory Areas */ /* PPU Memory Areas */
byte *ppu_mem_nameTables; uint8_t *ppu_mem_nameTables;
byte *ppu_mem_patternTables; uint8_t *ppu_mem_patternTables;
byte *ppu_mem_paletteValues; uint8_t *ppu_mem_paletteValues;
byte ppu_mem_spritesTable[0x100]; uint8_t ppu_mem_spritesTable[0x100];
byte ppu_mem_sptrTablePtr; uint8_t ppu_mem_sptrTablePtr;
/* Some other PPU "registers" */ /* Some other PPU "registers" */
byte ppu_VramAccessFlipFlop; uint8_t ppu_VramAccessFlipFlop;
byte ppu_inVBlankTime; uint8_t ppu_inVBlankTime;
byte ppu_spriteZeroHit; uint8_t ppu_spriteZeroHit;
byte ppu_scanlineSpriteOverflow; uint8_t ppu_scanlineSpriteOverflow;
byte ppu_bgColor; uint8_t ppu_bgColor;
/* CR #1 variables */ /* CR #1 variables */
unsigned short ppu_spritePatternTable; uint16_t ppu_spritePatternTable;
byte ppu_spriteSize; uint8_t ppu_spriteSize;
byte ppu_addrIncrement; uint8_t ppu_addrIncrement;
byte ppu_execNMIonVBlank; uint8_t ppu_execNMIonVBlank;
/* CR #2 variables */ /* CR #2 variables */
byte ppu_spriteVisibility; uint8_t ppu_spriteVisibility;
byte ppu_backgroundVisibility; uint8_t ppu_backgroundVisibility;
byte ppu_spriteClipping; uint8_t ppu_spriteClipping;
byte ppu_backgroundClipping; uint8_t ppu_backgroundClipping;
byte ppu_displayType; uint8_t ppu_displayType;
byte ppu_mirrorMode; uint8_t ppu_mirrorMode;
byte ppu_singleScreenMode; uint8_t ppu_singleScreenMode;
byte ppu_screenMode; uint8_t ppu_screenMode;
#define PPU_MEM_PATTERNTABLES_SIZE 0x2000 #define PPU_MEM_PATTERNTABLES_SIZE 0x2000
#define PPU_MEM_NAMETABLE_SIZE 0x1000 #define PPU_MEM_NAMETABLE_SIZE 0x1000
@ -184,7 +155,7 @@ int ppu_init()
{ {
int i; int i;
/*byte defaultColors[] = { 0x09,0x01,0x00,0x01,0x00,0x02,0x02,0x0D,0x08,0x10,0x08,0x24,0x00,0x00,0x04,0x2C, /*uint8_t defaultColors[] = { 0x09,0x01,0x00,0x01,0x00,0x02,0x02,0x0D,0x08,0x10,0x08,0x24,0x00,0x00,0x04,0x2C,
0x09,0x01,0x34,0x03,0x00,0x04,0x00,0x14,0x08,0x3A,0x00,0x02,0x00,0x20,0x2C,0x08 };*/ 0x09,0x01,0x34,0x03,0x00,0x04,0x00,0x14,0x08,0x3A,0x00,0x02,0x00,0x20,0x2C,0x08 };*/
if ( ppu_initMemory() ) if ( ppu_initMemory() )
@ -193,15 +164,15 @@ int ppu_init()
/* Set ppu memory parameters */ /* Set ppu memory parameters */
/* First: Allocate each memory zone */ /* First: Allocate each memory zone */
ppu_mem_patternTables = (byte*) malloc(PPU_MEM_PATTERNTABLES_SIZE); ppu_mem_patternTables = (uint8_t *) malloc(PPU_MEM_PATTERNTABLES_SIZE);
if ( !ppu_mem_patternTables ) if ( !ppu_mem_patternTables )
return -1; return -1;
ppu_mem_nameTables = (byte*) malloc(PPU_MEM_NAMETABLE_SIZE); ppu_mem_nameTables = (uint8_t *) malloc(PPU_MEM_NAMETABLE_SIZE);
if ( !ppu_mem_nameTables ) if ( !ppu_mem_nameTables )
return -1; return -1;
ppu_mem_paletteValues = (byte*) malloc(PPU_MEM_PALETTEVALUES_SIZE); ppu_mem_paletteValues = (uint8_t *) malloc(PPU_MEM_PALETTEVALUES_SIZE);
if ( !ppu_mem_paletteValues ) if ( !ppu_mem_paletteValues )
return -1; return -1;
@ -264,86 +235,12 @@ int ppu_init()
set_page_ghost(i, true, 0x20); set_page_ghost(i, true, 0x20);
/* allocate the PPU Video memory */ /* allocate the PPU Video memory */
VideoBuffer = create_bitmap(256, 240); graphics_init();
if (VideoBuffer == NULL)
return -1;
return 0; return 0;
} }
void ppu_updateSpriteScanlineTable() void ppu_setMirroring(uint8_t direction)
{
int32_t i,j,k;
int line;
volatile int32_t sprite_x, sprite_y, sprite_idx, sprite_attr;
int curline;
for (line = 0; line < 241; line ++)
{
PPU_NbSpriteByScanLine[line] = 0;
PPU_NbSpriteByScanLineOverFlow[line] = 0;
for (i = 0; i < 9; i++)
PPU_SpriteByScanLine[line][i] = 0xFFFFFFFF;
}
for ( i = 0; i < 64; i ++)
{
/* Fill sprite_zzz variables */
sprite_y = ppu_mem_spritesTable[(i*4) + 0] + 1;
sprite_idx = ppu_mem_spritesTable[(i*4) + 1];
sprite_attr = ppu_mem_spritesTable[(i*4) + 2] | ((i==0)?0x04:0); /* Add a flag for the sprite #0 */
sprite_x = ppu_mem_spritesTable[(i*4) + 3];
/* For each line covered by the sprite */
for (line = 0; line < ppu_spriteSize; line ++)
{
curline = line + sprite_y;
if ((curline < 0) || (curline > 240))
continue; /* Don't go beyond, this sprite go beyond the borders */
if (PPU_NbSpriteByScanLine[curline] < 8)
PPU_NbSpriteByScanLine[curline] ++;
else
{
PPU_NbSpriteByScanLineOverFlow[curline] = 1;
continue; /* We have 8 sprite in this line, don't continue */
}
if (((sprite_x+8) < 0) && ((sprite_x-8) > 256))
continue; /* this sprite isn't either displayable */
/* Now test if this sprite can be put in the sprite list */
for (j = 0; j <= (int32_t)PPU_NbSpriteByScanLine[curline]; j++)
{
/* sprite are ordered by their y value, so, the first time that
we have lower y value is where we need to put the sprite */
if (sprite_x < (int32_t)PPU_SCANLINESPRITE_GET_X(PPU_SpriteByScanLine[curline][j]))
{
/* move the j eme item and next to the right in the list, trashing
if needed the rightest item. */
for (k = 7; k >= j; k--)
PPU_SpriteByScanLine[curline][k] = PPU_SpriteByScanLine[curline][k-1];
PPU_SpriteByScanLine[curline][j] = 0;
PPU_SCANLINESPRITE_SET_ATTRS (PPU_SpriteByScanLine[curline][j], sprite_attr);
PPU_SCANLINESPRITE_SET_TILIDX(PPU_SpriteByScanLine[curline][j], sprite_idx);
PPU_SCANLINESPRITE_SET_RELY (PPU_SpriteByScanLine[curline][j], curline - sprite_y);
PPU_SCANLINESPRITE_SET_X (PPU_SpriteByScanLine[curline][j], sprite_x);
break; /* Stop the for, we don't need to go further in the line list */
}
}
}
}
}
void ppu_setMirroring(byte direction)
{ {
if ( ppu_screenMode != PPU_SCMODE_NORMAL ) if ( ppu_screenMode != PPU_SCMODE_NORMAL )
return; return;
@ -373,7 +270,7 @@ void ppu_setMirroring(byte direction)
ppu_mirrorMode = direction; ppu_mirrorMode = direction;
} }
void ppu_setSingleScreen(byte screen) void ppu_setSingleScreen(uint8_t screen)
{ {
if ( ppu_screenMode != PPU_SCMODE_SINGLE ) if ( ppu_screenMode != PPU_SCMODE_SINGLE )
return; return;
@ -421,7 +318,7 @@ void ppu_setSingleScreen(byte screen)
Single screen (1 NT with mirroring) Single screen (1 NT with mirroring)
Normal screen (2 NT with mirroring) Normal screen (2 NT with mirroring)
Four screen (4 NT without mirroring) */ Four screen (4 NT without mirroring) */
void ppu_setScreenMode(byte mode) void ppu_setScreenMode(uint8_t mode)
{ {
if ( ppu_screenMode == mode ) if ( ppu_screenMode == mode )
return; /* Same value, no need to change! */ return; /* Same value, no need to change! */
@ -478,40 +375,73 @@ _AAA BCDD DDDE EEEE
PPU_Reg_Counter |= PPU_Reg_HT; PPU_Reg_Counter |= PPU_Reg_HT;
} }
int ppu_hblank(int scanline) int ppu_hblank(uint16_t scanline)
{ {
uint32_t i, j; uint32_t i, j;
byte pixelColor = 0x42; uint8_t pixelColor = 0;
byte BgColor = 0x42; uint8_t BgColor = 0;
byte SpriteColor = 0x42; uint8_t SpriteColor = 0;
/* Sprite to display on current scanline */
spriteData scanSprites[8];
uint16_t addr; uint16_t addr;
byte value; uint8_t value;
uint16_t tmp_HHT = 0; uint16_t tmp_HHT = 0;
uint16_t tmp_VVTFV = 0; uint16_t tmp_VVTFV = 0;
uint32_t CurrentSprite; uint8_t spriteCount = 0;
byte SpriteVFlip; ppu_scanlineSpriteOverflow = 0;
if ( scanline == 0 ) if ( scanline == 0 )
{ {
ppu_bgColor = ppu_readMemory(0x3F,00);
rectfill(Buffer, 256, 0, 277, 260, ppu_bgColor);
if ( ( ppu_spriteVisibility != 0 ) || ( ppu_backgroundVisibility != 0 ) ) if ( ( ppu_spriteVisibility != 0 ) || ( ppu_backgroundVisibility != 0 ) )
ppu_updateCounters(); ppu_updateCounters();
} }
if ( scanline < 240 ) if ( scanline < 240 )
{ {
/* Search for sprites on current scanline */
for (i = 0 ; i < 8 ; i++)
{
scanSprites[i].inUse = 0;
}
for (i = 0 ; i < 64 && spriteCount < 8; i++)
{
uint8_t spriteY = ppu_mem_spritesTable[i*4] + 1;
if ((scanline >= spriteY) && (scanline < (spriteY + ppu_spriteSize)))
{
/* This sprite is on the scanline */
scanSprites[spriteCount].inUse = 1;
scanSprites[spriteCount].x = ppu_mem_spritesTable[i*4 + 3];
scanSprites[spriteCount].y = spriteY;
scanSprites[spriteCount].rel_y = scanline - scanSprites[spriteCount].y;
scanSprites[spriteCount].tile = ppu_mem_spritesTable[i * 4 + 1];
scanSprites[spriteCount].bank = ppu_mem_spritesTable[i * 4 + 1] & 0x01;
scanSprites[spriteCount].flip_h = ( ppu_mem_spritesTable[i * 4 + 2] & PPU_SPRITE_FLAGS_HFLIP )?1:0;
scanSprites[spriteCount].flip_v = ( ppu_mem_spritesTable[i * 4 + 2] & PPU_SPRITE_FLAGS_VFLIP )?1:0;
scanSprites[spriteCount].palette = ( ppu_mem_spritesTable[i * 4 + 2] & PPU_SPRITE_FLAGS_UPPERCOLOR ) & 0x0F;
scanSprites[spriteCount].priority = ( ppu_mem_spritesTable[i * 4 + 2] & PPU_SPRITE_FLAGS_BGPRIO )?1:0;
spriteCount++;
}
}
ppu_bgColor = ppu_readMemory(0x3F, 00);
/* For each PPU pixel of this scanline */ /* For each PPU pixel of this scanline */
for ( i = 0 ; i < 256 ; i++ ) for ( i = 0 ; i < 256 ; i++ )
{ {
/* Set the current pixel color to the bg color */ /* Set the current pixel color to the bg color */
pixelColor = ppu_readMemory(0x3F,00); pixelColor = ppu_bgColor;
BgColor = 0;
/* Compute current pixel bg color if bg is visible */ /* Compute current pixel bg color if bg is visible */
if (ppu_backgroundVisibility == 1) if (( ppu_backgroundVisibility == 1 ) && (!getKeyStatus('B')))
{
if ( ((i < 8) && (!ppu_backgroundClipping)) || (i >= 8))
{ {
addr = ( PPU_Reg_Counter & 0x0C00 ); addr = ( PPU_Reg_Counter & 0x0C00 );
addr = addr | 0x03C0; addr = addr | 0x03C0;
@ -555,89 +485,118 @@ int ppu_hblank(int scanline)
( tmp_HHT & 0x001F ); ( tmp_HHT & 0x001F );
} }
} }
#if 0
// ISPAL
else
{
pixelColor = 0x1D;
}
#endif
}
/* Now calculate if there is a sprite here and sprite visibility is on */ /* Now calculate if there is a sprite here and sprite visibility is on */
if ((ppu_spriteVisibility == 1) && if ( ppu_spriteVisibility == 1 )
(PPU_NbSpriteByScanLine[scanline] != 0))
{ {
/* scan each sprite on this line to find the one (or more) that is on this pixel */ if (((!ppu_spriteClipping) && (i < 8)) || (i >= 8))
for (j = 0; j < PPU_NbSpriteByScanLine[scanline]; j++)
{ {
/* they are orderer by X, so if this one is too far on the right for( j = 0 ; j < 8 ; j++)
it's not need to go further */ {
CurrentSprite = PPU_SpriteByScanLine[scanline][j]; spriteData *sprite = &scanSprites[j];
int8_t spriteRelX;
if (PPU_SCANLINESPRITE_GET_X(CurrentSprite) > i) if ( sprite->inUse == 0 )
break; /* break the current for */ break;
if ((PPU_SCANLINESPRITE_GET_X(CurrentSprite) + 8) < i) spriteRelX = i - sprite->x;
continue; /* Not this one too (too far on the left) try next one*/
/* Ok if we arrive here, the current sprite is on the good position */
/* Does the sprite is a BG or FG sprite ? */
/* Ok we could now get the sprite current pixel color */
/* Read sprite scanline pattern */
SpriteVFlip = PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & PPU_SPRITE_FLAGS_VFLIP;
if ( ( spriteRelX >= 0 ) && ( spriteRelX < 8 ) )
{
/* Get sprite tile address */
if ( ppu_spriteSize == 8 ) if ( ppu_spriteSize == 8 )
{ {
addr = (PPU_SCANLINESPRITE_GET_TILIDX(CurrentSprite) << 4) + ppu_spritePatternTable; addr = ( sprite->tile << 4 ) + ppu_spritePatternTable;
} }
else else
{ {
if (PPU_SCANLINESPRITE_GET_RELY(CurrentSprite) < 8) if ( sprite->rel_y < 8 )
addr = (((PPU_SCANLINESPRITE_GET_TILIDX(CurrentSprite)&0xFE) + (SpriteVFlip?1:0)) << 4) + ((PPU_SCANLINESPRITE_GET_TILIDX(CurrentSprite)&0x01)?0x1000:0x0000); {
else addr = ( ( ( sprite->tile & 0xFE ) + ( sprite->flip_v?1:0 ) ) << 4 ) +
addr = (((PPU_SCANLINESPRITE_GET_TILIDX(CurrentSprite)&0xFE) + (SpriteVFlip?0:1)) << 4) + ((PPU_SCANLINESPRITE_GET_TILIDX(CurrentSprite)&0x01)?0x1000:0x0000); ( ( sprite->bank )?0x1000:0x0000 );
} }
if (SpriteVFlip) else
{
addr = ( ( ( sprite->tile & 0xFE ) + ( sprite->flip_v?0:1 ) ) << 4 ) +
( ( sprite->bank )?0x1000:0x0000 );
}
}
if ( sprite->flip_v )
{ {
addr += 7; addr += 7;
addr -= (PPU_SCANLINESPRITE_GET_RELY(CurrentSprite) % 8); addr -= sprite->rel_y % 8;
} }
else else
addr += (PPU_SCANLINESPRITE_GET_RELY(CurrentSprite) % 8); {
addr += sprite->rel_y % 8;
}
if ( sprite->flip_h )
if (PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & PPU_SPRITE_FLAGS_HFLIP)
{ {
value = ppu_readMemory(( addr >> 8 ), addr); value = ppu_readMemory(( addr >> 8 ), addr);
SpriteColor = (value & (1 << (i-PPU_SCANLINESPRITE_GET_X(CurrentSprite))))?0x01:0; SpriteColor = ( value & ( 1 << ( spriteRelX ) ) )?0x01:0;
value = ppu_readMemory(( addr >> 8 ), addr | 0x08); value = ppu_readMemory(( addr >> 8 ), addr | 0x08);
SpriteColor |= (value & (1 << (i-PPU_SCANLINESPRITE_GET_X(CurrentSprite))))?0x02:0; SpriteColor |= ( value & ( 1 << ( spriteRelX ) ) )?0x02:0;
} }
else else
{ {
value = ppu_readMemory(( addr >> 8 ), addr); value = ppu_readMemory(( addr >> 8 ), addr);
SpriteColor = (value & (1 << (7-(i-PPU_SCANLINESPRITE_GET_X(CurrentSprite)))))?0x01:0; SpriteColor = ( value & ( 1 << ( 7 - ( spriteRelX ) ) ) )?0x01:0;
value = ppu_readMemory(( addr >> 8 ), addr | 0x08); value = ppu_readMemory(( addr >> 8 ), addr | 0x08);
SpriteColor |= (value & (1 << (7-(i-PPU_SCANLINESPRITE_GET_X(CurrentSprite)))))?0x02:0; SpriteColor |= ( value & ( 1 << ( 7 - ( spriteRelX ) ) ) )?0x02:0;
} }
if (SpriteColor > 0x00) /* If we get a color different from 0, the pixel is not transparent */
if ( SpriteColor > 0 )
{ {
SpriteColor |= ((PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & PPU_SPRITE_FLAGS_UPPERCOLOR) << 2); /* Add second part of the colour */
SpriteColor |= ( ( sprite->palette ) << 2 );
SpriteColor &= 0x0F; SpriteColor &= 0x0F;
}
if ((PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & 0x04) && if ( j == 0 )
(SpriteColor != 0x00) && (BgColor != 0x00))
{ {
if (!ppu_spriteZeroHit) /* Sprite 0 */
if ( ( BgColor != 0 ) && ( !ppu_spriteZeroHit ) )
{ {
ppu_spriteZeroHit = ( ppu_backgroundVisibility )?1:0; ppu_spriteZeroHit = ( ppu_backgroundVisibility )?1:0;
if ( ppu_spriteZeroHit ) if ( ppu_spriteZeroHit )
SZHit = scanline; SZHit = scanline;
} }
} }
if ( ( (PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & PPU_SPRITE_FLAGS_BGPRIO) && (BgColor == 0x0000)) ||
(!(PPU_SCANLINESPRITE_GET_ATTRS(CurrentSprite) & PPU_SPRITE_FLAGS_BGPRIO)) ) if ( sprite->priority )
{ {
if (SpriteColor != 0x00) pixelColor = ppu_readMemory(0x3F, (0x10 + SpriteColor)); if ( SpriteColor > 0x00 )
{
if ( BgColor == 0 )
{
pixelColor = ppu_readMemory(0x3F, ( 0x10 + SpriteColor ));
} }
break;
}
}
else
{
if ( SpriteColor != 0x00 )
{
pixelColor = ppu_readMemory(0x3F, ( 0x10 + SpriteColor ));
break;
}
}
}
}
}
} }
} }
@ -646,14 +605,13 @@ int ppu_hblank(int scanline)
pixelColor &= 0x30; pixelColor &= 0x30;
/* draw the pixel */ /* draw the pixel */
_putpixel(VideoBuffer, i, scanline, pixelColor); graphics_drawpixel(i, scanline, pixelColor);
} }
if (ppu_backgroundVisibility || ppu_spriteVisibility) if (spriteCount > 8)
if (PPU_NbSpriteByScanLineOverFlow[scanline] == 1) {
ppu_scanlineSpriteOverflow = 1; ppu_scanlineSpriteOverflow = 1;
}
//blit(VideoBuffer, screen, 0, scanline, 0, scanline, 256, 1);
if ( ppu_backgroundVisibility == 1 ) if ( ppu_backgroundVisibility == 1 )
{ {
@ -680,7 +638,7 @@ int ppu_hblank(int scanline)
PPU_Reg_HT; PPU_Reg_HT;
} }
} }
/* Increment only V & VT & FV*/ /* Increment only V, VT & FV*/
/* /*
8421 8421 8421 8421 8421 8421 8421 8421
@ -706,33 +664,22 @@ E = HT
if ( scanline == 239 ) if ( scanline == 239 )
{ {
ppu_inVBlankTime = 1; ppu_inVBlankTime = 1;
textprintf_ex(Buffer, font, 260, 3, 4, 0, "FPS : %ld (CPU@~%2.2fMhz : %d%%)", FPS, (float) (((float) IPS) / 1000000.0), (int) ((((float) IPS) / 1770000.0) * 100.0)); // textprintf_ex(Buffer, font, 260, 3, 4, 0, "FPS : %ld (CPU@~%2.2fMhz : %d%%)", FPS, (float) (((float) IPS) / 1000000.0), (int) ((((float) IPS) / 1770000.0) * 100.0));
blit(VideoBuffer, Buffer, 0, 0, 0, 0, 256, 240);
blit(Buffer, screen, 0, 0, 0, 0, 512+256, 512);
graphics_blit(0, 0, 256, 240);
return ppu_execNMIonVBlank; return ppu_execNMIonVBlank;
} }
if (scanline == SZHit) /* Debug tools */
/*if ( scanline == SZHit )
{ {
line(Buffer, 257, scanline, 267, scanline, 0x12); graphics_drawline(0, scanline, 256, scanline, 0x12);
line(Buffer, 257, scanline, 260, scanline-2, 0x12);
line(Buffer, 257, scanline, 260, scanline+2, 0x12);
} }
if ( scanline == IRQScanHit ) if ( scanline == IRQScanHit )
{ {
line(Buffer, 267, scanline, 277, scanline, 0x13); graphics_drawline(0, scanline, 256, scanline, 0x13);
line(Buffer, 267, scanline, 270, scanline-2, 0x13); }*/
line(Buffer, 267, scanline, 270, scanline+2, 0x13); /* */
}
if (key[KEY_B])
{
blit(VideoBuffer, Buffer, 0, 0, 0, 0, 256, 240);
blit(Buffer, screen, 0, 0, 0, 0, 512 + 256, 480);
}
if ( scanline == ( 239 + VBLANK_TIME ) + 0 ) if ( scanline == ( 239 + VBLANK_TIME ) + 0 )
{ {
@ -743,13 +690,13 @@ E = HT
return 0; return 0;
} }
byte PPU_RegValues[8]; uint8_t PPU_RegValues[8];
byte ppu_readReg(byte id) uint8_t ppu_readReg(uint8_t id)
{ {
id &= 0x07; id &= 0x07;
static byte garbage; static uint8_t garbage;
static byte lastValue; static uint8_t lastValue;
switch(id) switch(id)
{ {
default: default:
@ -795,7 +742,7 @@ byte ppu_readReg(byte id)
} }
void ppu_writeReg(byte id, byte val) void ppu_writeReg(uint8_t id, uint8_t val)
{ {
id &= 0x07; id &= 0x07;
PPU_RegValues[id] = val; PPU_RegValues[id] = val;
@ -805,7 +752,6 @@ void ppu_writeReg(byte id, byte val)
break; break;
case 0x00: /* PPU Control Register #1 */ case 0x00: /* PPU Control Register #1 */
/* /*
+===============+===============================================+ +===============+===============================================+
|2000 | 1 0 4 | |2000 | 1 0 4 |
@ -829,14 +775,11 @@ void ppu_writeReg(byte id, byte val)
break; break;
case 0x01: /* PPU Control Register #2 */ case 0x01: /* PPU Control Register #2 */
ppu_spriteVisibility = ( val & 0x10 )?1:0; ppu_spriteVisibility = ( val & 0x10 )?1:0;
ppu_backgroundVisibility = ( val & 0x08 )?1:0; ppu_backgroundVisibility = ( val & 0x08 )?1:0;
ppu_spriteClipping = (val & 0x04)?1:0; ppu_spriteClipping = ( val & 0x04 )?0:1;
ppu_backgroundClipping = (val & 0x02)?1:0; ppu_backgroundClipping = ( val & 0x02 )?0:1;
ppu_displayType = ( val & 0x01 )?1:0; ppu_displayType = ( val & 0x01 )?1:0;
ppu_updateSpriteScanlineTable();
break; break;
case 0x03: /* SPR-RAM Address Register */ case 0x03: /* SPR-RAM Address Register */
@ -845,7 +788,6 @@ void ppu_writeReg(byte id, byte val)
case 0x04: /* SPR-RAM I/O */ case 0x04: /* SPR-RAM I/O */
ppu_mem_spritesTable[ppu_mem_sptrTablePtr++] = val; ppu_mem_spritesTable[ppu_mem_sptrTablePtr++] = val;
ppu_updateSpriteScanlineTable();
break; break;
case 0x05: /* 2005 VRAM Register */ case 0x05: /* 2005 VRAM Register */
@ -928,13 +870,12 @@ void ppu_writeReg(byte id, byte val)
} }
} }
void ppu_fillSprRamDMA(byte value) void ppu_fillSprRamDMA(uint8_t value)
{ {
short i; short i;
byte *ptr = get_page_ptr(value); uint8_t *ptr = get_page_ptr(value);
for ( i = 0 ; i < 0x100 ; i++ ) for ( i = 0 ; i < 0x100 ; i++ )
{ {
ppu_mem_spritesTable[( ppu_mem_sptrTablePtr + i ) & 0xFF] = *( ptr + i ); ppu_mem_spritesTable[( ppu_mem_sptrTablePtr + i ) & 0xFF] = *( ptr + i );
} }
ppu_updateSpriteScanlineTable();
} }

View File

@ -3,7 +3,7 @@
* ppu.memory.c - Inspired from the memory manager of the Quick6502 Project. * ppu.memory.c - Inspired from the memory manager of the Quick6502 Project.
* *
* Created by Manoel Trapier on 12/04/07. * Created by Manoel Trapier on 12/04/07.
* Copyright 2003-2008 986 Corp. All rights reserved. * Copyright (c) 2003-2016 986-Studio. All rights reserved.
* *
* $LastChangedDate$ * $LastChangedDate$
* $Author$ * $Author$