From cc9a03f51229e11f6d7523665c9aa505d350feaa Mon Sep 17 00:00:00 2001 From: stephena Date: Wed, 21 Apr 2004 16:27:34 +0000 Subject: [PATCH] - Beginings of support for MacOS X. That's right boys and girls, there's an OSX port on the way. - Added z26 palette support. Use Control-P to switch between the three available color palettes. - Special thanks go to Mark Grebe for all the above changes. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@238 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- stella/src/build/makefile | 5 +- stella/src/emucore/Settings.hxx | 37 +- stella/src/emucore/TIA.cxx | 142 ++- stella/src/emucore/TIASound.c | 1337 +++++++++++++------------- stella/src/ui/sdl/FrameBufferSDL.cxx | 7 +- 5 files changed, 830 insertions(+), 698 deletions(-) diff --git a/stella/src/build/makefile b/stella/src/build/makefile index ceb2b8224..0bba57909 100644 --- a/stella/src/build/makefile +++ b/stella/src/build/makefile @@ -13,7 +13,7 @@ ## See the file "license" for information on usage and redistribution of ## this file, and for a DISCLAIMER OF ALL WARRANTIES. ## -## $Id: makefile,v 1.50 2004-04-20 21:07:35 stephena Exp $ +## $Id: makefile,v 1.51 2004-04-21 16:27:14 stephena Exp $ ##============================================================================ ##============================================================================ @@ -43,9 +43,6 @@ OPTIMIZATIONS = ### change to number of CPU's you have NUMBER_CPU = 1 -### you want a 6507 trace written to stdout -# DEBUG = 1 - ##============================================================================ ## All done, type make to get a list of frontends ## No configurable options below this line ... diff --git a/stella/src/emucore/Settings.hxx b/stella/src/emucore/Settings.hxx index ebdc91e3f..0d338920f 100644 --- a/stella/src/emucore/Settings.hxx +++ b/stella/src/emucore/Settings.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Settings.hxx,v 1.11 2003-11-24 01:14:38 stephena Exp $ +// $Id: Settings.hxx,v 1.12 2004-04-21 16:27:18 stephena Exp $ //============================================================================ #ifndef SETTINGS_HXX @@ -32,7 +32,7 @@ class Console; This class provides an interface for accessing frontend specific settings. @author Stephen Anthony - @version $Id: Settings.hxx,v 1.11 2003-11-24 01:14:38 stephena Exp $ + @version $Id: Settings.hxx,v 1.12 2004-04-21 16:27:18 stephena Exp $ */ class Settings { @@ -51,12 +51,12 @@ class Settings /** This method should be called to load the current settings from an rc file. */ - void loadConfig(); + virtual void loadConfig(); /** This method should be called to save the current settings to an rc file. */ - void saveConfig(); + virtual void saveConfig(); /** This method should be called to load the arguments from the commandline. @@ -233,17 +233,7 @@ class Settings // The full pathname of the settings file for output string mySettingsOutputFilename; - - private: - // Copy constructor isn't supported by this class so make it private - Settings(const Settings&); - - // Assignment operator isn't supported by this class so make it private - Settings& operator = (const Settings&); - - // Test whether the given setting is present in the array - bool contains(const string& key); - + // Structure used for storing settings struct Setting { @@ -255,11 +245,22 @@ class Settings // Pointer to a dynamically allocated array of settings Setting* mySettings; - // Current capacity of the settings array - unsigned int myCapacity; - // Size of the settings array (i.e. the number of pairs) unsigned int mySize; + + // Test whether the given setting is present in the array + bool contains(const string& key); + + + private: + // Copy constructor isn't supported by this class so make it private + Settings(const Settings&); + + // Assignment operator isn't supported by this class so make it private + Settings& operator = (const Settings&); + + // Current capacity of the settings array + unsigned int myCapacity; }; #endif diff --git a/stella/src/emucore/TIA.cxx b/stella/src/emucore/TIA.cxx index 281162cd3..a19445855 100644 --- a/stella/src/emucore/TIA.cxx +++ b/stella/src/emucore/TIA.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: TIA.cxx,v 1.29 2004-04-20 21:07:47 stephena Exp $ +// $Id: TIA.cxx,v 1.30 2004-04-21 16:27:30 stephena Exp $ //============================================================================ #include @@ -1637,7 +1637,7 @@ inline void TIA::updateFrameScanline(uInt32 clocksToUpdate, uInt32 hpos) myFramePointer = ending; // Add sound bytes to the sound queue every scanline - mySound.update(); //FIXME + mySound.update(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -3126,14 +3126,144 @@ const uInt32 TIA::ourPALPalette11[256] = { 0x000000, 0x000000, 0x242424, 0x242424, 0x484848, 0x484848, 0x6d6d6d, 0x6d6d6d, 0x919191, 0x919191, 0xb6b6b6, 0xb6b6b6, - 0xdadada, 0xdadada, 0xffffff, 0xffffff + 0xdadada, 0xdadada, 0xffffff, 0xff4ffff // FIXME - check this out }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt32 TIA::ourNTSCPaletteZ26[256] = { 0 }; // FIXME - +const uInt32 TIA::ourNTSCPaletteZ26[256] = { + 0x000000, 0x000000, 0x505050, 0x505050, + 0x646464, 0x646464, 0x787878, 0x787878, + 0x8c8c8c, 0x8c8c8c, 0xa0a0a0, 0xa0a0a0, + 0xb4b4b4, 0xb4b4b4, 0xc8c8c8, 0xc8c8c8, + 0x445400, 0x445400, 0x586800, 0x586800, + 0x6c7c00, 0x6c7c00, 0x809000, 0x809000, + 0x94a414, 0x94a414, 0xa8b828, 0xa8b828, + 0xbccc3c, 0xbccc3c, 0xd0e050, 0xd0e050, + 0x673900, 0x673900, 0x7b4d00, 0x7b4d00, + 0x8f6100, 0x8f6100, 0xa37513, 0xa37513, + 0xb78927, 0xb78927, 0xcb9d3b, 0xcb9d3b, + 0xdfb14f, 0xdfb14f, 0xf3c563, 0xf3c563, + 0x7b2504, 0x7b2504, 0x8f3918, 0x8f3918, + 0xa34d2c, 0xa34d2c, 0xb76140, 0xb76140, + 0xcb7554, 0xcb7554, 0xdf8968, 0xdf8968, + 0xf39d7c, 0xf39d7c, 0xffb190, 0xffb190, + 0x7d122c, 0x7d122c, 0x912640, 0x912640, + 0xa53a54, 0xa53a54, 0xb94e68, 0xb94e68, + 0xcd627c, 0xcd627c, 0xe17690, 0xe17690, + 0xf58aa4, 0xf58aa4, 0xff9eb8, 0xff9eb8, + 0x730871, 0x730871, 0x871c85, 0x871c85, + 0x9b3099, 0x9b3099, 0xaf44ad, 0xaf44ad, + 0xc358c1, 0xc358c1, 0xd76cd5, 0xd76cd5, + 0xeb80e9, 0xeb80e9, 0xff94fd, 0xff94fd, + 0x5d0b92, 0x5d0b92, 0x711fa6, 0x711fa6, + 0x8533ba, 0x8533ba, 0x9947ce, 0x9947ce, + 0xad5be2, 0xad5be2, 0xc16ff6, 0xc16ff6, + 0xd583ff, 0xd583ff, 0xe997ff, 0xe997ff, + 0x401599, 0x401599, 0x5429ad, 0x5429ad, + 0x683dc1, 0x683dc1, 0x7c51d5, 0x7c51d5, + 0x9065e9, 0x9065e9, 0xa479fd, 0xa479fd, + 0xb88dff, 0xb88dff, 0xcca1ff, 0xcca1ff, + 0x252593, 0x252593, 0x3939a7, 0x3939a7, + 0x4d4dbb, 0x4d4dbb, 0x6161cf, 0x6161cf, + 0x7575e3, 0x7575e3, 0x8989f7, 0x8989f7, + 0x9d9dff, 0x9d9dff, 0xb1b1ff, 0xb1b1ff, + 0x0f3480, 0x0f3480, 0x234894, 0x234894, + 0x375ca8, 0x375ca8, 0x4b70bc, 0x4b70bc, + 0x5f84d0, 0x5f84d0, 0x7398e4, 0x7398e4, + 0x87acf8, 0x87acf8, 0x9bc0ff, 0x9bc0ff, + 0x04425a, 0x04425a, 0x18566e, 0x18566e, + 0x2c6a82, 0x2c6a82, 0x407e96, 0x407e96, + 0x5492aa, 0x5492aa, 0x68a6be, 0x68a6be, + 0x7cbad2, 0x7cbad2, 0x90cee6, 0x90cee6, + 0x044f30, 0x044f30, 0x186344, 0x186344, + 0x2c7758, 0x2c7758, 0x408b6c, 0x408b6c, + 0x549f80, 0x549f80, 0x68b394, 0x68b394, + 0x7cc7a8, 0x7cc7a8, 0x90dbbc, 0x90dbbc, + 0x0f550a, 0x0f550a, 0x23691e, 0x23691e, + 0x377d32, 0x377d32, 0x4b9146, 0x4b9146, + 0x5fa55a, 0x5fa55a, 0x73b96e, 0x73b96e, + 0x87cd82, 0x87cd82, 0x9be196, 0x9be196, + 0x1f5100, 0x1f5100, 0x336505, 0x336505, + 0x477919, 0x477919, 0x5b8d2d, 0x5b8d2d, + 0x6fa141, 0x6fa141, 0x83b555, 0x83b555, + 0x97c969, 0x97c969, 0xabdd7d, 0xabdd7d, + 0x344600, 0x344600, 0x485a00, 0x485a00, + 0x5c6e14, 0x5c6e14, 0x708228, 0x708228, + 0x84963c, 0x84963c, 0x98aa50, 0x98aa50, + 0xacbe64, 0xacbe64, 0xc0d278, 0xc0d278, + 0x463e00, 0x463e00, 0x5a5205, 0x5a5205, + 0x6e6619, 0x6e6619, 0x827a2d, 0x827a2d, + 0x968e41, 0x968e41, 0xaaa255, 0xaaa255, + 0xbeb669, 0xbeb669, 0xd2ca7d, 0xd2ca7d +}; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const uInt32 TIA::ourPALPaletteZ26[256] = { 0 }; // FIXME +const uInt32 TIA::ourPALPaletteZ26[256] = { + 0x000000, 0x000000, 0x4c4c4c, 0x4c4c4c, + 0x606060, 0x606060, 0x747474, 0x747474, + 0x888888, 0x888888, 0x9c9c9c, 0x9c9c9c, + 0xb0b0b0, 0xb0b0b0, 0xc4c4c4, 0xc4c4c4, + 0x000000, 0x000000, 0x4c4c4c, 0x4c4c4c, + 0x606060, 0x606060, 0x747474, 0x747474, + 0x888888, 0x888888, 0x9c9c9c, 0x9c9c9c, + 0xb0b0b0, 0xb0b0b0, 0xc4c4c4, 0xc4c4c4, + 0x533a00, 0x533a00, 0x674e00, 0x674e00, + 0x7b6203, 0x7b6203, 0x8f7617, 0x8f7617, + 0xa38a2b, 0xa38a2b, 0xb79e3f, 0xb79e3f, + 0xcbb253, 0xcbb253, 0xdfc667, 0xdfc667, + 0x1b5800, 0x1b5800, 0x2f6c00, 0x2f6c00, + 0x438001, 0x438001, 0x579415, 0x579415, + 0x6ba829, 0x6ba829, 0x7fbc3d, 0x7fbc3d, + 0x93d051, 0x93d051, 0xa7e465, 0xa7e465, + 0x6a2900, 0x6a2900, 0x7e3d12, 0x7e3d12, + 0x925126, 0x925126, 0xa6653a, 0xa6653a, + 0xba794e, 0xba794e, 0xce8d62, 0xce8d62, + 0xe2a176, 0xe2a176, 0xf6b58a, 0xf6b58a, + 0x075b00, 0x075b00, 0x1b6f11, 0x1b6f11, + 0x2f8325, 0x2f8325, 0x439739, 0x439739, + 0x57ab4d, 0x57ab4d, 0x6bbf61, 0x6bbf61, + 0x7fd375, 0x7fd375, 0x93e789, 0x93e789, + 0x741b2f, 0x741b2f, 0x882f43, 0x882f43, + 0x9c4357, 0x9c4357, 0xb0576b, 0xb0576b, + 0xc46b7f, 0xc46b7f, 0xd87f93, 0xd87f93, + 0xec93a7, 0xec93a7, 0xffa7bb, 0xffa7bb, + 0x00572e, 0x00572e, 0x106b42, 0x106b42, + 0x247f56, 0x247f56, 0x38936a, 0x38936a, + 0x4ca77e, 0x4ca77e, 0x60bb92, 0x60bb92, + 0x74cfa6, 0x74cfa6, 0x88e3ba, 0x88e3ba, + 0x6d165f, 0x6d165f, 0x812a73, 0x812a73, + 0x953e87, 0x953e87, 0xa9529b, 0xa9529b, + 0xbd66af, 0xbd66af, 0xd17ac3, 0xd17ac3, + 0xe58ed7, 0xe58ed7, 0xf9a2eb, 0xf9a2eb, + 0x014c5e, 0x014c5e, 0x156072, 0x156072, + 0x297486, 0x297486, 0x3d889a, 0x3d889a, + 0x519cae, 0x519cae, 0x65b0c2, 0x65b0c2, + 0x79c4d6, 0x79c4d6, 0x8dd8ea, 0x8dd8ea, + 0x5f1588, 0x5f1588, 0x73299c, 0x73299c, + 0x873db0, 0x873db0, 0x9b51c4, 0x9b51c4, + 0xaf65d8, 0xaf65d8, 0xc379ec, 0xc379ec, + 0xd78dff, 0xd78dff, 0xeba1ff, 0xeba1ff, + 0x123b87, 0x123b87, 0x264f9b, 0x264f9b, + 0x3a63af, 0x3a63af, 0x4e77c3, 0x4e77c3, + 0x628bd7, 0x628bd7, 0x769feb, 0x769feb, + 0x8ab3ff, 0x8ab3ff, 0x9ec7ff, 0x9ec7ff, + 0x451e9d, 0x451e9d, 0x5932b1, 0x5932b1, + 0x6d46c5, 0x6d46c5, 0x815ad9, 0x815ad9, + 0x956eed, 0x956eed, 0xa982ff, 0xa982ff, + 0xbd96ff, 0xbd96ff, 0xd1aaff, 0xd1aaff, + 0x2a2b9e, 0x2a2b9e, 0x3e3fb2, 0x3e3fb2, + 0x5253c6, 0x5253c6, 0x6667da, 0x6667da, + 0x7a7bee, 0x7a7bee, 0x8e8fff, 0x8e8fff, + 0xa2a3ff, 0xa2a3ff, 0xb6b7ff, 0xb6b7ff, + 0x000000, 0x000000, 0x4c4c4c, 0x4c4c4c, + 0x606060, 0x606060, 0x747474, 0x747474, + 0x888888, 0x888888, 0x9c9c9c, 0x9c9c9c, + 0xb0b0b0, 0xb0b0b0, 0xc4c4c4, 0xc4c4c4, + 0x000000, 0x000000, 0x4c4c4c, 0x4c4c4c, + 0x606060, 0x606060, 0x747474, 0x747474, + 0x888888, 0x888888, 0x9c9c9c, 0x9c9c9c, + 0xb0b0b0, 0xb0b0b0, 0xc4c4c4, 0xc4c4c4 +}; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TIA::TIA(const TIA& c) diff --git a/stella/src/emucore/TIASound.c b/stella/src/emucore/TIASound.c index 076bbd4d4..3b5859e9e 100644 --- a/stella/src/emucore/TIASound.c +++ b/stella/src/emucore/TIASound.c @@ -1,667 +1,670 @@ -/*****************************************************************************/ -/* */ -/* Module: TIA Chip Sound Simulator */ -/* Purpose: To emulate the sound generation hardware of the Atari TIA chip. */ -/* Author: Ron Fries */ -/* */ -/* Revision History: */ -/* 10-Sep-96 - V1.0 - Initial Release */ -/* 14-Jan-97 - V1.1 - Cleaned up sound output by eliminating counter */ -/* reset. */ -/* */ -/*****************************************************************************/ -/* */ -/* License Information and Copyright Notice */ -/* ======================================== */ -/* */ -/* TiaSound is Copyright(c) 1996 by Ron Fries */ -/* */ -/* This library is free software; you can redistribute it and/or modify it */ -/* under the terms of version 2 of the GNU Library General Public License */ -/* as published by the Free Software Foundation. */ -/* */ -/* This library 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 Library */ -/* General Public License for more details. */ -/* To obtain a copy of the GNU Library General Public License, write to the */ -/* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* */ -/* Any permitted reproduction of these routines, in whole or in part, must */ -/* bear this legend. */ -/* */ -/*****************************************************************************/ - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include - - -/* define some data types to keep it platform independent */ -#ifdef WIN32 -#define int8 char -#define int16 short -#define int32 int -#else -#define int8 char -#define int16 int -#define int32 long -#endif - -#define uint8 unsigned int8 -#define uint16 unsigned int16 -#define uint32 unsigned int32 - - -/* CONSTANT DEFINITIONS */ - -/* definitions for AUDCx (15, 16) */ -#define SET_TO_1 0x00 /* 0000 */ -#define POLY4 0x01 /* 0001 */ -#define DIV31_POLY4 0x02 /* 0010 */ -#define POLY5_POLY4 0x03 /* 0011 */ -#define PURE 0x04 /* 0100 */ -#define PURE2 0x05 /* 0101 */ -#define DIV31_PURE 0x06 /* 0110 */ -#define POLY5_2 0x07 /* 0111 */ -#define POLY9 0x08 /* 1000 */ -#define POLY5 0x09 /* 1001 */ -#define DIV31_POLY5 0x0a /* 1010 */ -#define POLY5_POLY5 0x0b /* 1011 */ -#define DIV3_PURE 0x0c /* 1100 */ -#define DIV3_PURE2 0x0d /* 1101 */ -#define DIV93_PURE 0x0e /* 1110 */ -#define DIV3_POLY5 0x0f /* 1111 */ - -#define DIV3_MASK 0x0c - -#define AUDC0 0x15 -#define AUDC1 0x16 -#define AUDF0 0x17 -#define AUDF1 0x18 -#define AUDV0 0x19 -#define AUDV1 0x1a - -/* the size (in entries) of the 4 polynomial tables */ -#define POLY4_SIZE 0x000f -#define POLY5_SIZE 0x001f -#define POLY9_SIZE 0x01ff - -/* channel definitions */ -#define CHAN1 0 -#define CHAN2 1 - -#define FALSE 0 -#define TRUE 1 - - -/* LOCAL GLOBAL VARIABLE DEFINITIONS */ - -/* structures to hold the 6 tia sound control bytes */ -static uint8 AUDC[2]; /* AUDCx (15, 16) */ -static uint8 AUDF[2]; /* AUDFx (17, 18) */ -static uint8 AUDV[2]; /* AUDVx (19, 1A) */ - -static uint8 Outvol[2]; /* last output volume for each channel */ - - -/* Initialze the bit patterns for the polynomials. */ - -/* The 4bit and 5bit patterns are the identical ones used in the tia chip. */ -/* Though the patterns could be packed with 8 bits per byte, using only a */ -/* single bit per byte keeps the math simple, which is important for */ -/* efficient processing. */ - -static uint8 Bit4[POLY4_SIZE] = - { 1,1,0,1,1,1,0,0,0,0,1,0,1,0,0 }; - -static uint8 Bit5[POLY5_SIZE] = - { 0,0,1,0,1,1,0,0,1,1,1,1,1,0,0,0,1,1,0,1,1,1,0,1,0,1,0,0,0,0,1 }; - -/* I've treated the 'Div by 31' counter as another polynomial because of */ -/* the way it operates. It does not have a 50% duty cycle, but instead */ -/* has a 13:18 ratio (of course, 13+18 = 31). This could also be */ -/* implemented by using counters. */ - -static uint8 Div31[POLY5_SIZE] = - { 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0 }; - -/* Rather than have a table with 511 entries, I use a random number */ -/* generator. */ - -static uint8 Bit9[POLY9_SIZE]; - -static uint8 P4[2]; /* Position pointer for the 4-bit POLY array */ -static uint8 P5[2]; /* Position pointer for the 5-bit POLY array */ -static uint16 P9[2]; /* Position pointer for the 9-bit POLY array */ - -static uint8 Div_n_cnt[2]; /* Divide by n counter. one for each channel */ -static uint8 Div_n_max[2]; /* Divide by n maximum, one for each channel */ - - -/* In my routines, I treat the sample output as another divide by N counter. */ -/* For better accuracy, the Samp_n_cnt has a fixed binary decimal point */ -/* which has 8 binary digits to the right of the decimal point. */ - -static uint16 Samp_n_max; /* Sample max, multiplied by 256 */ -static uint16 Samp_n_cnt; /* Sample cnt. */ - - - -/*****************************************************************************/ -/* Module: Tia_sound_init() */ -/* Purpose: to handle the power-up initialization functions */ -/* these functions should only be executed on a cold-restart */ -/* */ -/* Author: Ron Fries */ -/* Date: September 10, 1996 */ -/* */ -/* Inputs: sample_freq - the value for the '30 Khz' Tia audio clock */ -/* playback_freq - the playback frequency in samples per second */ -/* */ -/* Outputs: Adjusts local globals - no return value */ -/* */ -/*****************************************************************************/ - -void Tia_sound_init (uint16 sample_freq, uint16 playback_freq) -{ - uint8 chan; - int16 n; - - /* fill the 9bit polynomial with random bits */ - for (n=0; n 1) - { - /* decrement and loop */ - Div_n_cnt[chan]--; - } - /* otherwise if we've reached the bottom */ - else if (Div_n_cnt[chan] == 1) - { - /* reset the counter */ - Div_n_cnt[chan] = Div_n_max[chan]; - - /* the P5 counter has multiple uses, so we inc it here */ - P5[chan]++; - if (P5[chan] == POLY5_SIZE) - P5[chan] = 0; - - /* check clock modifier for clock tick */ - - /* if we're using pure tones OR - we're using DIV31 and the DIV31 bit is set OR - we're using POLY5 and the POLY5 bit is set */ - if (((AUDC[chan] & 0x02) == 0) || - (((AUDC[chan] & 0x01) == 0) && Div31[P5[chan]]) || - (((AUDC[chan] & 0x01) == 1) && Bit5[P5[chan]])) - { - if (AUDC[chan] & 0x04) /* pure modified clock selected */ - { - if (Outvol[chan]) /* if the output was set */ - Outvol[chan] = 0; /* turn it off */ - else - Outvol[chan] = AUDV[chan]; /* else turn it on */ - } - else if (AUDC[chan] & 0x08) /* check for p5/p9 */ - { - if (AUDC[chan] == POLY9) /* check for poly9 */ - { - /* inc the poly9 counter */ - P9[chan]++; - if (P9[chan] == POLY9_SIZE) - P9[chan] = 0; - - if (Bit9[P9[chan]]) /* if poly9 bit is set */ - Outvol[chan] = AUDV[chan]; - else - Outvol[chan] = 0; - } - else /* must be poly5 */ - { - if (Bit5[P5[chan]]) - Outvol[chan] = AUDV[chan]; - else - Outvol[chan] = 0; - } - } - else /* poly4 is the only remaining option */ - { - /* inc the poly4 counter */ - P4[chan]++; - if (P4[chan] == POLY4_SIZE) - P4[chan] = 0; - - if (Bit4[P4[chan]]) - Outvol[chan] = AUDV[chan]; - else - Outvol[chan] = 0; - } - } - } - } - - /* decrement the sample counter - value is 256 since the lower - byte contains the fractional part */ - Samp_n_cnt -= 256; - - /* if the count down has reached zero */ - if (Samp_n_cnt < 256) - { - /* adjust the sample counter */ - Samp_n_cnt += Samp_n_max; - - /* calculate the latest output value and place in buffer */ - *(buffer++) = Outvol[0] + Outvol[1]; - - /* and indicate one less byte to process */ - n--; - } - } -} - - -/*****************************************************************************/ -/* Module: Tia_process() */ -/* Purpose: To fill the output buffer with the sound output based on the */ -/* tia chip parameters. This routine has been optimized. */ -/* */ -/* Author: Ron Fries */ -/* Date: September 10, 1996 */ -/* */ -/* Inputs: *buffer - pointer to the buffer where the audio output will */ -/* be placed */ -/* n - size of the playback buffer */ -/* */ -/* Outputs: the buffer will be filled with n bytes of audio - no return val */ -/* */ -/*****************************************************************************/ - -void Tia_process (register unsigned char *buffer, register uint16 n) -{ - register uint8 audc0,audv0,audc1,audv1; - register uint8 div_n_cnt0,div_n_cnt1; - register uint8 p5_0, p5_1,outvol_0,outvol_1; - - audc0 = AUDC[0]; - audv0 = AUDV[0]; - audc1 = AUDC[1]; - audv1 = AUDV[1]; - - /* make temporary local copy */ - p5_0 = P5[0]; - p5_1 = P5[1]; - outvol_0 = Outvol[0]; - outvol_1 = Outvol[1]; - div_n_cnt0 = Div_n_cnt[0]; - div_n_cnt1 = Div_n_cnt[1]; - - /* loop until the buffer is filled */ - while (n) - { - /* Process channel 0 */ - if (div_n_cnt0 > 1) - { - div_n_cnt0--; - } - else if (div_n_cnt0 == 1) - { - div_n_cnt0 = Div_n_max[0]; - - /* the P5 counter has multiple uses, so we inc it here */ - p5_0++; - if (p5_0 == POLY5_SIZE) - p5_0 = 0; - - /* check clock modifier for clock tick */ - if (((audc0 & 0x02) == 0) || - (((audc0 & 0x01) == 0) && Div31[p5_0]) || - (((audc0 & 0x01) == 1) && Bit5[p5_0])) - { - if (audc0 & 0x04) /* pure modified clock selected */ - { - if (outvol_0) /* if the output was set */ - outvol_0 = 0; /* turn it off */ - else - outvol_0 = audv0; /* else turn it on */ - } - else if (audc0 & 0x08) /* check for p5/p9 */ - { - if (audc0 == POLY9) /* check for poly9 */ - { - /* inc the poly9 counter */ - P9[0]++; - if (P9[0] == POLY9_SIZE) - P9[0] = 0; - - if (Bit9[P9[0]]) - outvol_0 = audv0; - else - outvol_0 = 0; - } - else /* must be poly5 */ - { - if (Bit5[p5_0]) - outvol_0 = audv0; - else - outvol_0 = 0; - } - } - else /* poly4 is the only remaining option */ - { - /* inc the poly4 counter */ - P4[0]++; - if (P4[0] == POLY4_SIZE) - P4[0] = 0; - - if (Bit4[P4[0]]) - outvol_0 = audv0; - else - outvol_0 = 0; - } - } - } - - - /* Process channel 1 */ - if (div_n_cnt1 > 1) - { - div_n_cnt1--; - } - else if (div_n_cnt1 == 1) - { - div_n_cnt1 = Div_n_max[1]; - - /* the P5 counter has multiple uses, so we inc it here */ - p5_1++; - if (p5_1 == POLY5_SIZE) - p5_1 = 0; - - /* check clock modifier for clock tick */ - if (((audc1 & 0x02) == 0) || - (((audc1 & 0x01) == 0) && Div31[p5_1]) || - (((audc1 & 0x01) == 1) && Bit5[p5_1])) - { - if (audc1 & 0x04) /* pure modified clock selected */ - { - if (outvol_1) /* if the output was set */ - outvol_1 = 0; /* turn it off */ - else - outvol_1 = audv1; /* else turn it on */ - } - else if (audc1 & 0x08) /* check for p5/p9 */ - { - if (audc1 == POLY9) /* check for poly9 */ - { - /* inc the poly9 counter */ - P9[1]++; - if (P9[1] == POLY9_SIZE) - P9[1] = 0; - - if (Bit9[P9[1]]) - outvol_1 = audv1; - else - outvol_1 = 0; - } - else /* must be poly5 */ - { - if (Bit5[p5_1]) - outvol_1 = audv1; - else - outvol_1 = 0; - } - } - else /* poly4 is the only remaining option */ - { - /* inc the poly4 counter */ - P4[1]++; - if (P4[1] == POLY4_SIZE) - P4[1] = 0; - - if (Bit4[P4[1]]) - outvol_1 = audv1; - else - outvol_1 = 0; - } - } - } - - /* decrement the sample counter - value is 256 since the lower - byte contains the fractional part */ - Samp_n_cnt -= 256; - - /* if the count down has reached zero */ - if (Samp_n_cnt < 256) - { - /* adjust the sample counter */ - Samp_n_cnt += Samp_n_max; - - /* calculate the latest output value and place in buffer */ - *(buffer++) = outvol_0 + outvol_1; - - /* and indicate one less byte to process */ - n--; - } - } - - /* save for next round */ - P5[0] = p5_0; - P5[1] = p5_1; - Outvol[0] = outvol_0; - Outvol[1] = outvol_1; - Div_n_cnt[0] = div_n_cnt0; - Div_n_cnt[1] = div_n_cnt1; - -} - - -/*****************************************************************************/ -/* Module: Tia_get_registers() */ -/* Purpose: Returns the 6 TIA sound registers for use in state */ -/* loading and saving. */ -/* */ -/* Author: Stephen Anthony */ -/* Date: October 31, 2002 */ -/* */ -/* Inputs: reg .. reg6 - pointers to the variables where the registers */ -/* will be placed */ -/* */ -/*****************************************************************************/ - -void Tia_get_registers (unsigned char *reg1, unsigned char *reg2, unsigned char *reg3, - unsigned char *reg4, unsigned char *reg5, unsigned char *reg6) -{ - *reg1 = AUDC[0]; - *reg2 = AUDC[1]; - *reg3 = AUDF[0]; - *reg4 = AUDF[1]; - *reg5 = AUDV[0]; - *reg6 = AUDV[1]; -} - - -/*****************************************************************************/ -/* Module: Tia_set_registers() */ -/* Purpose: Sets the 6 TIA sound registers for use in state */ -/* loading and saving. */ -/* */ -/* Author: Stephen Anthony */ -/* Date: October 31, 2002 */ -/* */ -/* Inputs: reg .. reg6 - the registers to be set */ -/* */ -/*****************************************************************************/ - -void Tia_set_registers (unsigned char reg1, unsigned char reg2, unsigned char reg3, - unsigned char reg4, unsigned char reg5, unsigned char reg6) -{ - AUDC[0] = reg1; - AUDC[1] = reg2; - AUDF[0] = reg3; - AUDF[1] = reg4; - AUDV[0] = reg5; - AUDV[1] = reg6; -} - -#ifdef __cplusplus -} -#endif +/*****************************************************************************/ +/* */ +/* Module: TIA Chip Sound Simulator */ +/* Purpose: To emulate the sound generation hardware of the Atari TIA chip. */ +/* Author: Ron Fries */ +/* */ +/* Revision History: */ +/* 10-Sep-96 - V1.0 - Initial Release */ +/* 14-Jan-97 - V1.1 - Cleaned up sound output by eliminating counter */ +/* reset. */ +/* */ +/*****************************************************************************/ +/* */ +/* License Information and Copyright Notice */ +/* ======================================== */ +/* */ +/* TiaSound is Copyright(c) 1996 by Ron Fries */ +/* */ +/* This library is free software; you can redistribute it and/or modify it */ +/* under the terms of version 2 of the GNU Library General Public License */ +/* as published by the Free Software Foundation. */ +/* */ +/* This library 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 Library */ +/* General Public License for more details. */ +/* To obtain a copy of the GNU Library General Public License, write to the */ +/* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* */ +/* Any permitted reproduction of these routines, in whole or in part, must */ +/* bear this legend. */ +/* */ +/*****************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + + +/* define some data types to keep it platform independent */ +#ifdef WIN32 +#define int8 char +#define int16 short +#define int32 int +#else +#define int8 char +#define int16 int +#define int32 long +#endif + +#define uint8 unsigned int8 +#define uint16 unsigned int16 +#define uint32 unsigned int32 + + +/* CONSTANT DEFINITIONS */ + +/* definitions for AUDCx (15, 16) */ +#define SET_TO_1 0x00 /* 0000 */ +#define POLY4 0x01 /* 0001 */ +#define DIV31_POLY4 0x02 /* 0010 */ +#define POLY5_POLY4 0x03 /* 0011 */ +#define PURE 0x04 /* 0100 */ +#define PURE2 0x05 /* 0101 */ +#define DIV31_PURE 0x06 /* 0110 */ +#define POLY5_2 0x07 /* 0111 */ +#define POLY9 0x08 /* 1000 */ +#define POLY5 0x09 /* 1001 */ +#define DIV31_POLY5 0x0a /* 1010 */ +#define POLY5_POLY5 0x0b /* 1011 */ +#define DIV3_PURE 0x0c /* 1100 */ +#define DIV3_PURE2 0x0d /* 1101 */ +#define DIV93_PURE 0x0e /* 1110 */ +#define DIV3_POLY5 0x0f /* 1111 */ + +#define DIV3_MASK 0x0c + +#define AUDC0 0x15 +#define AUDC1 0x16 +#define AUDF0 0x17 +#define AUDF1 0x18 +#define AUDV0 0x19 +#define AUDV1 0x1a + +/* the size (in entries) of the 4 polynomial tables */ +#define POLY4_SIZE 0x000f +#define POLY5_SIZE 0x001f +#define POLY9_SIZE 0x01ff + +/* channel definitions */ +#define CHAN1 0 +#define CHAN2 1 + +#define FALSE 0 +#define TRUE 1 + + +/* LOCAL GLOBAL VARIABLE DEFINITIONS */ + +/* structures to hold the 6 tia sound control bytes */ +static uint8 AUDC[2]; /* AUDCx (15, 16) */ +static uint8 AUDF[2]; /* AUDFx (17, 18) */ +static uint8 AUDV[2]; /* AUDVx (19, 1A) */ + +static uint8 Outvol[2]; /* last output volume for each channel */ + + +/* Initialze the bit patterns for the polynomials. */ + +/* The 4bit and 5bit patterns are the identical ones used in the tia chip. */ +/* Though the patterns could be packed with 8 bits per byte, using only a */ +/* single bit per byte keeps the math simple, which is important for */ +/* efficient processing. */ + +static uint8 Bit4[POLY4_SIZE] = + { 1,1,0,1,1,1,0,0,0,0,1,0,1,0,0 }; + +static uint8 Bit5[POLY5_SIZE] = + { 0,0,1,0,1,1,0,0,1,1,1,1,1,0,0,0,1,1,0,1,1,1,0,1,0,1,0,0,0,0,1 }; + +/* I've treated the 'Div by 31' counter as another polynomial because of */ +/* the way it operates. It does not have a 50% duty cycle, but instead */ +/* has a 13:18 ratio (of course, 13+18 = 31). This could also be */ +/* implemented by using counters. */ + +static uint8 Div31[POLY5_SIZE] = + { 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0 }; + +/* Rather than have a table with 511 entries, I use a random number */ +/* generator. */ + +static uint8 Bit9[POLY9_SIZE]; + +static uint8 P4[2]; /* Position pointer for the 4-bit POLY array */ +static uint8 P5[2]; /* Position pointer for the 5-bit POLY array */ +static uint16 P9[2]; /* Position pointer for the 9-bit POLY array */ + +static uint8 Div_n_cnt[2]; /* Divide by n counter. one for each channel */ +static uint8 Div_n_max[2]; /* Divide by n maximum, one for each channel */ + + +/* In my routines, I treat the sample output as another divide by N counter. */ +/* For better accuracy, the Samp_n_cnt has a fixed binary decimal point */ +/* which has 8 binary digits to the right of the decimal point. */ + +static uint16 Samp_n_max; /* Sample max, multiplied by 256 */ +static uint16 Samp_n_cnt; /* Sample cnt. */ + + + +/*****************************************************************************/ +/* Module: Tia_sound_init() */ +/* Purpose: to handle the power-up initialization functions */ +/* these functions should only be executed on a cold-restart */ +/* */ +/* Author: Ron Fries */ +/* Date: September 10, 1996 */ +/* */ +/* Inputs: sample_freq - the value for the '30 Khz' Tia audio clock */ +/* playback_freq - the playback frequency in samples per second */ +/* */ +/* Outputs: Adjusts local globals - no return value */ +/* */ +/*****************************************************************************/ + +void Tia_sound_init (uint16 sample_freq, uint16 playback_freq) +{ + uint8 chan; + int16 n; + + /* fill the 9bit polynomial with random bits */ + for (n=0; n 1) + { + /* decrement and loop */ + Div_n_cnt[chan]--; + } + /* otherwise if we've reached the bottom */ + else if (Div_n_cnt[chan] == 1) + { + /* reset the counter */ + Div_n_cnt[chan] = Div_n_max[chan]; + + /* the P5 counter has multiple uses, so we inc it here */ + P5[chan]++; + if (P5[chan] == POLY5_SIZE) + P5[chan] = 0; + + /* check clock modifier for clock tick */ + + /* if we're using pure tones OR + we're using DIV31 and the DIV31 bit is set OR + we're using POLY5 and the POLY5 bit is set */ + if (((AUDC[chan] & 0x02) == 0) || + (((AUDC[chan] & 0x01) == 0) && Div31[P5[chan]]) || + (((AUDC[chan] & 0x01) == 1) && Bit5[P5[chan]])) + { + if (AUDC[chan] & 0x04) /* pure modified clock selected */ + { + if (Outvol[chan]) /* if the output was set */ + Outvol[chan] = 0; /* turn it off */ + else + Outvol[chan] = AUDV[chan]; /* else turn it on */ + } + else if (AUDC[chan] & 0x08) /* check for p5/p9 */ + { + if (AUDC[chan] == POLY9) /* check for poly9 */ + { + /* inc the poly9 counter */ + P9[chan]++; + if (P9[chan] == POLY9_SIZE) + P9[chan] = 0; + + if (Bit9[P9[chan]]) /* if poly9 bit is set */ + Outvol[chan] = AUDV[chan]; + else + Outvol[chan] = 0; + } + else /* must be poly5 */ + { + if (Bit5[P5[chan]]) + Outvol[chan] = AUDV[chan]; + else + Outvol[chan] = 0; + } + } + else /* poly4 is the only remaining option */ + { + /* inc the poly4 counter */ + P4[chan]++; + if (P4[chan] == POLY4_SIZE) + P4[chan] = 0; + + if (Bit4[P4[chan]]) + Outvol[chan] = AUDV[chan]; + else + Outvol[chan] = 0; + } + } + } + } + + /* decrement the sample counter - value is 256 since the lower + byte contains the fractional part */ + Samp_n_cnt -= 256; + + /* if the count down has reached zero */ + if (Samp_n_cnt < 256) + { + /* adjust the sample counter */ + Samp_n_cnt += Samp_n_max; + + /* calculate the latest output value and place in buffer */ + *(buffer++) = Outvol[0] + Outvol[1]; + + /* and indicate one less byte to process */ + n--; + } + } +} + + +/*****************************************************************************/ +/* Module: Tia_process() */ +/* Purpose: To fill the output buffer with the sound output based on the */ +/* tia chip parameters. This routine has been optimized. */ +/* */ +/* Author: Ron Fries */ +/* Date: September 10, 1996 */ +/* */ +/* Inputs: *buffer - pointer to the buffer where the audio output will */ +/* be placed */ +/* n - size of the playback buffer */ +/* */ +/* Outputs: the buffer will be filled with n bytes of audio - no return val */ +/* */ +/*****************************************************************************/ + +void Tia_process (register unsigned char *buffer, register uint16 n) +{ + register uint8 audc0,audv0,audc1,audv1; + register uint8 div_n_cnt0,div_n_cnt1; + register uint8 p5_0, p5_1,outvol_0,outvol_1; + + audc0 = AUDC[0]; + audv0 = AUDV[0]; + audc1 = AUDC[1]; + audv1 = AUDV[1]; + + /* make temporary local copy */ + p5_0 = P5[0]; + p5_1 = P5[1]; + outvol_0 = Outvol[0]; + outvol_1 = Outvol[1]; + div_n_cnt0 = Div_n_cnt[0]; + div_n_cnt1 = Div_n_cnt[1]; + + /* loop until the buffer is filled */ + while (n) + { + /* Process channel 0 */ + if (div_n_cnt0 > 1) + { + div_n_cnt0--; + } + else if (div_n_cnt0 == 1) + { + div_n_cnt0 = Div_n_max[0]; + + /* the P5 counter has multiple uses, so we inc it here */ + p5_0++; + if (p5_0 == POLY5_SIZE) + p5_0 = 0; + + /* check clock modifier for clock tick */ + if (((audc0 & 0x02) == 0) || + (((audc0 & 0x01) == 0) && Div31[p5_0]) || + (((audc0 & 0x01) == 1) && Bit5[p5_0])) + { + if (audc0 & 0x04) /* pure modified clock selected */ + { + if (outvol_0) /* if the output was set */ + outvol_0 = 0; /* turn it off */ + else + outvol_0 = audv0; /* else turn it on */ + } + else if (audc0 & 0x08) /* check for p5/p9 */ + { + if (audc0 == POLY9) /* check for poly9 */ + { + /* inc the poly9 counter */ + P9[0]++; + if (P9[0] == POLY9_SIZE) + P9[0] = 0; + + if (Bit9[P9[0]]) + outvol_0 = audv0; + else + outvol_0 = 0; + } + else /* must be poly5 */ + { + if (Bit5[p5_0]) + outvol_0 = audv0; + else + outvol_0 = 0; + } + } + else /* poly4 is the only remaining option */ + { + /* inc the poly4 counter */ + P4[0]++; + if (P4[0] == POLY4_SIZE) + P4[0] = 0; + + if (Bit4[P4[0]]) + outvol_0 = audv0; + else + outvol_0 = 0; + } + } + } + + + /* Process channel 1 */ + if (div_n_cnt1 > 1) + { + div_n_cnt1--; + } + else if (div_n_cnt1 == 1) + { + div_n_cnt1 = Div_n_max[1]; + + /* the P5 counter has multiple uses, so we inc it here */ + p5_1++; + if (p5_1 == POLY5_SIZE) + p5_1 = 0; + + /* check clock modifier for clock tick */ + if (((audc1 & 0x02) == 0) || + (((audc1 & 0x01) == 0) && Div31[p5_1]) || + (((audc1 & 0x01) == 1) && Bit5[p5_1])) + { + if (audc1 & 0x04) /* pure modified clock selected */ + { + if (outvol_1) /* if the output was set */ + outvol_1 = 0; /* turn it off */ + else + outvol_1 = audv1; /* else turn it on */ + } + else if (audc1 & 0x08) /* check for p5/p9 */ + { + if (audc1 == POLY9) /* check for poly9 */ + { + /* inc the poly9 counter */ + P9[1]++; + if (P9[1] == POLY9_SIZE) + P9[1] = 0; + + if (Bit9[P9[1]]) + outvol_1 = audv1; + else + outvol_1 = 0; + } + else /* must be poly5 */ + { + if (Bit5[p5_1]) + outvol_1 = audv1; + else + outvol_1 = 0; + } + } + else /* poly4 is the only remaining option */ + { + /* inc the poly4 counter */ + P4[1]++; + if (P4[1] == POLY4_SIZE) + P4[1] = 0; + + if (Bit4[P4[1]]) + outvol_1 = audv1; + else + outvol_1 = 0; + } + } + } + + /* decrement the sample counter - value is 256 since the lower + byte contains the fractional part */ + Samp_n_cnt -= 256; + + /* if the count down has reached zero */ + if (Samp_n_cnt < 256) + { + /* adjust the sample counter */ + Samp_n_cnt += Samp_n_max; + + /* calculate the latest output value and place in buffer */ +#ifdef MAC_OSX + *(buffer++) = (outvol_0 + outvol_1)/2 + 128; +#else + *(buffer++) = outvol_0 + outvol_1; +#endif + /* and indicate one less byte to process */ + n--; + } + } + + /* save for next round */ + P5[0] = p5_0; + P5[1] = p5_1; + Outvol[0] = outvol_0; + Outvol[1] = outvol_1; + Div_n_cnt[0] = div_n_cnt0; + Div_n_cnt[1] = div_n_cnt1; + +} + + +/*****************************************************************************/ +/* Module: Tia_get_registers() */ +/* Purpose: Returns the 6 TIA sound registers for use in state */ +/* loading and saving. */ +/* */ +/* Author: Stephen Anthony */ +/* Date: October 31, 2002 */ +/* */ +/* Inputs: reg .. reg6 - pointers to the variables where the registers */ +/* will be placed */ +/* */ +/*****************************************************************************/ + +void Tia_get_registers (unsigned char *reg1, unsigned char *reg2, unsigned char *reg3, + unsigned char *reg4, unsigned char *reg5, unsigned char *reg6) +{ + *reg1 = AUDC[0]; + *reg2 = AUDC[1]; + *reg3 = AUDF[0]; + *reg4 = AUDF[1]; + *reg5 = AUDV[0]; + *reg6 = AUDV[1]; +} + + +/*****************************************************************************/ +/* Module: Tia_set_registers() */ +/* Purpose: Sets the 6 TIA sound registers for use in state */ +/* loading and saving. */ +/* */ +/* Author: Stephen Anthony */ +/* Date: October 31, 2002 */ +/* */ +/* Inputs: reg .. reg6 - the registers to be set */ +/* */ +/*****************************************************************************/ + +void Tia_set_registers (unsigned char reg1, unsigned char reg2, unsigned char reg3, + unsigned char reg4, unsigned char reg5, unsigned char reg6) +{ + AUDC[0] = reg1; + AUDC[1] = reg2; + AUDF[0] = reg3; + AUDF[1] = reg4; + AUDV[0] = reg5; + AUDV[1] = reg6; +} + +#ifdef __cplusplus +} +#endif diff --git a/stella/src/ui/sdl/FrameBufferSDL.cxx b/stella/src/ui/sdl/FrameBufferSDL.cxx index 48aedd772..cff51c072 100644 --- a/stella/src/ui/sdl/FrameBufferSDL.cxx +++ b/stella/src/ui/sdl/FrameBufferSDL.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: FrameBufferSDL.cxx,v 1.12 2004-04-20 21:08:03 stephena Exp $ +// $Id: FrameBufferSDL.cxx,v 1.13 2004-04-21 16:27:34 stephena Exp $ //============================================================================ #include @@ -179,8 +179,7 @@ uInt32 FrameBufferSDL::maxWindowSizeForScreen() if(!x11Available) return 4; - /* Every UNIX except Darwin with Cocoa. */ -#if UNIX && (!__APPLE__) +#ifdef UNIX // Otherwise, lock the screen and get the width and height myWMInfo.info.x11.lock_func(); Display* theX11Display = myWMInfo.info.x11.display; @@ -221,6 +220,7 @@ void FrameBufferSDL::setWindowAttributes() name << "Stella: \"" << myConsole->properties().get("Cartridge.Name") << "\""; SDL_WM_SetCaption(name.str().c_str(), "stella"); +#ifndef MAC_OSX // Set the window icon uInt32 w, h, ncols, nbytes; uInt32 rgba[256], icon[32 * 32]; @@ -273,4 +273,5 @@ void FrameBufferSDL::setWindowAttributes() 32 * 4, 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000); SDL_WM_SetIcon(surface, (unsigned char *) mask); SDL_FreeSurface(surface); +#endif }