forked from Mirrors/openclonk
491 lines
13 KiB
Plaintext
491 lines
13 KiB
Plaintext
|
/*
|
||
|
* OpenClonk, http://www.openclonk.org
|
||
|
*
|
||
|
* Portions might be copyrighted by other authors who have contributed
|
||
|
* to OpenClonk.
|
||
|
*
|
||
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||
|
* purpose with or without fee is hereby granted, provided that the above
|
||
|
* copyright notice and this permission notice appear in all copies.
|
||
|
* See isc_license.txt for full license and disclaimer.
|
||
|
*
|
||
|
* "Clonk" is a registered trademark of Matthes Bender.
|
||
|
* See clonk_trademark_license.txt for full license.
|
||
|
*/
|
||
|
|
||
|
#include <C4Include.h>
|
||
|
#include <C4Console.h>
|
||
|
#include <C4Application.h>
|
||
|
|
||
|
#include <C4GameSave.h>
|
||
|
#include <C4Game.h>
|
||
|
#include <C4MessageInput.h>
|
||
|
#include <C4UserMessages.h>
|
||
|
#include <C4Version.h>
|
||
|
#include <C4Language.h>
|
||
|
#include <C4Player.h>
|
||
|
#include <C4Landscape.h>
|
||
|
#include <C4GraphicsSystem.h>
|
||
|
#include <C4PlayerList.h>
|
||
|
#include <C4GameControl.h>
|
||
|
#include <C4Texture.h>
|
||
|
|
||
|
#include <StdFile.h>
|
||
|
#include <StdRegistry.h>
|
||
|
#include <StdGL.h>
|
||
|
|
||
|
#import <Cocoa/Cocoa.h>
|
||
|
#import "ClonkAppDelegate.h"
|
||
|
#import "ConsoleWindowController.h"
|
||
|
#import "ClonkOpenGLView.h"
|
||
|
|
||
|
// implementation of C4Console GUI for Mac OS X
|
||
|
|
||
|
namespace
|
||
|
{
|
||
|
inline ConsoleWindowController* ctrler(C4ConsoleGUI* gui) {return (ConsoleWindowController*)gui->GetController();}
|
||
|
}
|
||
|
|
||
|
class C4ConsoleGUI::State: public C4ConsoleGUI::InternalState<class C4ConsoleGUI>
|
||
|
{
|
||
|
public:
|
||
|
State(C4ConsoleGUI *console): Super(console) {}
|
||
|
};
|
||
|
|
||
|
class C4ToolsDlg::State: public C4ConsoleGUI::InternalState<class C4ToolsDlg>
|
||
|
{
|
||
|
public:
|
||
|
State(C4ToolsDlg *toolsDlg): Super(toolsDlg) {}
|
||
|
~State()
|
||
|
{
|
||
|
[ctrler(&Console).toolsPanel orderOut:nil];
|
||
|
}
|
||
|
CGImageRef CreatePreviewImage();
|
||
|
void Default() {}
|
||
|
void Clear() {}
|
||
|
};
|
||
|
|
||
|
class C4PropertyDlg::State: public C4ConsoleGUI::InternalState<class C4PropertyDlg>
|
||
|
{
|
||
|
public:
|
||
|
State(C4PropertyDlg *dlg): Super(dlg) {}
|
||
|
void Default() {}
|
||
|
void Clear() {}
|
||
|
};
|
||
|
|
||
|
CStdWindow* C4ConsoleGUI::CreateConsoleWindow(CStdApp *application)
|
||
|
{
|
||
|
ClonkWindowController* controller = [ConsoleWindowController new];
|
||
|
this->controller = controller;
|
||
|
[NSBundle loadNibNamed:@"ConsoleWindow" owner:controller];
|
||
|
[controller setStdWindow:this];
|
||
|
this->Active = true;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
bool C4ConsoleGUI::Out(const char* message)
|
||
|
{
|
||
|
ConsoleWindowController* controller;
|
||
|
if (controller = ctrler(this))
|
||
|
{
|
||
|
NSTextStorage* textStorage = controller.outputTextView.textStorage;
|
||
|
[textStorage appendAttributedString:[[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%s\n", message]] autorelease]];
|
||
|
[controller.outputTextView scrollRangeToVisible:NSMakeRange([textStorage length]-1, 1)];
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool C4ConsoleGUI::ClearLog()
|
||
|
{
|
||
|
[ctrler(this).outputTextView.textStorage
|
||
|
replaceCharactersInRange:NSMakeRange(0, ctrler(this).outputTextView.textStorage.length)
|
||
|
withAttributedString:[[NSAttributedString alloc] initWithString:@""]];
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::DisplayInfoText(C4ConsoleGUI::InfoTextType type, StdStrBuf& text)
|
||
|
{
|
||
|
NSTextField* label;
|
||
|
switch (type)
|
||
|
{
|
||
|
case CONSOLE_FrameCounter:
|
||
|
label = ctrler(this).frameLabel;
|
||
|
break;
|
||
|
case CONSOLE_ScriptCounter:
|
||
|
label = ctrler(this).scriptLabel;
|
||
|
break;
|
||
|
case CONSOLE_TimeFPS:
|
||
|
label = ctrler(this).timeLabel;
|
||
|
break;
|
||
|
case CONSOLE_Cursor:
|
||
|
return;
|
||
|
default:
|
||
|
return;
|
||
|
}
|
||
|
[label setStringValue:[NSString stringWithUTF8String:text.getData()]];
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::SetCaptionToFileName(const char* file_name)
|
||
|
{
|
||
|
[ctrler(this).window setRepresentedFilename:[NSString stringWithUTF8String:file_name]];
|
||
|
}
|
||
|
|
||
|
bool C4ConsoleGUI::FileSelect(char *sFilename, int iSize, const char * szFilter, DWORD dwFlags, bool fSave)
|
||
|
{
|
||
|
NSSavePanel* savePanel = fSave ? [NSSavePanel savePanel] : [NSOpenPanel openPanel];
|
||
|
if (!fSave)
|
||
|
{
|
||
|
[(NSOpenPanel*)savePanel setCanChooseFiles:YES];
|
||
|
[(NSOpenPanel*)savePanel setCanChooseDirectories:YES];
|
||
|
}
|
||
|
if ([savePanel runModal] == NSFileHandlingPanelOKButton && [[savePanel URL] isFileURL])
|
||
|
{
|
||
|
strncpy(sFilename, [[savePanel URL].path cStringUsingEncoding:NSUTF8StringEncoding], iSize);
|
||
|
return true;
|
||
|
}
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::AddMenuItemForPlayer(C4Player* player, StdStrBuf& player_text)
|
||
|
{
|
||
|
NSMenuItem* item = [
|
||
|
[ClonkAppDelegate instance].newViewportForPlayerMenuItem.submenu
|
||
|
addItemWithTitle:[NSString stringWithUTF8String:player_text.getData()] action:@selector(newViewportForPlayer:) keyEquivalent:@""
|
||
|
];
|
||
|
[item setTag:player->Number];
|
||
|
[item setTarget: ClonkAppDelegate.instance];
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::ClearViewportMenu()
|
||
|
{
|
||
|
[[ClonkAppDelegate instance].newViewportForPlayerMenuItem.submenu removeAllItems];
|
||
|
}
|
||
|
|
||
|
bool C4ConsoleGUI::Message(const char *message, bool query)
|
||
|
{
|
||
|
NSAlert* alert = [NSAlert
|
||
|
alertWithMessageText:[NSString stringWithUTF8String:C4ENGINECAPTION]
|
||
|
defaultButton:query ? @"Yes" : nil
|
||
|
alternateButton:query ? @"No" : nil
|
||
|
otherButton:nil
|
||
|
informativeTextWithFormat:[NSString stringWithUTF8String:message]
|
||
|
];
|
||
|
[alert runModal];
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool C4ConsoleGUI::PropertyDlgOpen(C4PropertyDlg* dlg)
|
||
|
{
|
||
|
[ctrler(this).objectsPanel orderFront:nil];
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::PropertyDlgUpdate(C4PropertyDlg *dlg, StdStrBuf &text)
|
||
|
{
|
||
|
[ctrler(this).objectPropertiesText.textStorage setAttributedString:[[[NSAttributedString alloc] initWithString:[NSString stringWithUTF8String:text.getData()]] autorelease]];
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::ClearDlg(void *dlg)
|
||
|
{
|
||
|
if (dlg == &Console.PropertyDlg)
|
||
|
[ctrler(this).objectsPanel orderOut:nil];
|
||
|
else if (dlg == &Console.ToolsDlg)
|
||
|
[ctrler(this).toolsPanel orderOut:nil];
|
||
|
}
|
||
|
|
||
|
bool C4ConsoleGUI::ToolsDlgOpen(C4ToolsDlg *dlg)
|
||
|
{
|
||
|
[ctrler(this).toolsPanel orderFront:nil];
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::ToolsDlgInitMaterialCtrls(class C4ToolsDlg *dlg)
|
||
|
{
|
||
|
NSPopUpButton* materialsPopup = ctrler(this).materialsPopup;
|
||
|
[materialsPopup removeAllItems];
|
||
|
[materialsPopup addItemWithTitle:[NSString stringWithUTF8String:C4TLS_MatSky]];
|
||
|
NSMutableArray* ary = [[NSMutableArray alloc] initWithCapacity:MaterialMap.Num+1];
|
||
|
[ary addObject:[NSString stringWithUTF8String:C4TLS_MatSky]];
|
||
|
for (int32_t cnt = 0; cnt < ::MaterialMap.Num; cnt++)
|
||
|
{
|
||
|
[ary addObject:[NSString stringWithUTF8String: ::MaterialMap.Map[cnt].Name]];
|
||
|
}
|
||
|
[ary sortUsingComparator:^(id a, id b) {return [a compare:b];}];
|
||
|
for (NSString* s in ary)
|
||
|
{
|
||
|
[materialsPopup addItemWithTitle:s];
|
||
|
}
|
||
|
[ary release];
|
||
|
[materialsPopup selectItemWithTitle:[NSString stringWithUTF8String:dlg->Material]];
|
||
|
}
|
||
|
|
||
|
void C4ToolsDlg::UpdateToolCtrls()
|
||
|
{
|
||
|
[ctrler(&Console).toolSelector setSelectedSegment:Tool];
|
||
|
}
|
||
|
|
||
|
void C4ToolsDlg::UpdateTextures()
|
||
|
{
|
||
|
// Refill dlg
|
||
|
NSPopUpButton* texturesPopup = ctrler(&Console).texturesPopup;
|
||
|
[texturesPopup removeAllItems];
|
||
|
// bottom-most: any invalid textures
|
||
|
bool fAnyEntry = false; int32_t cnt; const char *szTexture;
|
||
|
if (::Landscape.Mode!=C4LSC_Exact)
|
||
|
for (cnt=0; (szTexture=::TextureMap.GetTexture(cnt)); cnt++)
|
||
|
{
|
||
|
if (!::TextureMap.GetIndex(Material, szTexture, false))
|
||
|
{
|
||
|
fAnyEntry = true;
|
||
|
[texturesPopup insertItemWithTitle:[NSString stringWithUTF8String:szTexture] atIndex:0];
|
||
|
}
|
||
|
}
|
||
|
// separator
|
||
|
if (fAnyEntry)
|
||
|
{
|
||
|
[texturesPopup insertItemWithTitle:@"-------" atIndex:0];
|
||
|
}
|
||
|
|
||
|
// atop: valid textures
|
||
|
for (cnt=0; (szTexture=::TextureMap.GetTexture(cnt)); cnt++)
|
||
|
{
|
||
|
// Current material-texture valid? Always valid for exact mode
|
||
|
if (::TextureMap.GetIndex(Material,szTexture,false) || ::Landscape.Mode==C4LSC_Exact)
|
||
|
{
|
||
|
[texturesPopup insertItemWithTitle:[NSString stringWithUTF8String:szTexture] atIndex:0];
|
||
|
}
|
||
|
}
|
||
|
// reselect current
|
||
|
[texturesPopup selectItemWithTitle:[NSString stringWithUTF8String:Texture]];
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::ToolsDlgSetTexture(class C4ToolsDlg *dlg, const char *texture)
|
||
|
{
|
||
|
[ctrler(this).texturesPopup selectItemWithTitle:[NSString stringWithUTF8String:texture]];
|
||
|
}
|
||
|
|
||
|
void C4ToolsDlg::NeedPreviewUpdate()
|
||
|
{
|
||
|
CGImageRef image = state->CreatePreviewImage();
|
||
|
[ctrler(&Console).previewView setImage:image imageProperties:[NSDictionary dictionary]];
|
||
|
CGImageRelease(image);
|
||
|
}
|
||
|
|
||
|
namespace
|
||
|
{
|
||
|
// copy-pasta from http://stackoverflow.com/questions/2395650/fastest-way-to-draw-a-screen-buffer-on-the-iphone
|
||
|
const void* GetBytePointer(void* info)
|
||
|
{
|
||
|
// this is currently only called once
|
||
|
return info; // info is a pointer to the buffer
|
||
|
}
|
||
|
|
||
|
void ReleaseBytePointer(void*info, const void* pointer)
|
||
|
{
|
||
|
// don't care, just using the one static buffer at the moment
|
||
|
}
|
||
|
|
||
|
|
||
|
size_t GetBytesAtPosition(void* info, void* buffer, off_t position, size_t count)
|
||
|
{
|
||
|
// I don't think this ever gets called
|
||
|
memcpy(buffer, ((char*)info) + position, count);
|
||
|
return count;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CGImageRef C4ToolsDlg::State::CreatePreviewImage()
|
||
|
{
|
||
|
SURFACE sfcPreview;
|
||
|
int32_t iPrvWdt,iPrvHgt;
|
||
|
RECT rect;
|
||
|
|
||
|
rect.left = rect.top = 0;
|
||
|
rect.bottom = [ctrler(&Console).previewView frame].size.height;
|
||
|
rect.right = [ctrler(&Console).previewView frame].size.width;
|
||
|
|
||
|
iPrvWdt=rect.right-rect.left;
|
||
|
iPrvHgt=rect.bottom-rect.top;
|
||
|
|
||
|
if (!(sfcPreview=new CSurface(iPrvWdt,iPrvHgt))) return NULL;
|
||
|
|
||
|
// fill bg
|
||
|
BYTE bCol = 0;
|
||
|
CPattern Pattern;
|
||
|
// Sky material: sky as pattern only
|
||
|
if (SEqual(GetOwner()->Material,C4TLS_MatSky))
|
||
|
{
|
||
|
Pattern.Set(::Landscape.Sky.Surface, 0);
|
||
|
}
|
||
|
// Material-Texture
|
||
|
else
|
||
|
{
|
||
|
bCol=Mat2PixColDefault(::MaterialMap.Get(GetOwner()->Material));
|
||
|
// Get/Create TexMap entry
|
||
|
BYTE iTex = ::TextureMap.GetIndex(GetOwner()->Material, GetOwner()->Texture, true);
|
||
|
if (iTex)
|
||
|
{
|
||
|
// Define texture pattern
|
||
|
const C4TexMapEntry *pTex = ::TextureMap.GetEntry(iTex);
|
||
|
// Security
|
||
|
if (pTex)
|
||
|
{
|
||
|
// Set drawing pattern
|
||
|
Pattern = pTex->GetPattern();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
lpDDraw->DrawPatternedCircle(
|
||
|
sfcPreview,
|
||
|
iPrvWdt/2,iPrvHgt/2,
|
||
|
GetOwner()->Grade,
|
||
|
bCol, Pattern, *::Landscape.GetPal()
|
||
|
);
|
||
|
//Application.DDraw->AttachPrimaryPalette(sfcPreview);
|
||
|
|
||
|
DWORD *pixels = new DWORD[iPrvWdt*iPrvHgt];
|
||
|
for (int x = 0; x < iPrvWdt; x++) for (int y = 0; y < iPrvHgt; y++)
|
||
|
{
|
||
|
pixels[x+y*iPrvWdt] = sfcPreview->GetPixDw(x, y, true);
|
||
|
}
|
||
|
CGDataProviderDirectCallbacks callbacks = {0, ::GetBytePointer, ::ReleaseBytePointer, ::GetBytesAtPosition, 0};
|
||
|
CGDataProviderRef pixelData = CGDataProviderCreateDirect(pixels, iPrvWdt*iPrvHgt*sizeof(DWORD), &callbacks);
|
||
|
CGImageRef image = CGImageCreate(iPrvWdt, iPrvHgt, 8, 4*8, iPrvWdt*4, [[NSColorSpace deviceRGBColorSpace] CGColorSpace], kCGBitmapByteOrder32Little, pixelData, NULL, true, kCGRenderingIntentDefault);
|
||
|
CGDataProviderRelease(pixelData);
|
||
|
delete sfcPreview;
|
||
|
return image;
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::ToolsDlgSetMaterial(class C4ToolsDlg *dlg, const char *material)
|
||
|
{
|
||
|
[ctrler(this).texturesPopup selectItemWithTitle:[NSString stringWithUTF8String:material]];
|
||
|
}
|
||
|
|
||
|
void C4ToolsDlg::InitGradeCtrl()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
bool C4ToolsDlg::PopMaterial()
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::ShowAboutWithCopyright(StdStrBuf ©right)
|
||
|
{
|
||
|
StdStrBuf strMessage; strMessage.Format("%s %s\n\n%s", C4ENGINECAPTION, C4VERSION, copyright.getData());
|
||
|
Message(strMessage.getData(), false);
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::ToolsDlgSelectTexture(C4ToolsDlg *dlg, const char *texture)
|
||
|
{
|
||
|
[ctrler(this).texturesPopup selectItemWithTitle:[NSString stringWithUTF8String:texture]];
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::ToolsDlgSelectMaterial(C4ToolsDlg *dlg, const char *material)
|
||
|
{
|
||
|
[ctrler(this).materialsPopup selectItemWithTitle:[NSString stringWithUTF8String:material]];
|
||
|
}
|
||
|
|
||
|
void C4ToolsDlg::UpdateIFTControls()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::SetCursor(C4ConsoleGUI::Cursor cursor)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::RecordingEnabled()
|
||
|
{
|
||
|
[[[ClonkAppDelegate instance] recordMenuItem] setEnabled:NO];
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::UpdateNetMenu(Stage stage)
|
||
|
{
|
||
|
switch (stage)
|
||
|
{
|
||
|
case C4ConsoleGUI::STAGE_Start:
|
||
|
[ClonkAppDelegate.instance.netMenu setHidden:NO];
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::ClearNetMenu(Stage stage)
|
||
|
{
|
||
|
switch (stage)
|
||
|
{
|
||
|
case C4ConsoleGUI::STAGE_Start:
|
||
|
[ClonkAppDelegate.instance.netMenu setHidden:YES];
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::DoEnableControls(bool fEnable)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
bool C4ConsoleGUI::DoUpdateHaltCtrls(bool fHalt)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::ToolsDlgEnableControls(C4ToolsDlg *dlg)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::ClearInput()
|
||
|
{
|
||
|
[ctrler(this).consoleCombo setStringValue:[NSString string]];
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::ClearPlayerMenu()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::AddNetMenuItemForPlayer(int32_t index, StdStrBuf &text)
|
||
|
{
|
||
|
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:[NSString stringWithCString:text.getData() encoding:NSUTF8StringEncoding] action:@selector(kickPlayer:) keyEquivalent:[NSString string]];
|
||
|
[item setTarget:ctrler(this)];
|
||
|
[ClonkAppDelegate.instance.netMenu.submenu addItem:item];
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::SetInputFunctions(std::vector<char*> &functions)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::PropertyDlgSetFunctions(C4PropertyDlg *dlg, std::vector<char*> &functions)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void C4ConsoleGUI::AddKickPlayerMenuItem(C4Player *player, StdStrBuf& player_text, bool enabled)
|
||
|
{
|
||
|
NSMenuItem* item = [
|
||
|
[ClonkAppDelegate instance].kickPlayerMenuItem.submenu
|
||
|
addItemWithTitle:[NSString stringWithUTF8String:player_text.getData()] action:@selector(kickPlayer:) keyEquivalent:@""
|
||
|
];
|
||
|
[item setEnabled:enabled];
|
||
|
[item setTag:player->Number];
|
||
|
[item setTarget: ctrler(this)];
|
||
|
}
|
||
|
|
||
|
bool C4ToolsDlg::PopTextures()
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void C4ToolsDlg::UpdateLandscapeModeCtrls()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
bool C4ConsoleGUI::UpdateModeCtrls(int iMode)
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
#define CONSOLEGUICOMMONINCLUDE
|
||
|
#include "C4ConsoleGUICommon.h"
|