# HG changeset patch # User koda # Date 1352311340 0 # Node ID aac257b77842fa08476c5b2bdd9b5612a091f3e6 # Parent a3974abc62d306e44066e832c057a74b4b08ebf3 move stuff out of engine folder diff -r a3974abc62d3 -r aac257b77842 hedgewars/CMakeLists.txt --- a/hedgewars/CMakeLists.txt Wed Nov 07 16:16:03 2012 +0000 +++ b/hedgewars/CMakeLists.txt Wed Nov 07 18:02:20 2012 +0000 @@ -143,7 +143,7 @@ if(SDLMAIN_LIB MATCHES "SDLMAIN_LIB-NOTFOUND") include_directories(${SDL_INCLUDE_DIR}) - add_library (SDLmain STATIC SDLMain.m) + add_library (SDLmain STATIC sdlmain_osx/SDLMain.m) #add a dependency to the hwengine target set(engine_sources ${engine_sources} SDLmain) set(SDLMAIN_LIB "${LIBRARY_OUTPUT_PATH}/libSDLmain.a") @@ -205,11 +205,11 @@ set(pascal_flags "-dUSE_VIDEO_RECORDING" ${pascal_flags}) IF (WIN32) # there are some problems with linking our avwrapper as static lib, so link it as shared - add_library(avwrapper SHARED avwrapper.c) + add_library(avwrapper SHARED videorec/avwrapper.c) target_link_libraries(avwrapper ${FFMPEG_LIBRARIES}) install(PROGRAMS "${EXECUTABLE_OUTPUT_PATH}/${CMAKE_SHARED_LIBRARY_PREFIX}avwrapper${CMAKE_SHARED_LIBRARY_SUFFIX}" DESTINATION ${target_dir}) ELSE() - add_library(avwrapper STATIC avwrapper.c) + add_library(avwrapper STATIC videorec/avwrapper.c) set(pascal_flags "-k${FFMPEG_LIBAVCODEC}" "-k${FFMPEG_LIBAVFORMAT}" "-k${FFMPEG_LIBAVUTIL}" ${pascal_flags}) ENDIF() if(fpc_version LESS "020600") diff -r a3974abc62d3 -r aac257b77842 hedgewars/GL.h --- a/hedgewars/GL.h Wed Nov 07 16:16:03 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,3 +0,0 @@ -#pragma once - -#include diff -r a3974abc62d3 -r aac257b77842 hedgewars/Math.h --- a/hedgewars/Math.h Wed Nov 07 16:16:03 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -#pragma once - diff -r a3974abc62d3 -r aac257b77842 hedgewars/SDLMain.h --- a/hedgewars/SDLMain.h Wed Nov 07 16:16:03 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,16 +0,0 @@ -/* SDLMain.m - main entry point for our Cocoa-ized SDL app - Initial Version: Darrell Walisser - Non-NIB-Code & other changes: Max Horn - - Feel free to customize this file to suit your needs -*/ - -#ifndef _SDLMain_h_ -#define _SDLMain_h_ - -#import - -@interface SDLMain : NSObject -@end - -#endif /* _SDLMain_h_ */ diff -r a3974abc62d3 -r aac257b77842 hedgewars/SDLMain.m --- a/hedgewars/SDLMain.m Wed Nov 07 16:16:03 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,385 +0,0 @@ -/* SDLMain.m - main entry point for our Cocoa-ized SDL app - Initial Version: Darrell Walisser - Non-NIB-Code & other changes: Max Horn - - Feel free to customize this file to suit your needs -*/ - -#include "SDL.h" -#include "SDLMain.h" -#include /* for MAXPATHLEN */ -#include - -/* For some reaon, Apple removed setAppleMenu from the headers in 10.4, - but the method still is there and works. To avoid warnings, we declare - it ourselves here. */ -@interface NSApplication(SDL_Missing_Methods) -- (void)setAppleMenu:(NSMenu *)menu; -@end - -/* Use this flag to determine whether we use SDLMain.nib or not */ -#define SDL_USE_NIB_FILE 0 - -/* Use this flag to determine whether we use CPS (docking) or not */ -#define SDL_USE_CPS 1 -#ifdef SDL_USE_CPS -/* Portions of CPS.h */ -typedef struct CPSProcessSerNum -{ - UInt32 lo; - UInt32 hi; -} CPSProcessSerNum; - -extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); -extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); -extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); - -#endif /* SDL_USE_CPS */ - -static int gArgc; -static char **gArgv; -static BOOL gFinderLaunch; -static BOOL gCalledAppMainline = FALSE; - -static NSString *getApplicationName(void) -{ - const NSDictionary *dict; - NSString *appName = 0; - - /* Determine the application name */ - dict = (const NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); - if (dict) - appName = [dict objectForKey: @"CFBundleName"]; - - if (![appName length]) - appName = [[NSProcessInfo processInfo] processName]; - - return appName; -} - -#if SDL_USE_NIB_FILE -/* A helper category for NSString */ -@interface NSString (ReplaceSubString) -- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; -@end -#endif - -@interface SDLApplication : NSApplication -@end - -@implementation SDLApplication -/* Invoked from the Quit menu item */ -- (void)terminate:(id)sender -{ - /* Post a SDL_QUIT event */ - SDL_Event event; - event.type = SDL_QUIT; - SDL_PushEvent(&event); -} -@end - -/* The main class of the application, the application's delegate */ -@implementation SDLMain - -/* Set the working directory to the .app's parent directory */ -- (void) setupWorkingDirectory:(BOOL)shouldChdir -{ - if (shouldChdir) - { - char parentdir[MAXPATHLEN]; - CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); - if (CFURLGetFileSystemRepresentation(url2, 1, (UInt8 *)parentdir, MAXPATHLEN)) { - chdir(parentdir); /* chdir to the binary app's parent */ - } - CFRelease(url); - CFRelease(url2); - } -} - -#if SDL_USE_NIB_FILE - -/* Fix menu to contain the real app name instead of "SDL App" */ -- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName -{ - NSRange aRange; - NSEnumerator *enumerator; - NSMenuItem *menuItem; - - aRange = [[aMenu title] rangeOfString:@"SDL App"]; - if (aRange.length != 0) - [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]]; - - enumerator = [[aMenu itemArray] objectEnumerator]; - while ((menuItem = [enumerator nextObject])) - { - aRange = [[menuItem title] rangeOfString:@"SDL App"]; - if (aRange.length != 0) - [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]]; - if ([menuItem hasSubmenu]) - [self fixMenu:[menuItem submenu] withAppName:appName]; - } - [ aMenu sizeToFit ]; -} - -#else - -static void setApplicationMenu(void) -{ - /* warning: this code is very odd */ - NSMenu *appleMenu; - NSMenuItem *menuItem; - NSString *title; - NSString *appName; - - appName = getApplicationName(); - appleMenu = [[NSMenu alloc] initWithTitle:@""]; - - /* Add menu items */ - title = [@"About " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Hide " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; - - menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; - [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; - - [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Quit " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; - - - /* Put menu into the menubar */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; - [menuItem setSubmenu:appleMenu]; - [[NSApp mainMenu] addItem:menuItem]; - - /* Tell the application object that this is now the application menu */ - [NSApp setAppleMenu:appleMenu]; - - /* Finally give up our references to the objects */ - [appleMenu release]; - [menuItem release]; -} - -/* Create a window menu */ -static void setupWindowMenu(void) -{ - NSMenu *windowMenu; - NSMenuItem *windowMenuItem; - NSMenuItem *menuItem; - - windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; - - /* "Minimize" item */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; - [windowMenu addItem:menuItem]; - [menuItem release]; - - /* Put menu into the menubar */ - windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; - [windowMenuItem setSubmenu:windowMenu]; - [[NSApp mainMenu] addItem:windowMenuItem]; - - /* Tell the application object that this is now the window menu */ - [NSApp setWindowsMenu:windowMenu]; - - /* Finally give up our references to the objects */ - [windowMenu release]; - [windowMenuItem release]; -} - -/* Replacement for NSApplicationMain */ -static void CustomApplicationMain (int argc, char **argv) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - SDLMain *sdlMain; - - /* Ensure the application object is initialised */ - [SDLApplication sharedApplication]; - -#ifdef SDL_USE_CPS - { - CPSProcessSerNum PSN; - /* Tell the dock about us */ - if (!CPSGetCurrentProcess(&PSN)) - if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) - if (!CPSSetFrontProcess(&PSN)) - [SDLApplication sharedApplication]; - } -#endif /* SDL_USE_CPS */ - - /* Set up the menubar */ - NSMenu *menu = [[NSMenu alloc] init]; - [NSApp setMainMenu:menu]; - setApplicationMenu(); - setupWindowMenu(); - [menu release]; - - /* Create SDLMain and make it the app delegate */ - sdlMain = [[SDLMain alloc] init]; - [NSApp setDelegate:sdlMain]; - - /* Start the main event loop */ - [NSApp run]; - - [sdlMain release]; - [pool release]; -} - -#endif - - -/* - * Catch document open requests...this lets us notice files when the app - * was launched by double-clicking a document, or when a document was - * dragged/dropped on the app's icon. You need to have a - * CFBundleDocumentsType section in your Info.plist to get this message, - * apparently. - * - * Files are added to gArgv, so to the app, they'll look like command line - * arguments. Previously, apps launched from the finder had nothing but - * an argv[0]. - * - * This message may be received multiple times to open several docs on launch. - * - * This message is ignored once the app's mainline has been called. - */ -- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename -{ - const char *temparg; - size_t arglen; - char *arg; - char **newargv; - - if (!gFinderLaunch) /* MacOS is passing command line args. */ - return FALSE; - - if (gCalledAppMainline) /* app has started, ignore this document. */ - return FALSE; - - temparg = [filename UTF8String]; - arglen = SDL_strlen(temparg) + 1; - arg = (char *) SDL_malloc(arglen); - if (arg == NULL) - return FALSE; - - newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2)); - if (newargv == NULL) - { - SDL_free(arg); - return FALSE; - } - gArgv = newargv; - - SDL_strlcpy(arg, temparg, arglen); - gArgv[gArgc++] = arg; - gArgv[gArgc] = NULL; - return TRUE; -} - - -/* Called when the internal event loop has just started running */ -- (void) applicationDidFinishLaunching: (NSNotification *) note -{ - int status; - - /* Set the working directory to the .app's parent directory */ - [self setupWorkingDirectory:gFinderLaunch]; - -#if SDL_USE_NIB_FILE - /* Set the main menu to contain the real app name instead of "SDL App" */ - [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()]; -#endif - - /* Hand off to main application code */ - gCalledAppMainline = TRUE; - status = SDL_main (gArgc, gArgv); - - /* We're done, thank you for playing */ - exit(status); -} -@end - - -@implementation NSString (ReplaceSubString) - -- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString -{ - unsigned int bufferSize; - unsigned int selfLen = [self length]; - unsigned int aStringLen = [aString length]; - unichar *buffer; - NSRange localRange; - NSString *result; - - bufferSize = selfLen + aStringLen - aRange.length; - buffer = (unichar *)NSAllocateMemoryPages(bufferSize*sizeof(unichar)); - - /* Get first part into buffer */ - localRange.location = 0; - localRange.length = aRange.location; - [self getCharacters:buffer range:localRange]; - - /* Get middle part into buffer */ - localRange.location = 0; - localRange.length = aStringLen; - [aString getCharacters:(buffer+aRange.location) range:localRange]; - - /* Get last part into buffer */ - localRange.location = aRange.location + aRange.length; - localRange.length = selfLen - localRange.location; - [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange]; - - /* Build output string */ - result = [NSString stringWithCharacters:buffer length:bufferSize]; - - NSDeallocateMemoryPages(buffer, bufferSize); - - return result; -} - -@end - - - -#ifdef main -# undef main -#endif - - -/* Main entry point to executable - should *not* be SDL_main! */ -int main (int argc, char **argv) -{ - /* Copy the arguments into a global variable */ - /* This is passed if we are launched by double-clicking */ - if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { - gArgv = (char **) SDL_malloc(sizeof (char *) * 2); - gArgv[0] = argv[0]; - gArgv[1] = NULL; - gArgc = 1; - gFinderLaunch = YES; - } else { - int i; - gArgc = argc; - gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1)); - for (i = 0; i <= argc; i++) - gArgv[i] = argv[i]; - gFinderLaunch = NO; - } - -#if SDL_USE_NIB_FILE - [SDLApplication poseAsClass:[NSApplication class]]; - NSApplicationMain (argc, argv); -#else - CustomApplicationMain (argc, argv); -#endif - return 0; -} - diff -r a3974abc62d3 -r aac257b77842 hedgewars/SysUtils.h diff -r a3974abc62d3 -r aac257b77842 hedgewars/Types.h diff -r a3974abc62d3 -r aac257b77842 hedgewars/avwrapper.c --- a/hedgewars/avwrapper.c Wed Nov 07 16:16:03 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,515 +0,0 @@ -/* - * Hedgewars, a free turn based strategy game - * Copyright (c) 2004-2012 Andrey Korotaev - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include -#include -#include -#include -#include -#include "libavformat/avformat.h" - -#ifndef AVIO_FLAG_WRITE -#define AVIO_FLAG_WRITE AVIO_WRONLY -#endif - -static AVFormatContext* g_pContainer; -static AVOutputFormat* g_pFormat; -static AVStream* g_pAStream; -static AVStream* g_pVStream; -static AVFrame* g_pAFrame; -static AVFrame* g_pVFrame; -static AVCodec* g_pACodec; -static AVCodec* g_pVCodec; -static AVCodecContext* g_pAudio; -static AVCodecContext* g_pVideo; - -static int g_Width, g_Height; -static uint32_t g_Frequency, g_Channels; -static int g_VQuality; -static AVRational g_Framerate; - -static FILE* g_pSoundFile; -static int16_t* g_pSamples; -static int g_NumSamples; - -/* -Initially I wrote code for latest ffmpeg, but on Linux (Ubuntu) -only older version is available from repository. That's why you see here -all of this #if LIBAVCODEC_VERSION_MAJOR < 54. -Actually, it may be possible to remove code for newer version -and use only code for older version. -*/ - -#if LIBAVCODEC_VERSION_MAJOR < 54 -#define OUTBUFFER_SIZE 200000 -static uint8_t g_OutBuffer[OUTBUFFER_SIZE]; -#endif - -// pointer to function from hwengine (uUtils.pas) -static void (*AddFileLogRaw)(const char* pString); - -static void FatalError(const char* pFmt, ...) -{ - const char Buffer[1024]; - va_list VaArgs; - - va_start(VaArgs, pFmt); - vsnprintf(Buffer, 1024, pFmt, VaArgs); - va_end(VaArgs); - - AddFileLogRaw("Error in av-wrapper: "); - AddFileLogRaw(Buffer); - AddFileLogRaw("\n"); - exit(1); -} - -// Function to be called from libav for logging. -// Note: libav can call LogCallback from different threads -// (there is mutex in AddFileLogRaw). -static void LogCallback(void* p, int Level, const char* pFmt, va_list VaArgs) -{ - const char Buffer[1024]; - - vsnprintf(Buffer, 1024, pFmt, VaArgs); - AddFileLogRaw(Buffer); -} - -static void Log(const char* pFmt, ...) -{ - const char Buffer[1024]; - va_list VaArgs; - - va_start(VaArgs, pFmt); - vsnprintf(Buffer, 1024, pFmt, VaArgs); - va_end(VaArgs); - - AddFileLogRaw(Buffer); -} - -static void AddAudioStream() -{ -#if LIBAVFORMAT_VERSION_MAJOR >= 54 - g_pAStream = avformat_new_stream(g_pContainer, g_pACodec); -#else - g_pAStream = av_new_stream(g_pContainer, 1); -#endif - if(!g_pAStream) - { - Log("Could not allocate audio stream\n"); - return; - } - g_pAStream->id = 1; - - g_pAudio = g_pAStream->codec; - - avcodec_get_context_defaults3(g_pAudio, g_pACodec); - g_pAudio->codec_id = g_pACodec->id; - - // put parameters - g_pAudio->sample_fmt = AV_SAMPLE_FMT_S16; - g_pAudio->sample_rate = g_Frequency; - g_pAudio->channels = g_Channels; - - // set quality - g_pAudio->bit_rate = 160000; - - // for codecs that support variable bitrate use it, it should be better - g_pAudio->flags |= CODEC_FLAG_QSCALE; - g_pAudio->global_quality = 1*FF_QP2LAMBDA; - - // some formats want stream headers to be separate - if (g_pFormat->flags & AVFMT_GLOBALHEADER) - g_pAudio->flags |= CODEC_FLAG_GLOBAL_HEADER; - - // open it -#if LIBAVCODEC_VERSION_MAJOR >= 53 - if (avcodec_open2(g_pAudio, g_pACodec, NULL) < 0) -#else - if (avcodec_open(g_pAudio, g_pACodec) < 0) -#endif - { - Log("Could not open audio codec %s\n", g_pACodec->long_name); - return; - } - -#if LIBAVCODEC_VERSION_MAJOR >= 54 - if (g_pACodec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE) -#else - if (g_pAudio->frame_size == 0) -#endif - g_NumSamples = 4096; - else - g_NumSamples = g_pAudio->frame_size; - g_pSamples = (int16_t*)av_malloc(g_NumSamples*g_Channels*sizeof(int16_t)); - g_pAFrame = avcodec_alloc_frame(); - if (!g_pAFrame) - { - Log("Could not allocate frame\n"); - return; - } -} - -// returns non-zero if there is more sound -static int WriteAudioFrame() -{ - if (!g_pAStream) - return 0; - - AVPacket Packet = { 0 }; - av_init_packet(&Packet); - - int NumSamples = fread(g_pSamples, 2*g_Channels, g_NumSamples, g_pSoundFile); - -#if LIBAVCODEC_VERSION_MAJOR >= 54 - AVFrame* pFrame = NULL; - if (NumSamples > 0) - { - g_pAFrame->nb_samples = NumSamples; - avcodec_fill_audio_frame(g_pAFrame, g_Channels, AV_SAMPLE_FMT_S16, - (uint8_t*)g_pSamples, NumSamples*2*g_Channels, 1); - pFrame = g_pAFrame; - } - // when NumSamples == 0 we still need to call encode_audio2 to flush - int got_packet; - if (avcodec_encode_audio2(g_pAudio, &Packet, pFrame, &got_packet) != 0) - FatalError("avcodec_encode_audio2 failed"); - if (!got_packet) - return 0; -#else - if (NumSamples == 0) - return 0; - int BufferSize = OUTBUFFER_SIZE; - if (g_pAudio->frame_size == 0) - BufferSize = NumSamples*g_Channels*2; - Packet.size = avcodec_encode_audio(g_pAudio, g_OutBuffer, BufferSize, g_pSamples); - if (Packet.size == 0) - return 1; - if (g_pAudio->coded_frame && g_pAudio->coded_frame->pts != AV_NOPTS_VALUE) - Packet.pts = av_rescale_q(g_pAudio->coded_frame->pts, g_pAudio->time_base, g_pAStream->time_base); - Packet.flags |= AV_PKT_FLAG_KEY; - Packet.data = g_OutBuffer; -#endif - - // Write the compressed frame to the media file. - Packet.stream_index = g_pAStream->index; - if (av_interleaved_write_frame(g_pContainer, &Packet) != 0) - FatalError("Error while writing audio frame"); - return 1; -} - -// add a video output stream -static void AddVideoStream() -{ -#if LIBAVFORMAT_VERSION_MAJOR >= 54 - g_pVStream = avformat_new_stream(g_pContainer, g_pVCodec); -#else - g_pVStream = av_new_stream(g_pContainer, 0); -#endif - if (!g_pVStream) - FatalError("Could not allocate video stream"); - - g_pVideo = g_pVStream->codec; - - avcodec_get_context_defaults3(g_pVideo, g_pVCodec); - g_pVideo->codec_id = g_pVCodec->id; - - // put parameters - // resolution must be a multiple of two - g_pVideo->width = g_Width & ~1; // make even (dimensions should be even) - g_pVideo->height = g_Height & ~1; // make even - /* time base: this is the fundamental unit of time (in seconds) in terms - of which frame timestamps are represented. for fixed-fps content, - timebase should be 1/framerate and timestamp increments should be - identically 1. */ - g_pVideo->time_base.den = g_Framerate.num; - g_pVideo->time_base.num = g_Framerate.den; - //g_pVideo->gop_size = 12; /* emit one intra frame every twelve frames at most */ - g_pVideo->pix_fmt = PIX_FMT_YUV420P; - - // set quality - if (g_VQuality > 100) - g_pVideo->bit_rate = g_VQuality; - else - { - g_pVideo->flags |= CODEC_FLAG_QSCALE; - g_pVideo->global_quality = g_VQuality*FF_QP2LAMBDA; - } - - // some formats want stream headers to be separate - if (g_pFormat->flags & AVFMT_GLOBALHEADER) - g_pVideo->flags |= CODEC_FLAG_GLOBAL_HEADER; - -#if LIBAVCODEC_VERSION_MAJOR < 54 - // for some versions of ffmpeg x264 options must be set explicitly - if (strcmp(g_pVCodec->name, "libx264") == 0) - { - g_pVideo->coder_type = FF_CODER_TYPE_AC; - g_pVideo->flags |= CODEC_FLAG_LOOP_FILTER; - g_pVideo->crf = 23; - g_pVideo->thread_count = 3; - g_pVideo->me_cmp = FF_CMP_CHROMA; - g_pVideo->partitions = X264_PART_I8X8 | X264_PART_I4X4 | X264_PART_P8X8 | X264_PART_B8X8; - g_pVideo->me_method = ME_HEX; - g_pVideo->me_subpel_quality = 7; - g_pVideo->me_range = 16; - g_pVideo->gop_size = 250; - g_pVideo->keyint_min = 25; - g_pVideo->scenechange_threshold = 40; - g_pVideo->i_quant_factor = 0.71; - g_pVideo->b_frame_strategy = 1; - g_pVideo->qcompress = 0.6; - g_pVideo->qmin = 10; - g_pVideo->qmax = 51; - g_pVideo->max_qdiff = 4; - g_pVideo->max_b_frames = 3; - g_pVideo->refs = 3; - g_pVideo->directpred = 1; - g_pVideo->trellis = 1; - g_pVideo->flags2 = CODEC_FLAG2_BPYRAMID | CODEC_FLAG2_MIXED_REFS | CODEC_FLAG2_WPRED | CODEC_FLAG2_8X8DCT | CODEC_FLAG2_FASTPSKIP; - g_pVideo->weighted_p_pred = 2; - } -#endif - - // open the codec -#if LIBAVCODEC_VERSION_MAJOR >= 53 - AVDictionary* pDict = NULL; - if (strcmp(g_pVCodec->name, "libx264") == 0) - av_dict_set(&pDict, "preset", "medium", 0); - - if (avcodec_open2(g_pVideo, g_pVCodec, &pDict) < 0) -#else - if (avcodec_open(g_pVideo, g_pVCodec) < 0) -#endif - FatalError("Could not open video codec %s", g_pVCodec->long_name); - - g_pVFrame = avcodec_alloc_frame(); - if (!g_pVFrame) - FatalError("Could not allocate frame"); - - g_pVFrame->linesize[0] = g_Width; - g_pVFrame->linesize[1] = g_Width/2; - g_pVFrame->linesize[2] = g_Width/2; - g_pVFrame->linesize[3] = 0; -} - -static int WriteFrame(AVFrame* pFrame) -{ - double AudioTime, VideoTime; - - // write interleaved audio frame - if (g_pAStream) - { - VideoTime = (double)g_pVStream->pts.val*g_pVStream->time_base.num/g_pVStream->time_base.den; - do - AudioTime = (double)g_pAStream->pts.val*g_pAStream->time_base.num/g_pAStream->time_base.den; - while (AudioTime < VideoTime && WriteAudioFrame()); - } - - if (!g_pVStream) - return 0; - - AVPacket Packet; - av_init_packet(&Packet); - Packet.data = NULL; - Packet.size = 0; - - g_pVFrame->pts++; - if (g_pFormat->flags & AVFMT_RAWPICTURE) - { - /* raw video case. The API will change slightly in the near - future for that. */ - Packet.flags |= AV_PKT_FLAG_KEY; - Packet.stream_index = g_pVStream->index; - Packet.data = (uint8_t*)pFrame; - Packet.size = sizeof(AVPicture); - - if (av_interleaved_write_frame(g_pContainer, &Packet) != 0) - FatalError("Error while writing video frame"); - return 0; - } - else - { -#if LIBAVCODEC_VERSION_MAJOR >= 54 - int got_packet; - if (avcodec_encode_video2(g_pVideo, &Packet, pFrame, &got_packet) < 0) - FatalError("avcodec_encode_video2 failed"); - if (!got_packet) - return 0; - - if (Packet.pts != AV_NOPTS_VALUE) - Packet.pts = av_rescale_q(Packet.pts, g_pVideo->time_base, g_pVStream->time_base); - if (Packet.dts != AV_NOPTS_VALUE) - Packet.dts = av_rescale_q(Packet.dts, g_pVideo->time_base, g_pVStream->time_base); -#else - Packet.size = avcodec_encode_video(g_pVideo, g_OutBuffer, OUTBUFFER_SIZE, pFrame); - if (Packet.size < 0) - FatalError("avcodec_encode_video failed"); - if (Packet.size == 0) - return 0; - - if( g_pVideo->coded_frame->pts != AV_NOPTS_VALUE) - Packet.pts = av_rescale_q(g_pVideo->coded_frame->pts, g_pVideo->time_base, g_pVStream->time_base); - if( g_pVideo->coded_frame->key_frame ) - Packet.flags |= AV_PKT_FLAG_KEY; - Packet.data = g_OutBuffer; -#endif - // write the compressed frame in the media file - Packet.stream_index = g_pVStream->index; - if (av_interleaved_write_frame(g_pContainer, &Packet) != 0) - FatalError("Error while writing video frame"); - - return 1; - } -} - -void AVWrapper_WriteFrame(uint8_t* pY, uint8_t* pCb, uint8_t* pCr) -{ - g_pVFrame->data[0] = pY; - g_pVFrame->data[1] = pCb; - g_pVFrame->data[2] = pCr; - WriteFrame(g_pVFrame); -} - -void AVWrapper_Init( - void (*pAddFileLogRaw)(const char*), - const char* pFilename, - const char* pDesc, - const char* pSoundFile, - const char* pFormatName, - const char* pVCodecName, - const char* pACodecName, - int Width, int Height, - int FramerateNum, int FramerateDen, - int VQuality) -{ - AddFileLogRaw = pAddFileLogRaw; - av_log_set_callback( &LogCallback ); - - g_Width = Width; - g_Height = Height; - g_Framerate.num = FramerateNum; - g_Framerate.den = FramerateDen; - g_VQuality = VQuality; - - // initialize libav and register all codecs and formats - av_register_all(); - - // find format - g_pFormat = av_guess_format(pFormatName, NULL, NULL); - if (!g_pFormat) - FatalError("Format \"%s\" was not found", pFormatName); - - // allocate the output media context - g_pContainer = avformat_alloc_context(); - if (!g_pContainer) - FatalError("Could not allocate output context"); - - g_pContainer->oformat = g_pFormat; - - // store description of file - av_dict_set(&g_pContainer->metadata, "comment", pDesc, 0); - - // append extesnion to filename - char ext[16]; - strncpy(ext, g_pFormat->extensions, 16); - ext[15] = 0; - ext[strcspn(ext,",")] = 0; - snprintf(g_pContainer->filename, sizeof(g_pContainer->filename), "%s.%s", pFilename, ext); - - // find codecs - g_pVCodec = avcodec_find_encoder_by_name(pVCodecName); - g_pACodec = avcodec_find_encoder_by_name(pACodecName); - - // add audio and video stream to container - g_pVStream = NULL; - g_pAStream = NULL; - - if (g_pVCodec) - AddVideoStream(); - else - Log("Video codec \"%s\" was not found; video will be ignored.\n", pVCodecName); - - if (g_pACodec) - { - g_pSoundFile = fopen(pSoundFile, "rb"); - if (g_pSoundFile) - { - fread(&g_Frequency, 4, 1, g_pSoundFile); - fread(&g_Channels, 4, 1, g_pSoundFile); - AddAudioStream(); - } - else - Log("Could not open %s\n", pSoundFile); - } - else - Log("Audio codec \"%s\" was not found; audio will be ignored.\n", pACodecName); - - if (!g_pAStream && !g_pVStream) - FatalError("No video, no audio, aborting..."); - - // write format info to log - av_dump_format(g_pContainer, 0, g_pContainer->filename, 1); - - // open the output file, if needed - if (!(g_pFormat->flags & AVFMT_NOFILE)) - { - if (avio_open(&g_pContainer->pb, g_pContainer->filename, AVIO_FLAG_WRITE) < 0) - FatalError("Could not open output file (%s)", g_pContainer->filename); - } - - // write the stream header, if any - avformat_write_header(g_pContainer, NULL); - - g_pVFrame->pts = -1; -} - -void AVWrapper_Close() -{ - // output buffered frames - if (g_pVCodec->capabilities & CODEC_CAP_DELAY) - while( WriteFrame(NULL) ); - // output any remaining audio - while( WriteAudioFrame() ); - - // write the trailer, if any. - av_write_trailer(g_pContainer); - - // close the output file - if (!(g_pFormat->flags & AVFMT_NOFILE)) - avio_close(g_pContainer->pb); - - // free everything - if (g_pVStream) - { - avcodec_close(g_pVideo); - av_free(g_pVideo); - av_free(g_pVStream); - av_free(g_pVFrame); - } - if (g_pAStream) - { - avcodec_close(g_pAudio); - av_free(g_pAudio); - av_free(g_pAStream); - av_free(g_pAFrame); - av_free(g_pSamples); - fclose(g_pSoundFile); - } - - av_free(g_pContainer); -} diff -r a3974abc62d3 -r aac257b77842 hedgewars/hwengine.ico Binary file hedgewars/hwengine.ico has changed diff -r a3974abc62d3 -r aac257b77842 hedgewars/hwengine.pas --- a/hedgewars/hwengine.pas Wed Nov 07 16:16:03 2012 +0000 +++ b/hedgewars/hwengine.pas Wed Nov 07 18:02:20 2012 +0000 @@ -19,7 +19,7 @@ {$INCLUDE "options.inc"} {$IFDEF WIN32} -{$R hwengine.rc} +{$R res/hwengine.rc} {$ENDIF} {$IFDEF HWLIBRARY} diff -r a3974abc62d3 -r aac257b77842 hedgewars/hwengine.rc --- a/hedgewars/hwengine.rc Wed Nov 07 16:16:03 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -MAINICON ICON "hwengine.ico" \ No newline at end of file diff -r a3974abc62d3 -r aac257b77842 hedgewars/pas2c.h --- a/hedgewars/pas2c.h Wed Nov 07 16:16:03 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,144 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -typedef union string255_ - { - struct { - char s[256]; - }; - struct { - char len; - char str[255]; - }; - } string255; -typedef struct string192_ - { - char s[193]; - } string192; -typedef struct string31_ - { - char s[32]; - } string31; -typedef struct string15_ - { - char s[16]; - } string15; - -typedef string255 shortstring; -typedef string255 ansistring; - -typedef uint8_t Byte; -typedef int8_t ShortInt; -typedef uint16_t Word; -typedef int16_t SmallInt; -typedef uint32_t LongWord; -typedef int32_t LongInt; -typedef uint64_t QWord; -typedef int64_t Int64; -typedef LongWord Cardinal; - -typedef LongInt Integer; -typedef float extended; -typedef float real; -typedef float single; - -typedef bool boolean; -typedef int LongBool; - -typedef void * pointer; -typedef Byte * PByte; -typedef char * PChar; -typedef LongInt * PLongInt; -typedef LongWord * PLongWord; -typedef Integer * PInteger; -typedef int PtrInt; -typedef wchar_t widechar; - -#define new(a) __new((void **)&a, sizeof(*(a))) -void __new(void ** p, int size); -#define dispose(a) __dispose(a, sizeof(*(a))) -void __dispose(pointer p, int size); - -void * GetMem(int size); -void FreeMem(void * p, int size); - -#define FillChar(a, b, c) __FillChar(&(a), b, c) - -void __FillChar(pointer p, int size, char fill); -string255 _strconcat(string255 a, string255 b); -string255 _strappend(string255 s, char c); -string255 _strprepend(char c, string255 s); -string255 _chrconcat(char a, char b); -bool _strcompare(string255 a, string255 b); -bool _strcomparec(string255 a, char b); -bool _strncompare(string255 a, string255 b); -char * _pchar(string255 s); -string255 pchar2str(char * s); - -int Length(string255 a); -string255 copy(string255 a, int s, int l); -string255 delete(string255 a, int s, int l); -string255 trim(string255 a); - -#define STRINIT(a) {.len = sizeof(a) - 1, .str = a} - - -int length_ar(void * a); - -typedef int file; -typedef int TextFile; -extern int FileMode; -extern int IOResult; -extern int stdout; -extern int stderr; - -#define assign(a, b) assign_(&(a), b) -void assign_(int * f, string255 fileName); -void reset_1(int f, int size); -void reset_2(int f, int size); -#define BlockRead(a, b, c, d) BlockRead_(a, &(b), c, &(d)) -void BlockRead_(int f, void * p, int size, int * sizeRead); -#define BlockWrite(a, b, c) BlockWrite_(a, &(b), c) -void BlockWrite_(int f, void * p, int size); -void close(int f); - -void write(int f, string255 s); -void writeLn(int f, string255 s); - -bool DirectoryExists(string255 dir); -bool FileExists(string255 filename); - -bool odd(int i); - - -typedef int TThreadId; -void ThreadSwitch(); -#define InterlockedIncrement(a) __InterlockedIncrement(&(a)) -#define InterlockedDecrement(a) __InterlockedDecrement(&(a)) -void __InterlockedIncrement(int * a); -void __InterlockedDecrement(int * a); - -bool Assigned(void * a); - -void randomize(); -int random(int max); -int abs(int i); -double sqr(double n); -double sqrt(double n); -int trunc(double n); -int round(double n); - -string255 ParamStr(int n); -int ParamCount(); - -#define val(a, b, c) _val(a, (LongInt*)&(b), (LongInt*)&(c)) -void _val(string255 str, LongInt * a, LongInt * c); - -extern double pi; - -string255 EnumToStr(int a); -string255 ExtractFileName(string255 f); diff -r a3974abc62d3 -r aac257b77842 hedgewars/res/hwengine.ico Binary file hedgewars/res/hwengine.ico has changed diff -r a3974abc62d3 -r aac257b77842 hedgewars/res/hwengine.rc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hedgewars/res/hwengine.rc Wed Nov 07 18:02:20 2012 +0000 @@ -0,0 +1,1 @@ +MAINICON ICON "res/hwengine.ico" \ No newline at end of file diff -r a3974abc62d3 -r aac257b77842 hedgewars/sdlmain_osx/SDLMain.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hedgewars/sdlmain_osx/SDLMain.h Wed Nov 07 18:02:20 2012 +0000 @@ -0,0 +1,16 @@ +/* SDLMain.m - main entry point for our Cocoa-ized SDL app + Initial Version: Darrell Walisser + Non-NIB-Code & other changes: Max Horn + + Feel free to customize this file to suit your needs +*/ + +#ifndef _SDLMain_h_ +#define _SDLMain_h_ + +#import + +@interface SDLMain : NSObject +@end + +#endif /* _SDLMain_h_ */ diff -r a3974abc62d3 -r aac257b77842 hedgewars/sdlmain_osx/SDLMain.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hedgewars/sdlmain_osx/SDLMain.m Wed Nov 07 18:02:20 2012 +0000 @@ -0,0 +1,385 @@ +/* SDLMain.m - main entry point for our Cocoa-ized SDL app + Initial Version: Darrell Walisser + Non-NIB-Code & other changes: Max Horn + + Feel free to customize this file to suit your needs +*/ + +#include "SDL.h" +#include "SDLMain.h" +#include /* for MAXPATHLEN */ +#include + +/* For some reaon, Apple removed setAppleMenu from the headers in 10.4, + but the method still is there and works. To avoid warnings, we declare + it ourselves here. */ +@interface NSApplication(SDL_Missing_Methods) +- (void)setAppleMenu:(NSMenu *)menu; +@end + +/* Use this flag to determine whether we use SDLMain.nib or not */ +#define SDL_USE_NIB_FILE 0 + +/* Use this flag to determine whether we use CPS (docking) or not */ +#define SDL_USE_CPS 1 +#ifdef SDL_USE_CPS +/* Portions of CPS.h */ +typedef struct CPSProcessSerNum +{ + UInt32 lo; + UInt32 hi; +} CPSProcessSerNum; + +extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); +extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); +extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); + +#endif /* SDL_USE_CPS */ + +static int gArgc; +static char **gArgv; +static BOOL gFinderLaunch; +static BOOL gCalledAppMainline = FALSE; + +static NSString *getApplicationName(void) +{ + const NSDictionary *dict; + NSString *appName = 0; + + /* Determine the application name */ + dict = (const NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); + if (dict) + appName = [dict objectForKey: @"CFBundleName"]; + + if (![appName length]) + appName = [[NSProcessInfo processInfo] processName]; + + return appName; +} + +#if SDL_USE_NIB_FILE +/* A helper category for NSString */ +@interface NSString (ReplaceSubString) +- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; +@end +#endif + +@interface SDLApplication : NSApplication +@end + +@implementation SDLApplication +/* Invoked from the Quit menu item */ +- (void)terminate:(id)sender +{ + /* Post a SDL_QUIT event */ + SDL_Event event; + event.type = SDL_QUIT; + SDL_PushEvent(&event); +} +@end + +/* The main class of the application, the application's delegate */ +@implementation SDLMain + +/* Set the working directory to the .app's parent directory */ +- (void) setupWorkingDirectory:(BOOL)shouldChdir +{ + if (shouldChdir) + { + char parentdir[MAXPATHLEN]; + CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); + CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); + if (CFURLGetFileSystemRepresentation(url2, 1, (UInt8 *)parentdir, MAXPATHLEN)) { + chdir(parentdir); /* chdir to the binary app's parent */ + } + CFRelease(url); + CFRelease(url2); + } +} + +#if SDL_USE_NIB_FILE + +/* Fix menu to contain the real app name instead of "SDL App" */ +- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName +{ + NSRange aRange; + NSEnumerator *enumerator; + NSMenuItem *menuItem; + + aRange = [[aMenu title] rangeOfString:@"SDL App"]; + if (aRange.length != 0) + [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]]; + + enumerator = [[aMenu itemArray] objectEnumerator]; + while ((menuItem = [enumerator nextObject])) + { + aRange = [[menuItem title] rangeOfString:@"SDL App"]; + if (aRange.length != 0) + [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]]; + if ([menuItem hasSubmenu]) + [self fixMenu:[menuItem submenu] withAppName:appName]; + } + [ aMenu sizeToFit ]; +} + +#else + +static void setApplicationMenu(void) +{ + /* warning: this code is very odd */ + NSMenu *appleMenu; + NSMenuItem *menuItem; + NSString *title; + NSString *appName; + + appName = getApplicationName(); + appleMenu = [[NSMenu alloc] initWithTitle:@""]; + + /* Add menu items */ + title = [@"About " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; + + [appleMenu addItem:[NSMenuItem separatorItem]]; + + title = [@"Hide " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; + + menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; + [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; + + [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; + + [appleMenu addItem:[NSMenuItem separatorItem]]; + + title = [@"Quit " stringByAppendingString:appName]; + [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; + + + /* Put menu into the menubar */ + menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; + [menuItem setSubmenu:appleMenu]; + [[NSApp mainMenu] addItem:menuItem]; + + /* Tell the application object that this is now the application menu */ + [NSApp setAppleMenu:appleMenu]; + + /* Finally give up our references to the objects */ + [appleMenu release]; + [menuItem release]; +} + +/* Create a window menu */ +static void setupWindowMenu(void) +{ + NSMenu *windowMenu; + NSMenuItem *windowMenuItem; + NSMenuItem *menuItem; + + windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; + + /* "Minimize" item */ + menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; + [windowMenu addItem:menuItem]; + [menuItem release]; + + /* Put menu into the menubar */ + windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; + [windowMenuItem setSubmenu:windowMenu]; + [[NSApp mainMenu] addItem:windowMenuItem]; + + /* Tell the application object that this is now the window menu */ + [NSApp setWindowsMenu:windowMenu]; + + /* Finally give up our references to the objects */ + [windowMenu release]; + [windowMenuItem release]; +} + +/* Replacement for NSApplicationMain */ +static void CustomApplicationMain (int argc, char **argv) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + SDLMain *sdlMain; + + /* Ensure the application object is initialised */ + [SDLApplication sharedApplication]; + +#ifdef SDL_USE_CPS + { + CPSProcessSerNum PSN; + /* Tell the dock about us */ + if (!CPSGetCurrentProcess(&PSN)) + if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) + if (!CPSSetFrontProcess(&PSN)) + [SDLApplication sharedApplication]; + } +#endif /* SDL_USE_CPS */ + + /* Set up the menubar */ + NSMenu *menu = [[NSMenu alloc] init]; + [NSApp setMainMenu:menu]; + setApplicationMenu(); + setupWindowMenu(); + [menu release]; + + /* Create SDLMain and make it the app delegate */ + sdlMain = [[SDLMain alloc] init]; + [NSApp setDelegate:sdlMain]; + + /* Start the main event loop */ + [NSApp run]; + + [sdlMain release]; + [pool release]; +} + +#endif + + +/* + * Catch document open requests...this lets us notice files when the app + * was launched by double-clicking a document, or when a document was + * dragged/dropped on the app's icon. You need to have a + * CFBundleDocumentsType section in your Info.plist to get this message, + * apparently. + * + * Files are added to gArgv, so to the app, they'll look like command line + * arguments. Previously, apps launched from the finder had nothing but + * an argv[0]. + * + * This message may be received multiple times to open several docs on launch. + * + * This message is ignored once the app's mainline has been called. + */ +- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename +{ + const char *temparg; + size_t arglen; + char *arg; + char **newargv; + + if (!gFinderLaunch) /* MacOS is passing command line args. */ + return FALSE; + + if (gCalledAppMainline) /* app has started, ignore this document. */ + return FALSE; + + temparg = [filename UTF8String]; + arglen = SDL_strlen(temparg) + 1; + arg = (char *) SDL_malloc(arglen); + if (arg == NULL) + return FALSE; + + newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2)); + if (newargv == NULL) + { + SDL_free(arg); + return FALSE; + } + gArgv = newargv; + + SDL_strlcpy(arg, temparg, arglen); + gArgv[gArgc++] = arg; + gArgv[gArgc] = NULL; + return TRUE; +} + + +/* Called when the internal event loop has just started running */ +- (void) applicationDidFinishLaunching: (NSNotification *) note +{ + int status; + + /* Set the working directory to the .app's parent directory */ + [self setupWorkingDirectory:gFinderLaunch]; + +#if SDL_USE_NIB_FILE + /* Set the main menu to contain the real app name instead of "SDL App" */ + [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()]; +#endif + + /* Hand off to main application code */ + gCalledAppMainline = TRUE; + status = SDL_main (gArgc, gArgv); + + /* We're done, thank you for playing */ + exit(status); +} +@end + + +@implementation NSString (ReplaceSubString) + +- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString +{ + unsigned int bufferSize; + unsigned int selfLen = [self length]; + unsigned int aStringLen = [aString length]; + unichar *buffer; + NSRange localRange; + NSString *result; + + bufferSize = selfLen + aStringLen - aRange.length; + buffer = (unichar *)NSAllocateMemoryPages(bufferSize*sizeof(unichar)); + + /* Get first part into buffer */ + localRange.location = 0; + localRange.length = aRange.location; + [self getCharacters:buffer range:localRange]; + + /* Get middle part into buffer */ + localRange.location = 0; + localRange.length = aStringLen; + [aString getCharacters:(buffer+aRange.location) range:localRange]; + + /* Get last part into buffer */ + localRange.location = aRange.location + aRange.length; + localRange.length = selfLen - localRange.location; + [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange]; + + /* Build output string */ + result = [NSString stringWithCharacters:buffer length:bufferSize]; + + NSDeallocateMemoryPages(buffer, bufferSize); + + return result; +} + +@end + + + +#ifdef main +# undef main +#endif + + +/* Main entry point to executable - should *not* be SDL_main! */ +int main (int argc, char **argv) +{ + /* Copy the arguments into a global variable */ + /* This is passed if we are launched by double-clicking */ + if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { + gArgv = (char **) SDL_malloc(sizeof (char *) * 2); + gArgv[0] = argv[0]; + gArgv[1] = NULL; + gArgc = 1; + gFinderLaunch = YES; + } else { + int i; + gArgc = argc; + gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1)); + for (i = 0; i <= argc; i++) + gArgv[i] = argv[i]; + gFinderLaunch = NO; + } + +#if SDL_USE_NIB_FILE + [SDLApplication poseAsClass:[NSApplication class]]; + NSApplicationMain (argc, argv); +#else + CustomApplicationMain (argc, argv); +#endif + return 0; +} + diff -r a3974abc62d3 -r aac257b77842 hedgewars/videorec/avwrapper.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hedgewars/videorec/avwrapper.c Wed Nov 07 18:02:20 2012 +0000 @@ -0,0 +1,515 @@ +/* + * Hedgewars, a free turn based strategy game + * Copyright (c) 2004-2012 Andrey Korotaev + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include +#include +#include +#include "libavformat/avformat.h" + +#ifndef AVIO_FLAG_WRITE +#define AVIO_FLAG_WRITE AVIO_WRONLY +#endif + +static AVFormatContext* g_pContainer; +static AVOutputFormat* g_pFormat; +static AVStream* g_pAStream; +static AVStream* g_pVStream; +static AVFrame* g_pAFrame; +static AVFrame* g_pVFrame; +static AVCodec* g_pACodec; +static AVCodec* g_pVCodec; +static AVCodecContext* g_pAudio; +static AVCodecContext* g_pVideo; + +static int g_Width, g_Height; +static uint32_t g_Frequency, g_Channels; +static int g_VQuality; +static AVRational g_Framerate; + +static FILE* g_pSoundFile; +static int16_t* g_pSamples; +static int g_NumSamples; + +/* +Initially I wrote code for latest ffmpeg, but on Linux (Ubuntu) +only older version is available from repository. That's why you see here +all of this #if LIBAVCODEC_VERSION_MAJOR < 54. +Actually, it may be possible to remove code for newer version +and use only code for older version. +*/ + +#if LIBAVCODEC_VERSION_MAJOR < 54 +#define OUTBUFFER_SIZE 200000 +static uint8_t g_OutBuffer[OUTBUFFER_SIZE]; +#endif + +// pointer to function from hwengine (uUtils.pas) +static void (*AddFileLogRaw)(const char* pString); + +static void FatalError(const char* pFmt, ...) +{ + const char Buffer[1024]; + va_list VaArgs; + + va_start(VaArgs, pFmt); + vsnprintf(Buffer, 1024, pFmt, VaArgs); + va_end(VaArgs); + + AddFileLogRaw("Error in av-wrapper: "); + AddFileLogRaw(Buffer); + AddFileLogRaw("\n"); + exit(1); +} + +// Function to be called from libav for logging. +// Note: libav can call LogCallback from different threads +// (there is mutex in AddFileLogRaw). +static void LogCallback(void* p, int Level, const char* pFmt, va_list VaArgs) +{ + const char Buffer[1024]; + + vsnprintf(Buffer, 1024, pFmt, VaArgs); + AddFileLogRaw(Buffer); +} + +static void Log(const char* pFmt, ...) +{ + const char Buffer[1024]; + va_list VaArgs; + + va_start(VaArgs, pFmt); + vsnprintf(Buffer, 1024, pFmt, VaArgs); + va_end(VaArgs); + + AddFileLogRaw(Buffer); +} + +static void AddAudioStream() +{ +#if LIBAVFORMAT_VERSION_MAJOR >= 54 + g_pAStream = avformat_new_stream(g_pContainer, g_pACodec); +#else + g_pAStream = av_new_stream(g_pContainer, 1); +#endif + if(!g_pAStream) + { + Log("Could not allocate audio stream\n"); + return; + } + g_pAStream->id = 1; + + g_pAudio = g_pAStream->codec; + + avcodec_get_context_defaults3(g_pAudio, g_pACodec); + g_pAudio->codec_id = g_pACodec->id; + + // put parameters + g_pAudio->sample_fmt = AV_SAMPLE_FMT_S16; + g_pAudio->sample_rate = g_Frequency; + g_pAudio->channels = g_Channels; + + // set quality + g_pAudio->bit_rate = 160000; + + // for codecs that support variable bitrate use it, it should be better + g_pAudio->flags |= CODEC_FLAG_QSCALE; + g_pAudio->global_quality = 1*FF_QP2LAMBDA; + + // some formats want stream headers to be separate + if (g_pFormat->flags & AVFMT_GLOBALHEADER) + g_pAudio->flags |= CODEC_FLAG_GLOBAL_HEADER; + + // open it +#if LIBAVCODEC_VERSION_MAJOR >= 53 + if (avcodec_open2(g_pAudio, g_pACodec, NULL) < 0) +#else + if (avcodec_open(g_pAudio, g_pACodec) < 0) +#endif + { + Log("Could not open audio codec %s\n", g_pACodec->long_name); + return; + } + +#if LIBAVCODEC_VERSION_MAJOR >= 54 + if (g_pACodec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE) +#else + if (g_pAudio->frame_size == 0) +#endif + g_NumSamples = 4096; + else + g_NumSamples = g_pAudio->frame_size; + g_pSamples = (int16_t*)av_malloc(g_NumSamples*g_Channels*sizeof(int16_t)); + g_pAFrame = avcodec_alloc_frame(); + if (!g_pAFrame) + { + Log("Could not allocate frame\n"); + return; + } +} + +// returns non-zero if there is more sound +static int WriteAudioFrame() +{ + if (!g_pAStream) + return 0; + + AVPacket Packet = { 0 }; + av_init_packet(&Packet); + + int NumSamples = fread(g_pSamples, 2*g_Channels, g_NumSamples, g_pSoundFile); + +#if LIBAVCODEC_VERSION_MAJOR >= 54 + AVFrame* pFrame = NULL; + if (NumSamples > 0) + { + g_pAFrame->nb_samples = NumSamples; + avcodec_fill_audio_frame(g_pAFrame, g_Channels, AV_SAMPLE_FMT_S16, + (uint8_t*)g_pSamples, NumSamples*2*g_Channels, 1); + pFrame = g_pAFrame; + } + // when NumSamples == 0 we still need to call encode_audio2 to flush + int got_packet; + if (avcodec_encode_audio2(g_pAudio, &Packet, pFrame, &got_packet) != 0) + FatalError("avcodec_encode_audio2 failed"); + if (!got_packet) + return 0; +#else + if (NumSamples == 0) + return 0; + int BufferSize = OUTBUFFER_SIZE; + if (g_pAudio->frame_size == 0) + BufferSize = NumSamples*g_Channels*2; + Packet.size = avcodec_encode_audio(g_pAudio, g_OutBuffer, BufferSize, g_pSamples); + if (Packet.size == 0) + return 1; + if (g_pAudio->coded_frame && g_pAudio->coded_frame->pts != AV_NOPTS_VALUE) + Packet.pts = av_rescale_q(g_pAudio->coded_frame->pts, g_pAudio->time_base, g_pAStream->time_base); + Packet.flags |= AV_PKT_FLAG_KEY; + Packet.data = g_OutBuffer; +#endif + + // Write the compressed frame to the media file. + Packet.stream_index = g_pAStream->index; + if (av_interleaved_write_frame(g_pContainer, &Packet) != 0) + FatalError("Error while writing audio frame"); + return 1; +} + +// add a video output stream +static void AddVideoStream() +{ +#if LIBAVFORMAT_VERSION_MAJOR >= 54 + g_pVStream = avformat_new_stream(g_pContainer, g_pVCodec); +#else + g_pVStream = av_new_stream(g_pContainer, 0); +#endif + if (!g_pVStream) + FatalError("Could not allocate video stream"); + + g_pVideo = g_pVStream->codec; + + avcodec_get_context_defaults3(g_pVideo, g_pVCodec); + g_pVideo->codec_id = g_pVCodec->id; + + // put parameters + // resolution must be a multiple of two + g_pVideo->width = g_Width & ~1; // make even (dimensions should be even) + g_pVideo->height = g_Height & ~1; // make even + /* time base: this is the fundamental unit of time (in seconds) in terms + of which frame timestamps are represented. for fixed-fps content, + timebase should be 1/framerate and timestamp increments should be + identically 1. */ + g_pVideo->time_base.den = g_Framerate.num; + g_pVideo->time_base.num = g_Framerate.den; + //g_pVideo->gop_size = 12; /* emit one intra frame every twelve frames at most */ + g_pVideo->pix_fmt = PIX_FMT_YUV420P; + + // set quality + if (g_VQuality > 100) + g_pVideo->bit_rate = g_VQuality; + else + { + g_pVideo->flags |= CODEC_FLAG_QSCALE; + g_pVideo->global_quality = g_VQuality*FF_QP2LAMBDA; + } + + // some formats want stream headers to be separate + if (g_pFormat->flags & AVFMT_GLOBALHEADER) + g_pVideo->flags |= CODEC_FLAG_GLOBAL_HEADER; + +#if LIBAVCODEC_VERSION_MAJOR < 54 + // for some versions of ffmpeg x264 options must be set explicitly + if (strcmp(g_pVCodec->name, "libx264") == 0) + { + g_pVideo->coder_type = FF_CODER_TYPE_AC; + g_pVideo->flags |= CODEC_FLAG_LOOP_FILTER; + g_pVideo->crf = 23; + g_pVideo->thread_count = 3; + g_pVideo->me_cmp = FF_CMP_CHROMA; + g_pVideo->partitions = X264_PART_I8X8 | X264_PART_I4X4 | X264_PART_P8X8 | X264_PART_B8X8; + g_pVideo->me_method = ME_HEX; + g_pVideo->me_subpel_quality = 7; + g_pVideo->me_range = 16; + g_pVideo->gop_size = 250; + g_pVideo->keyint_min = 25; + g_pVideo->scenechange_threshold = 40; + g_pVideo->i_quant_factor = 0.71; + g_pVideo->b_frame_strategy = 1; + g_pVideo->qcompress = 0.6; + g_pVideo->qmin = 10; + g_pVideo->qmax = 51; + g_pVideo->max_qdiff = 4; + g_pVideo->max_b_frames = 3; + g_pVideo->refs = 3; + g_pVideo->directpred = 1; + g_pVideo->trellis = 1; + g_pVideo->flags2 = CODEC_FLAG2_BPYRAMID | CODEC_FLAG2_MIXED_REFS | CODEC_FLAG2_WPRED | CODEC_FLAG2_8X8DCT | CODEC_FLAG2_FASTPSKIP; + g_pVideo->weighted_p_pred = 2; + } +#endif + + // open the codec +#if LIBAVCODEC_VERSION_MAJOR >= 53 + AVDictionary* pDict = NULL; + if (strcmp(g_pVCodec->name, "libx264") == 0) + av_dict_set(&pDict, "preset", "medium", 0); + + if (avcodec_open2(g_pVideo, g_pVCodec, &pDict) < 0) +#else + if (avcodec_open(g_pVideo, g_pVCodec) < 0) +#endif + FatalError("Could not open video codec %s", g_pVCodec->long_name); + + g_pVFrame = avcodec_alloc_frame(); + if (!g_pVFrame) + FatalError("Could not allocate frame"); + + g_pVFrame->linesize[0] = g_Width; + g_pVFrame->linesize[1] = g_Width/2; + g_pVFrame->linesize[2] = g_Width/2; + g_pVFrame->linesize[3] = 0; +} + +static int WriteFrame(AVFrame* pFrame) +{ + double AudioTime, VideoTime; + + // write interleaved audio frame + if (g_pAStream) + { + VideoTime = (double)g_pVStream->pts.val*g_pVStream->time_base.num/g_pVStream->time_base.den; + do + AudioTime = (double)g_pAStream->pts.val*g_pAStream->time_base.num/g_pAStream->time_base.den; + while (AudioTime < VideoTime && WriteAudioFrame()); + } + + if (!g_pVStream) + return 0; + + AVPacket Packet; + av_init_packet(&Packet); + Packet.data = NULL; + Packet.size = 0; + + g_pVFrame->pts++; + if (g_pFormat->flags & AVFMT_RAWPICTURE) + { + /* raw video case. The API will change slightly in the near + future for that. */ + Packet.flags |= AV_PKT_FLAG_KEY; + Packet.stream_index = g_pVStream->index; + Packet.data = (uint8_t*)pFrame; + Packet.size = sizeof(AVPicture); + + if (av_interleaved_write_frame(g_pContainer, &Packet) != 0) + FatalError("Error while writing video frame"); + return 0; + } + else + { +#if LIBAVCODEC_VERSION_MAJOR >= 54 + int got_packet; + if (avcodec_encode_video2(g_pVideo, &Packet, pFrame, &got_packet) < 0) + FatalError("avcodec_encode_video2 failed"); + if (!got_packet) + return 0; + + if (Packet.pts != AV_NOPTS_VALUE) + Packet.pts = av_rescale_q(Packet.pts, g_pVideo->time_base, g_pVStream->time_base); + if (Packet.dts != AV_NOPTS_VALUE) + Packet.dts = av_rescale_q(Packet.dts, g_pVideo->time_base, g_pVStream->time_base); +#else + Packet.size = avcodec_encode_video(g_pVideo, g_OutBuffer, OUTBUFFER_SIZE, pFrame); + if (Packet.size < 0) + FatalError("avcodec_encode_video failed"); + if (Packet.size == 0) + return 0; + + if( g_pVideo->coded_frame->pts != AV_NOPTS_VALUE) + Packet.pts = av_rescale_q(g_pVideo->coded_frame->pts, g_pVideo->time_base, g_pVStream->time_base); + if( g_pVideo->coded_frame->key_frame ) + Packet.flags |= AV_PKT_FLAG_KEY; + Packet.data = g_OutBuffer; +#endif + // write the compressed frame in the media file + Packet.stream_index = g_pVStream->index; + if (av_interleaved_write_frame(g_pContainer, &Packet) != 0) + FatalError("Error while writing video frame"); + + return 1; + } +} + +void AVWrapper_WriteFrame(uint8_t* pY, uint8_t* pCb, uint8_t* pCr) +{ + g_pVFrame->data[0] = pY; + g_pVFrame->data[1] = pCb; + g_pVFrame->data[2] = pCr; + WriteFrame(g_pVFrame); +} + +void AVWrapper_Init( + void (*pAddFileLogRaw)(const char*), + const char* pFilename, + const char* pDesc, + const char* pSoundFile, + const char* pFormatName, + const char* pVCodecName, + const char* pACodecName, + int Width, int Height, + int FramerateNum, int FramerateDen, + int VQuality) +{ + AddFileLogRaw = pAddFileLogRaw; + av_log_set_callback( &LogCallback ); + + g_Width = Width; + g_Height = Height; + g_Framerate.num = FramerateNum; + g_Framerate.den = FramerateDen; + g_VQuality = VQuality; + + // initialize libav and register all codecs and formats + av_register_all(); + + // find format + g_pFormat = av_guess_format(pFormatName, NULL, NULL); + if (!g_pFormat) + FatalError("Format \"%s\" was not found", pFormatName); + + // allocate the output media context + g_pContainer = avformat_alloc_context(); + if (!g_pContainer) + FatalError("Could not allocate output context"); + + g_pContainer->oformat = g_pFormat; + + // store description of file + av_dict_set(&g_pContainer->metadata, "comment", pDesc, 0); + + // append extesnion to filename + char ext[16]; + strncpy(ext, g_pFormat->extensions, 16); + ext[15] = 0; + ext[strcspn(ext,",")] = 0; + snprintf(g_pContainer->filename, sizeof(g_pContainer->filename), "%s.%s", pFilename, ext); + + // find codecs + g_pVCodec = avcodec_find_encoder_by_name(pVCodecName); + g_pACodec = avcodec_find_encoder_by_name(pACodecName); + + // add audio and video stream to container + g_pVStream = NULL; + g_pAStream = NULL; + + if (g_pVCodec) + AddVideoStream(); + else + Log("Video codec \"%s\" was not found; video will be ignored.\n", pVCodecName); + + if (g_pACodec) + { + g_pSoundFile = fopen(pSoundFile, "rb"); + if (g_pSoundFile) + { + fread(&g_Frequency, 4, 1, g_pSoundFile); + fread(&g_Channels, 4, 1, g_pSoundFile); + AddAudioStream(); + } + else + Log("Could not open %s\n", pSoundFile); + } + else + Log("Audio codec \"%s\" was not found; audio will be ignored.\n", pACodecName); + + if (!g_pAStream && !g_pVStream) + FatalError("No video, no audio, aborting..."); + + // write format info to log + av_dump_format(g_pContainer, 0, g_pContainer->filename, 1); + + // open the output file, if needed + if (!(g_pFormat->flags & AVFMT_NOFILE)) + { + if (avio_open(&g_pContainer->pb, g_pContainer->filename, AVIO_FLAG_WRITE) < 0) + FatalError("Could not open output file (%s)", g_pContainer->filename); + } + + // write the stream header, if any + avformat_write_header(g_pContainer, NULL); + + g_pVFrame->pts = -1; +} + +void AVWrapper_Close() +{ + // output buffered frames + if (g_pVCodec->capabilities & CODEC_CAP_DELAY) + while( WriteFrame(NULL) ); + // output any remaining audio + while( WriteAudioFrame() ); + + // write the trailer, if any. + av_write_trailer(g_pContainer); + + // close the output file + if (!(g_pFormat->flags & AVFMT_NOFILE)) + avio_close(g_pContainer->pb); + + // free everything + if (g_pVStream) + { + avcodec_close(g_pVideo); + av_free(g_pVideo); + av_free(g_pVStream); + av_free(g_pVFrame); + } + if (g_pAStream) + { + avcodec_close(g_pAudio); + av_free(g_pAudio); + av_free(g_pAStream); + av_free(g_pAFrame); + av_free(g_pSamples); + fclose(g_pSoundFile); + } + + av_free(g_pContainer); +} diff -r a3974abc62d3 -r aac257b77842 project_files/hwc/headers/GL.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/hwc/headers/GL.h Wed Nov 07 18:02:20 2012 +0000 @@ -0,0 +1,3 @@ +#pragma once + +#include diff -r a3974abc62d3 -r aac257b77842 project_files/hwc/headers/Math.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/hwc/headers/Math.h Wed Nov 07 18:02:20 2012 +0000 @@ -0,0 +1,2 @@ +#pragma once + diff -r a3974abc62d3 -r aac257b77842 project_files/hwc/headers/SysUtils.h diff -r a3974abc62d3 -r aac257b77842 project_files/hwc/headers/Types.h diff -r a3974abc62d3 -r aac257b77842 project_files/hwc/headers/pas2c.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/project_files/hwc/headers/pas2c.h Wed Nov 07 18:02:20 2012 +0000 @@ -0,0 +1,144 @@ +#pragma once + +#include +#include +#include +#include + +typedef union string255_ + { + struct { + char s[256]; + }; + struct { + char len; + char str[255]; + }; + } string255; +typedef struct string192_ + { + char s[193]; + } string192; +typedef struct string31_ + { + char s[32]; + } string31; +typedef struct string15_ + { + char s[16]; + } string15; + +typedef string255 shortstring; +typedef string255 ansistring; + +typedef uint8_t Byte; +typedef int8_t ShortInt; +typedef uint16_t Word; +typedef int16_t SmallInt; +typedef uint32_t LongWord; +typedef int32_t LongInt; +typedef uint64_t QWord; +typedef int64_t Int64; +typedef LongWord Cardinal; + +typedef LongInt Integer; +typedef float extended; +typedef float real; +typedef float single; + +typedef bool boolean; +typedef int LongBool; + +typedef void * pointer; +typedef Byte * PByte; +typedef char * PChar; +typedef LongInt * PLongInt; +typedef LongWord * PLongWord; +typedef Integer * PInteger; +typedef int PtrInt; +typedef wchar_t widechar; + +#define new(a) __new((void **)&a, sizeof(*(a))) +void __new(void ** p, int size); +#define dispose(a) __dispose(a, sizeof(*(a))) +void __dispose(pointer p, int size); + +void * GetMem(int size); +void FreeMem(void * p, int size); + +#define FillChar(a, b, c) __FillChar(&(a), b, c) + +void __FillChar(pointer p, int size, char fill); +string255 _strconcat(string255 a, string255 b); +string255 _strappend(string255 s, char c); +string255 _strprepend(char c, string255 s); +string255 _chrconcat(char a, char b); +bool _strcompare(string255 a, string255 b); +bool _strcomparec(string255 a, char b); +bool _strncompare(string255 a, string255 b); +char * _pchar(string255 s); +string255 pchar2str(char * s); + +int Length(string255 a); +string255 copy(string255 a, int s, int l); +string255 delete(string255 a, int s, int l); +string255 trim(string255 a); + +#define STRINIT(a) {.len = sizeof(a) - 1, .str = a} + + +int length_ar(void * a); + +typedef int file; +typedef int TextFile; +extern int FileMode; +extern int IOResult; +extern int stdout; +extern int stderr; + +#define assign(a, b) assign_(&(a), b) +void assign_(int * f, string255 fileName); +void reset_1(int f, int size); +void reset_2(int f, int size); +#define BlockRead(a, b, c, d) BlockRead_(a, &(b), c, &(d)) +void BlockRead_(int f, void * p, int size, int * sizeRead); +#define BlockWrite(a, b, c) BlockWrite_(a, &(b), c) +void BlockWrite_(int f, void * p, int size); +void close(int f); + +void write(int f, string255 s); +void writeLn(int f, string255 s); + +bool DirectoryExists(string255 dir); +bool FileExists(string255 filename); + +bool odd(int i); + + +typedef int TThreadId; +void ThreadSwitch(); +#define InterlockedIncrement(a) __InterlockedIncrement(&(a)) +#define InterlockedDecrement(a) __InterlockedDecrement(&(a)) +void __InterlockedIncrement(int * a); +void __InterlockedDecrement(int * a); + +bool Assigned(void * a); + +void randomize(); +int random(int max); +int abs(int i); +double sqr(double n); +double sqrt(double n); +int trunc(double n); +int round(double n); + +string255 ParamStr(int n); +int ParamCount(); + +#define val(a, b, c) _val(a, (LongInt*)&(b), (LongInt*)&(c)) +void _val(string255 str, LongInt * a, LongInt * c); + +extern double pi; + +string255 EnumToStr(int a); +string255 ExtractFileName(string255 f);