Merge pull request #7982 from hrydgard/remove-unused

Get rid of a ton of unused code in ext/native
This commit is contained in:
Henrik Rydgård 2015-09-19 12:37:35 +02:00
commit 5e640a3c40
69 changed files with 30 additions and 17707 deletions

View File

@ -423,11 +423,6 @@ add_library(rg_etc1 STATIC
ext/native/ext/rg_etc1/rg_etc1.h)
include_directories(ext/native/ext/rg_etc1)
add_library(stb_vorbis STATIC
ext/native/ext/stb_vorbis/stb_vorbis.c
ext/native/ext/stb_vorbis/stb_vorbis.h)
include_directories(ext/native/ext/stb_vorbis)
if(USE_FFMPEG)
if(USE_SYSTEM_FFMPEG)
find_package(FFMPEG)
@ -876,28 +871,17 @@ add_library(native STATIC
${nativeExtra}
ext/native/base/backtrace.cpp
ext/native/base/backtrace.h
ext/native/audio/mixer.cpp
ext/native/audio/mixer.h
ext/native/audio/wav_read.cpp
ext/native/audio/wav_read.h
ext/native/base/basictypes.h
ext/native/base/buffer.cpp
ext/native/base/buffer.h
ext/native/base/color.h
ext/native/base/colorutil.cpp
ext/native/base/colorutil.h
ext/native/base/display.cpp
ext/native/base/display.h
ext/native/base/error_context.cpp
ext/native/base/error_context.h
ext/native/base/fastlist.h
ext/native/base/fastlist_test.cpp
ext/native/base/functional.h
ext/native/base/linked_ptr.h
ext/native/base/logging.h
ext/native/base/mutex.h
ext/native/base/scoped_ptr.h
ext/native/base/stats.h
ext/native/base/stringutil.cpp
ext/native/base/stringutil.h
ext/native/base/timeutil.cpp
@ -910,8 +894,6 @@ add_library(native STATIC
ext/native/ext/vjson/block_allocator.h
ext/native/file/chunk_file.cpp
ext/native/file/chunk_file.h
ext/native/file/dialog.cpp
ext/native/file/dialog.h
ext/native/file/easy_file.cpp
ext/native/file/easy_file.h
ext/native/file/fd_util.cpp
@ -930,13 +912,8 @@ add_library(native STATIC
ext/native/gfx/gl_debug_log.h
ext/native/gfx/gl_lost_manager.cpp
ext/native/gfx/gl_lost_manager.h
ext/native/gfx/texture.cpp
ext/native/gfx/texture.h
ext/native/gfx/texture_atlas.cpp
ext/native/gfx/texture_atlas.h
# ext/native/gfx/texture_dx11.cpp
ext/native/gfx/texture_gen.cpp
ext/native/gfx/texture_gen.h
ext/native/gfx_es2/draw_buffer.cpp
ext/native/gfx_es2/draw_buffer.h
ext/native/gfx_es2/draw_text.cpp
@ -945,8 +922,6 @@ add_library(native STATIC
ext/native/gfx_es2/gpu_features.h
ext/native/gfx_es2/glsl_program.cpp
ext/native/gfx_es2/glsl_program.h
ext/native/gfx_es2/vertex_format.cpp
ext/native/gfx_es2/vertex_format.h
ext/native/gfx_es2/gl3stub.c
ext/native/gfx_es2/gl3stub.h
ext/native/i18n/i18n.cpp
@ -968,8 +943,6 @@ add_library(native STATIC
ext/native/math/curves.h
ext/native/math/expression_parser.cpp
ext/native/math/expression_parser.h
ext/native/math/lin/aabb.cpp
ext/native/math/lin/aabb.h
ext/native/math/lin/matrix4x4.cpp
ext/native/math/lin/matrix4x4.h
ext/native/math/lin/plane.cpp
@ -981,6 +954,8 @@ add_library(native STATIC
ext/native/math/lin/vec3.h
ext/native/math/math_util.cpp
ext/native/math/math_util.h
ext/native/net/http_server.cpp
ext/native/net/http_server.h
ext/native/net/http_client.cpp
ext/native/net/http_client.h
ext/native/net/resolve.cpp
@ -1012,15 +987,8 @@ add_library(native STATIC
ext/native/ui/viewgroup.h
ext/native/ui/virtual_input.cpp
ext/native/ui/virtual_input.h
ext/native/util/bits/bits.cpp
ext/native/util/bits/bits.h
ext/native/util/bits/hamming.h
ext/native/util/bits/varint.cpp
ext/native/util/bits/varint.h
ext/native/util/hash/hash.cpp
ext/native/util/hash/hash.h
ext/native/util/random/perlin.cpp
ext/native/util/random/perlin.h
ext/native/util/random/rng.h
ext/native/util/text/utf8.h
ext/native/util/text/utf8.cpp
@ -1037,7 +1005,7 @@ if (LINUX AND NOT ANDROID)
SET(RT_LIB rt)
endif()
target_link_libraries(native ${LIBZIP_LIBRARY} ${ZLIB_LIBRARY} ${PNG_LIBRARY} rg_etc1 vjson stb_vorbis snappy udis86 ${RT_LIB} ${GLEW_LIBRARIES})
target_link_libraries(native ${LIBZIP_LIBRARY} ${ZLIB_LIBRARY} ${PNG_LIBRARY} rg_etc1 vjson snappy udis86 ${RT_LIB} ${GLEW_LIBRARIES})
if(ANDROID)
target_link_libraries(native log EGL)

View File

@ -36,12 +36,6 @@ SOURCES += $$P/ext/native/ext/jpge/*.cpp
HEADERS += $$P/ext/native/ext/jpge/*.h
INCLUDEPATH += $$P/ext/native/ext/jpge
# Stb_vorbis
SOURCES += $$P/ext/native/ext/stb_vorbis/stb_vorbis.c
HEADERS += $$P/ext/native/ext/stb_vorbis/stb_vorbis.h
INCLUDEPATH += $$P/ext/native/ext/stb_vorbis
# Snappy
!exists( /usr/include/snappy-c.h ) {
SOURCES += $$P/ext/snappy/*.cpp
@ -77,23 +71,19 @@ win32|contains(QT_CONFIG, no-zlib) {
# Native
SOURCES += $$P/ext/native/audio/*.cpp \
SOURCES += \
$$P/ext/native/base/backtrace.cpp \
$$P/ext/native/base/buffer.cpp \
$$P/ext/native/base/colorutil.cpp \
$$P/ext/native/base/compat.cpp \
$$P/ext/native/base/display.cpp \
$$P/ext/native/base/error_context.cpp \
$$P/ext/native/base/fastlist_test.cpp \
$$P/ext/native/base/stringutil.cpp \
$$P/ext/native/base/timeutil.cpp \
$$P/ext/native/data/compression.cpp \
$$P/ext/native/file/*.cpp \
$$P/ext/native/gfx/gl_debug_log.cpp \
$$P/ext/native/gfx/gl_lost_manager.cpp \
$$P/ext/native/gfx/texture.cpp \
$$P/ext/native/gfx/texture_atlas.cpp \
$$P/ext/native/gfx/texture_gen.cpp \
$$P/ext/native/gfx_es2/*.cpp \
$$P/ext/native/gfx_es2/*.c \
$$P/ext/native/i18n/*.cpp \
@ -110,29 +100,22 @@ SOURCES += $$P/ext/native/audio/*.cpp \
$$P/ext/native/thin3d/thin3d_gl.cpp \
$$P/ext/native/thread/*.cpp \
$$P/ext/native/ui/*.cpp \
$$P/ext/native/util/bits/*.cpp \
$$P/ext/native/util/hash/hash.cpp \
$$P/ext/native/util/random/perlin.cpp \
$$P/ext/native/util/text/utf8.cpp \
$$P/ext/native/util/text/parsers.cpp
armv7: SOURCES += $$files($$P/ext/native/math/fast/fast_matrix_neon.S)
HEADERS += $$P/ext/native/audio/*.h \
HEADERS += \
$$P/ext/native/base/backtrace.h \
$$P/ext/native/base/basictypes.h \
$$P/ext/native/base/buffer.h \
$$P/ext/native/base/color.h \
$$P/ext/native/base/colorutil.h \
$$P/ext/native/base/display.h \
$$P/ext/native/base/error_context.h \
$$P/ext/native/base/fastlist.h \
$$P/ext/native/base/linked_ptr.h \
$$P/ext/native/base/logging.h \
$$P/ext/native/base/mutex.h \
$$P/ext/native/base/scoped_ptr.h \
$$P/ext/native/base/stats.h \
$$P/ext/native/base/stringutil.h \
$$P/ext/native/base/timeutil.h \
$$P/ext/native/data/compression.h \
@ -149,7 +132,6 @@ HEADERS += $$P/ext/native/audio/*.h \
$$P/ext/native/profiler/profiler.h \
$$P/ext/native/thread/*.h \
$$P/ext/native/ui/*.h \
$$P/ext/native/util/bits/*.h \
$$P/ext/native/util/hash/hash.h \
$$P/ext/native/util/random/*.h \
$$P/ext/native/util/text/utf8.h \

View File

@ -51,7 +51,6 @@
#include "gfx_es2/draw_text.h"
#include "gfx_es2/gpu_features.h"
#include "gfx/gl_lost_manager.h"
#include "gfx/texture.h"
#include "i18n/i18n.h"
#include "input/input_state.h"
#include "math/fast/fast_math.h"

View File

@ -22,7 +22,6 @@
#include "file/zip_read.h"
#include "input/input_state.h"
#include "profiler/profiler.h"
#include "audio/mixer.h"
#include "math/math_util.h"
#include "net/resolve.h"
#include "android/jni/native_audio.h"

View File

@ -1,92 +0,0 @@
/usr/bin/c++
-std=gnu++0x
CMakeFiles/ppsspp.dir/home/artart78/prog/psp/ppsspp/android/jni/NativeApp.cpp.o
CMakeFiles/ppsspp.dir/home/artart78/prog/psp/ppsspp/android/jni/EmuScreen.cpp.o
CMakeFiles/ppsspp.dir/home/artart78/prog/psp/ppsspp/android/jni/MenuScreens.cpp.o
CMakeFiles/ppsspp.dir/home/artart78/prog/psp/ppsspp/android/jni/GamepadEmu.cpp.o
CMakeFiles/ppsspp.dir/home/artart78/prog/psp/ppsspp/android/jni/UIShader.cpp.o
CMakeFiles/ppsspp.dir/home/artart78/prog/psp/ppsspp/android/jni/ui_atlas.cpp.o
CMakeFiles/ppsspp.dir/home/artart78/prog/psp/ppsspp/native/base/PCMain.cpp.o
-o
ppsspp
-rdynamic
-L/usr/local/lib
-L/opt/local/lib
-L/usr/X11/lib
-Wl,-Bstatic
-lSDLmain
-Wl,-Bdynamic
-lSDL
-lpthread
-lGLU
-lGL
-lSM
-lICE
-lX11
-lXext
-lGLEW
kirk/libkirk.a
file/libfile.a
kirk/libkirk.a
math/liblin.a
kirk/libkirk.a
-lpng
kirk/libkirk.a
-lz
kirk/libkirk.a
gfx/libgfx.a
kirk/libkirk.a
gfx_es2/libgfx_es2.a
kirk/libkirk.a
etcpack/libetcdec.a
kirk/libkirk.a
image/libimage.a
kirk/libkirk.a
stb_image/libstb_image.a
kirk/libkirk.a
audio/libmixer.a
kirk/libkirk.a
net/libnet.a
kirk/libkirk.a
ui/libui.a
kirk/libkirk.a
profiler/libprofiler.a
kirk/libkirk.a
base/libtimeutil.a
kirk/libkirk.a
libzip/libzip.a
kirk/libkirk.a
base/libbase.a
kirk/libkirk.a
math/liblin.a
kirk/libkirk.a
vjson/libvjson.a
kirk/libkirk.a
stb_vorbis/libstb_vorbis.a
kirk/libkirk.a
sha1/libsha1.a
kirk/libkirk.a
jsonwriter/libjsonwriter.a
kirk/libkirk.a
Common/libcommon.a
kirk/libkirk.a
Core/libcore.a
kirk/libkirk.a
GPU/libgpu.a
kirk/libkirk.a
base/libbase.a
kirk/libkirk.a
Common/libcommon.a
kirk/libkirk.a
math/liblin.a
kirk/libkirk.a
gfx_es2/libgfx_es2.a
kirk/libkirk.a
file/libfile.a
kirk/libkirk.a
libzip/libzip.a
kirk/libkirk.a
gfx/libgfx.a
kirk/libkirk.a
-Wl,-rpath,/usr/local/lib:/opt/local/lib:/usr/X11/lib

View File

@ -7,15 +7,12 @@ include $(CLEAR_VARS)
LOCAL_MODULE := libnative
LOCAL_ARM_MODE := arm
LOCAL_SRC_FILES :=\
audio/wav_read.cpp \
audio/mixer.cpp.arm \
base/backtrace.cpp \
base/buffer.cpp \
base/compat.cpp \
base/display.cpp \
base/timeutil.cpp \
base/colorutil.cpp \
base/error_context.cpp \
base/stringutil.cpp \
data/compression.cpp \
ext/rg_etc1/rg_etc1.cpp \
@ -39,10 +36,8 @@ LOCAL_SRC_FILES :=\
ext/jpge/jpgd.cpp \
ext/jpge/jpge.cpp \
ext/sha1/sha1.cpp \
ext/stb_vorbis/stb_vorbis.c.arm \
ext/vjson/json.cpp \
ext/vjson/block_allocator.cpp \
file/dialog.cpp \
file/fd_util.cpp \
file/easy_file.cpp \
file/chunk_file.cpp \
@ -59,12 +54,10 @@ LOCAL_SRC_FILES :=\
math/math_util.cpp \
math/curves.cpp \
math/expression_parser.cpp \
math/lin/aabb.cpp.arm \
math/lin/plane.cpp.arm \
math/lin/quat.cpp.arm \
math/lin/vec3.cpp.arm \
math/lin/matrix4x4.cpp.arm \
midi/midi_input.cpp \
net/http_client.cpp \
net/http_server.cpp \
net/http_headers.cpp \
@ -80,12 +73,9 @@ LOCAL_SRC_FILES :=\
gfx_es2/gl3stub.c \
gfx_es2/draw_buffer.cpp.arm \
gfx_es2/draw_text.cpp.arm \
gfx_es2/vertex_format.cpp \
gfx/gl_debug_log.cpp \
gfx/gl_lost_manager.cpp \
gfx/texture.cpp \
gfx/texture_atlas.cpp \
gfx/texture_gen.cpp \
image/zim_load.cpp \
image/zim_save.cpp \
image/png_load.cpp \
@ -98,7 +88,6 @@ LOCAL_SRC_FILES :=\
ui/ui_context.cpp \
ui/screen.cpp \
ui/virtual_input.cpp \
util/random/perlin.cpp \
util/text/utf8.cpp \
util/text/parsers.cpp \
util/hash/hash.cpp

View File

@ -1,50 +0,0 @@
native
======
This is my library of stuff that I use when writing C++ programs, mostly for Android but it's all written to enable easy portability between Android, Linux, Windows and MacOSX. The code is part ugly, part inconsistent but quite useful.
Features
--------
* JSON read/write (two libraries that should be made more similar)
* basic OpenGL utility code, like compressed texture loading
* 2D texture atlases and drawing code
* ETC1 texture save/load support
* basic logging
* Really simple audio mixer with OGG sample support
* RIFF file read/write
* MIDI Input (only on Windows)
Notes
-----
* The associated tools to create ZIM texture files and atlases do not yet live here but I might move them here eventually.
* This library is not really meant to be a public library but I see no reason not to set it free.
* Note that the included VS project is probably not very useful for you and you're likely better off making your own.
* Don't complain about inconsistent naming etc - this consists of code that has been cobbled together from a variety of my projects through the years. Fashions come and go.
Licenses
--------
This library, for my convenience, incorporates code from a variety of public domain or similarly-licensed code. This is the list:
* glew (GL extension wrangler), MIT license. TODO: should just use a submodule.
* rg_etc1. ZLIB license.
* sha1, public domain implementation by Dominik Reichl
* vjson in a heavily modified form, originally by Ivan Vashchaev (TODO: break out into its own repo?)
* libzip with attribution "Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner"
* stb_vorbis, public domain by Sean Barrett of RAD Tools
If you're not okay with the licenses above, don't use this code.
I hereby release all code here not under the licenses above under the MIT license.
Contact
-------
If you find this useful for your own projects, drop me a line at hrydgard@gmail.com .
Henrik Rydgård

View File

@ -1,11 +0,0 @@
set(SRCS
mixer.cpp
wav_read.cpp)
set(SRCS ${SRCS})
add_library(mixer STATIC ${SRCS})
if(UNIX)
add_definitions(-fPIC)
endif(UNIX)

View File

@ -1,201 +0,0 @@
#include <string.h>
#include "audio/mixer.h"
#include "audio/wav_read.h"
#include "base/logging.h"
#include "ext/stb_vorbis/stb_vorbis.h"
#include "file/vfs.h"
// TODO:
// * Vorbis streaming playback
struct ChannelEffectState {
// Filter state
};
enum CLIP_TYPE {
CT_PCM16,
CT_SYNTHFX,
CT_VORBIS,
// CT_PHOENIX?
};
struct Clip {
int type;
short *data;
int length;
int num_channels; // this is NOT stereo vs mono
int sample_rate;
int loop_start;
int loop_end;
};
// If current_clip == 0, the channel is free.
enum ClipPlaybackState {
PB_STOPPED = 0,
PB_PLAYING = 1,
};
struct Channel {
const Clip *current_clip;
// Playback state
ClipPlaybackState state;
int pos;
PlayParams params;
// Effect state
ChannelEffectState effect_state;
};
struct Mixer {
Channel *channels;
int sample_rate;
int num_channels;
int num_fixed_channels;
};
Mixer *mixer_create(int sample_rate, int channels, int fixed_channels) {
Mixer *mixer = new Mixer();
memset(mixer, 0, sizeof(Mixer));
mixer->channels = new Channel[channels];
memset(mixer->channels, 0, sizeof(Channel) * channels);
mixer->sample_rate = sample_rate;
mixer->num_channels = channels;
mixer->num_fixed_channels = fixed_channels;
return mixer;
}
void mixer_destroy(Mixer *mixer) {
delete [] mixer->channels;
delete mixer;
}
static int get_free_channel(Mixer *mixer) {
int chan_with_biggest_pos = -1;
int biggest_pos = -1;
for (int i = mixer->num_fixed_channels; i < mixer->num_channels; i++) {
Channel *chan = &mixer->channels[i];
if (!chan->current_clip) {
return i;
}
if (chan->pos > biggest_pos) {
biggest_pos = chan->pos;
chan_with_biggest_pos = i;
}
}
return chan_with_biggest_pos;
}
Clip *clip_load(const char *filename) {
short *data;
int num_samples;
int sample_rate, num_channels;
if (!strcmp(filename + strlen(filename) - 4, ".ogg")) {
// Ogg file. For now, directly decompress, no streaming support.
uint8_t *filedata;
size_t size;
filedata = VFSReadFile(filename, &size);
num_samples = (int)stb_vorbis_decode_memory(filedata, (int)size, &num_channels, &data);
if (num_samples <= 0)
return NULL;
sample_rate = 44100;
ILOG("read ogg %s, length %i, rate %i", filename, num_samples, sample_rate);
} else {
// Wav file. Easy peasy.
data = wav_read(filename, &num_samples, &sample_rate, &num_channels);
if (!data) {
return NULL;
}
}
Clip *clip = new Clip();
clip->type = CT_PCM16;
clip->data = data;
clip->length = num_samples;
clip->num_channels = num_channels;
clip->sample_rate = sample_rate;
clip->loop_start = 0;
clip->loop_end = 0;
return clip;
}
void clip_destroy(Clip *clip) {
if (clip) {
free(clip->data);
delete clip;
} else {
ELOG("Can't destroy zero clip");
}
}
const short *clip_data(const Clip *clip)
{
return clip->data;
}
size_t clip_length(const Clip *clip) {
return clip->length;
}
void clip_set_loop(Clip *clip, int start, int end) {
clip->loop_start = start;
clip->loop_end = end;
}
PlayParams *mixer_play_clip(Mixer *mixer, const Clip *clip, int channel) {
if (channel == -1) {
channel = get_free_channel(mixer);
}
Channel *chan = &mixer->channels[channel];
// Think about this order and make sure it's thread"safe" (not perfect but should not cause crashes).
chan->pos = 0;
chan->current_clip = clip;
chan->state = PB_PLAYING;
PlayParams *params = &chan->params;
params->volume = 128;
params->pan = 128;
return params;
}
void mixer_mix(Mixer *mixer, short *buffer, int num_samples) {
// Clear the buffer.
memset(buffer, 0, num_samples * sizeof(short) * 2);
for (int i = 0; i < mixer->num_channels; i++) {
Channel *chan = &mixer->channels[i];
if (chan->state == PB_PLAYING) {
const Clip *clip = chan->current_clip;
if (clip->type == CT_PCM16) {
// For now, only allow mono PCM
CHECK(clip->num_channels == 1);
if (true || chan->params.delta == 0) {
// Fast playback of non pitched clips
int cnt = num_samples;
if (clip->length - chan->pos < cnt) {
cnt = clip->length - chan->pos;
}
// TODO: Take pan into account.
int left_volume = chan->params.volume;
int right_volume = chan->params.volume;
// TODO: NEONize. Can also make special loops for left_volume == right_volume etc.
for (int s = 0; s < cnt; s++) {
int cdata = clip->data[chan->pos];
buffer[s * 2 + 0] += cdata * left_volume >> 8;
buffer[s * 2 + 1] += cdata * right_volume >> 8;
chan->pos++;
}
if (chan->pos >= clip->length) {
chan->state = PB_STOPPED;
chan->current_clip = 0;
break;
}
}
} else if (clip->type == CT_VORBIS) {
// For music
}
}
}
}

View File

@ -1,43 +0,0 @@
#pragma once
#include "base/basictypes.h"
// Simple mixer intended for sound effects for games.
// The clip loading code supports ogg SFX.
struct Mixer;
struct Clip;
struct Channel;
// This struct is public for easy manipulation of running channels.
struct PlayParams {
uint8_t volume; // 0-255
uint8_t pan; // 0-255, 127 is dead center.
int32_t delta;
};
// Mixer
// ==========================
// For now, channels is required to be 2 (it specifies L/R, not mixing channels)
Mixer *mixer_create(int sample_rate, int channels, int fixed_channels);
void mixer_destroy(Mixer *mixer);
// Buffer must be r/w.
void mixer_mix(Mixer *mixer, short *buffer, int num_samples);
// Clip
// ==========================
Clip *clip_load(const char *filename);
void clip_destroy(Clip *clip);
const short *clip_data(const Clip *clip);
size_t clip_length(const Clip *clip);
void clip_set_loop(int start, int end);
// The returned PlayState pointer can be used to set the playback parameters,
// but must not be kept around unless you are using a fixed channel.
// Channel must be either -1 for auto assignment to a free channel, or less
// than the number of fixed channels that the mixer was created with.
PlayParams *mixer_play_clip(Mixer *mixer, const Clip *clip, int channel);

View File

@ -1,70 +0,0 @@
#include "base/basictypes.h"
#include "base/logging.h"
#include "audio/wav_read.h"
#include "file/chunk_file.h"
short *wav_read(const char *filename,
int *num_samples, int *sample_rate,
int *num_channels)
{
ChunkFile cf(filename, true);
if (cf.failed()) {
WLOG("ERROR: Wave file %s could not be opened", filename);
return 0;
}
short *data = 0;
int samplesPerSec, avgBytesPerSec,wBlockAlign,wBytesPerSample;
if (cf.descend('RIFF')) {
cf.readInt(); //get past 'WAVE'
if (cf.descend('fmt ')) { //enter the format chunk
int temp = cf.readInt();
int format = temp & 0xFFFF;
if (format != 1) {
cf.ascend();
cf.ascend();
ELOG("Error - bad format");
return NULL;
}
*num_channels = temp >> 16;
samplesPerSec = cf.readInt();
avgBytesPerSec = cf.readInt();
temp = cf.readInt();
wBlockAlign = temp & 0xFFFF;
wBytesPerSample = temp >> 16;
cf.ascend();
// ILOG("got fmt data: %i", samplesPerSec);
} else {
ELOG("Error - no format chunk in wav");
cf.ascend();
return NULL;
}
if (cf.descend('data')) { //enter the data chunk
int numBytes = cf.getCurrentChunkSize();
int numSamples = numBytes / wBlockAlign;
data = (short *)malloc(sizeof(short) * numSamples * *num_channels);
*num_samples = numSamples;
if (wBlockAlign == 2 && *num_channels == 1) {
cf.readData((uint8_t *)data,numBytes);
} else {
ELOG("Error - bad blockalign or channels");
free(data);
return NULL;
}
cf.ascend();
} else {
ELOG("Error - no data chunk in wav");
cf.ascend();
return NULL;
}
cf.ascend();
} else {
ELOG("Could not descend into RIFF file");
return NULL;
}
*sample_rate = samplesPerSec;
ILOG("read wav %s, length %i, rate %i", filename, *num_samples, *sample_rate);
return data;
}

View File

@ -1,7 +0,0 @@
#include "base/basictypes.h"
// Allocates a buffer that should be freed using free().
short *wav_read(const char *filename,
int *num_samples, int *sample_rate,
int *num_channels);
// TODO: Non-allocating version.

View File

@ -2,7 +2,6 @@ set(SRCS
colorutil.cpp
timeutil.cpp
../thread/threadutil.cpp
error_context.cpp
display.cpp
buffer.cpp
backtrace.cpp)

View File

@ -1,16 +0,0 @@
#pragma once
typedef unsigned int Color;
//have to use a define to ensure constant folding.. with an inline I don't get that, sucks
#define COLOR(i) (((i&0xFF) << 16) | (i & 0xFF00) | ((i & 0xFF0000) >> 16) | 0xFF000000)
inline Color darkenColor(Color color) {
return (color & 0xFF000000) | ((color >> 1)&0x7F7F7F);
}
inline Color whitenColor(Color color) {
return ((color & 0xFF000000) | ((color >> 1)&0x7F7F7F)) + 0x7F7F7F;
}
inline Color colorInterpol(Color x, Color y, int n) {
// TODO
return x;
}

View File

@ -10,3 +10,17 @@ uint32_t alphaMul(uint32_t color, float alphaMul);
uint32_t rgba(float r, float g, float b, float alpha);
uint32_t rgba_clamp(float r, float g, float b, float alpha);
uint32_t hsva(float h, float s, float v, float alpha);
typedef unsigned int Color;
#define COLOR(i) (((i&0xFF) << 16) | (i & 0xFF00) | ((i & 0xFF0000) >> 16) | 0xFF000000)
inline Color darkenColor(Color color) {
return (color & 0xFF000000) | ((color >> 1) & 0x7F7F7F);
}
inline Color whitenColor(Color color) {
return ((color & 0xFF000000) | ((color >> 1) & 0x7F7F7F)) + 0x7F7F7F;
}
inline Color colorInterpol(Color x, Color y, int n) {
// TODO
return x;
}

View File

@ -1,40 +0,0 @@
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/error_context.h"
#include <vector>
// TODO: Fix this threadery
#ifndef _WIN32
#undef __THREAD
#define __THREAD
#endif
__THREAD std::vector<const char *> *_error_context_name;
__THREAD std::vector<const char *> *_error_context_data;
_ErrorContext::_ErrorContext(const char *name, const char *data) {
if (!_error_context_name) {
_error_context_name = new std::vector<const char *>();
_error_context_data = new std::vector<const char *>();
_error_context_name->reserve(16);
_error_context_data->reserve(16);
}
_error_context_name->push_back(name);
_error_context_data->push_back(data);
}
_ErrorContext::~_ErrorContext() {
_error_context_name->pop_back();
_error_context_data->pop_back();
}
void _ErrorContext::Log(const char *message) {
ILOG("EC: %s", message);
for (size_t i = 0; i < _error_context_name->size(); i++) {
if ((*_error_context_data)[i] != 0) {
ILOG("EC: %s: %s", (*_error_context_name)[i], (*_error_context_data)[i]);
} else {
ILOG("EC: %s: %s", (*_error_context_name)[i], (*_error_context_data)[i]);
}
}
}

View File

@ -1,18 +0,0 @@
#pragma once
// do not inherit
// TODO: Have the crash handler investigate the error context.
// Must only be constructed on the stack - DO NOT put these on the heap.
class _ErrorContext
{
public:
_ErrorContext(const char *name, const char *data = 0);
~_ErrorContext();
// Logs the current context stack.
static void Log(const char *message);
};
#define ErrorContext(...) _ErrorContext __ec(__VA_ARGS__)
#define LogErrorContext(msg) _ErrorContext::Log(msg)

View File

@ -1,39 +0,0 @@
#pragma once
// An inline fastlist is a fixed size array with a position counter.
// Objects stored in a fastlist must be copyable.
// [] returns the objects in consecutive order, up to and not including
// the value of .size().
// Order is not preserved when removing objects.
template<class T, int max_size>
class InlineFastList {
public:
InlineFastList() : count_(0) {}
~InlineFastList() {}
T& operator [](int index) { return data_[index]; }
const T& operator [](int index) const { return data_[index]; }
int size() const { return count_; }
void Add(T t) {
data_[count_++] = t;
}
void RemoveAt(int index) {
data_[index] = data_[count_ - 1];
count_--;
}
void Remove(T t) { // Requires operator==
for (int i = 0; i < count_; i++) {
if (data_[i] == t) {
RemoveAt(i);
return;
}
}
}
private:
T data_[max_size];
int count_;
};

View File

@ -1,19 +0,0 @@
#include "base/fastlist.h"
#include "base/logging.h"
/*
#include <gtest/gtest.h>
TEST(fastlist, AddRemove) {
InlineFastList<int, 8> list;
list.Add(8);
list.Remove(7);
EXPECT_EQ(1, list.size());
list.Remove(8);
EXPECT_EQ(0, list.size());
list.Add(1);
list.Add(2);
list.Add(3);
EXPECT_EQ(3, list.size());
}
*/

View File

@ -1,30 +0,0 @@
#pragma once
// Trivial implementation of boost::scoped_ptr, in a way that I prefer.
template<class T>
class scoped_ptr {
public:
scoped_ptr() : ptr_(0) {}
scoped_ptr(T *p) : ptr_(p) {}
~scoped_ptr() {
delete ptr_;
}
void reset(T *p) {
delete ptr_;
ptr_ = p;
}
T *release() {
T *p = ptr_;
ptr_ = 0;
return p;
}
T *operator->() { return ptr_; }
const T *operator->() const { return ptr_; }
const T *get() const { return ptr_; }
T *get() { return ptr_; }
private:
scoped_ptr(const scoped_ptr<T> &other);
void operator=(const scoped_ptr<T> &other);
T *ptr_;
};

View File

@ -1,18 +0,0 @@
#pragma once
// Statistics collection. Not very developed.
#define STATS_ENABLE
#ifdef STATS_ENABLE
void IncrementStat(const char *name);
#define INCSTAT(name) IncrementStat(name);
#else
#define INCSTAT(name)
#endif

View File

@ -1,52 +0,0 @@
Use of this software is granted under one of the following two licenses,
to be chosen freely by the user.
1. Boost Software License - Version 1.0 - August 17th, 2003
===============================================================================
Copyright (c) 2006, 2007 Marcin Kalicinski
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
2. The MIT License
===============================================================================
Copyright (c) 2006, 2007 Marcin Kalicinski
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,174 +0,0 @@
#ifndef RAPIDXML_ITERATORS_HPP_INCLUDED
#define RAPIDXML_ITERATORS_HPP_INCLUDED
// Copyright (C) 2006, 2009 Marcin Kalicinski
// Version 1.13
// Revision $DateTime: 2009/05/13 01:46:17 $
//! \file rapidxml_iterators.hpp This file contains rapidxml iterators
#include "rapidxml.hpp"
namespace rapidxml
{
//! Iterator of child nodes of xml_node
template<class Ch>
class node_iterator
{
public:
typedef typename xml_node<Ch> value_type;
typedef typename xml_node<Ch> &reference;
typedef typename xml_node<Ch> *pointer;
typedef std::ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
node_iterator()
: m_node(0)
{
}
node_iterator(xml_node<Ch> *node)
: m_node(node->first_node())
{
}
reference operator *() const
{
assert(m_node);
return *m_node;
}
pointer operator->() const
{
assert(m_node);
return m_node;
}
node_iterator& operator++()
{
assert(m_node);
m_node = m_node->next_sibling();
return *this;
}
node_iterator operator++(int)
{
node_iterator tmp = *this;
++this;
return tmp;
}
node_iterator& operator--()
{
assert(m_node && m_node->previous_sibling());
m_node = m_node->previous_sibling();
return *this;
}
node_iterator operator--(int)
{
node_iterator tmp = *this;
++this;
return tmp;
}
bool operator ==(const node_iterator<Ch> &rhs)
{
return m_node == rhs.m_node;
}
bool operator !=(const node_iterator<Ch> &rhs)
{
return m_node != rhs.m_node;
}
private:
xml_node<Ch> *m_node;
};
//! Iterator of child attributes of xml_node
template<class Ch>
class attribute_iterator
{
public:
typedef typename xml_attribute<Ch> value_type;
typedef typename xml_attribute<Ch> &reference;
typedef typename xml_attribute<Ch> *pointer;
typedef std::ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
attribute_iterator()
: m_attribute(0)
{
}
attribute_iterator(xml_node<Ch> *node)
: m_attribute(node->first_attribute())
{
}
reference operator *() const
{
assert(m_attribute);
return *m_attribute;
}
pointer operator->() const
{
assert(m_attribute);
return m_attribute;
}
attribute_iterator& operator++()
{
assert(m_attribute);
m_attribute = m_attribute->next_attribute();
return *this;
}
attribute_iterator operator++(int)
{
attribute_iterator tmp = *this;
++this;
return tmp;
}
attribute_iterator& operator--()
{
assert(m_attribute && m_attribute->previous_attribute());
m_attribute = m_attribute->previous_attribute();
return *this;
}
attribute_iterator operator--(int)
{
attribute_iterator tmp = *this;
++this;
return tmp;
}
bool operator ==(const attribute_iterator<Ch> &rhs)
{
return m_attribute == rhs.m_attribute;
}
bool operator !=(const attribute_iterator<Ch> &rhs)
{
return m_attribute != rhs.m_attribute;
}
private:
xml_attribute<Ch> *m_attribute;
};
}
#endif

View File

@ -1,421 +0,0 @@
#ifndef RAPIDXML_PRINT_HPP_INCLUDED
#define RAPIDXML_PRINT_HPP_INCLUDED
// Copyright (C) 2006, 2009 Marcin Kalicinski
// Version 1.13
// Revision $DateTime: 2009/05/13 01:46:17 $
//! \file rapidxml_print.hpp This file contains rapidxml printer implementation
#include "rapidxml.hpp"
// Only include streams if not disabled
#ifndef RAPIDXML_NO_STREAMS
#include <ostream>
#include <iterator>
#endif
namespace rapidxml
{
///////////////////////////////////////////////////////////////////////
// Printing flags
const int print_no_indenting = 0x1; //!< Printer flag instructing the printer to suppress indenting of XML. See print() function.
///////////////////////////////////////////////////////////////////////
// Internal
//! \cond internal
namespace internal
{
///////////////////////////////////////////////////////////////////////////
// Internal character operations
// Copy characters from given range to given output iterator
template<class OutIt, class Ch>
inline OutIt copy_chars(const Ch *begin, const Ch *end, OutIt out)
{
while (begin != end)
*out++ = *begin++;
return out;
}
// Copy characters from given range to given output iterator and expand
// characters into references (&lt; &gt; &apos; &quot; &amp;)
template<class OutIt, class Ch>
inline OutIt copy_and_expand_chars(const Ch *begin, const Ch *end, Ch noexpand, OutIt out)
{
while (begin != end)
{
if (*begin == noexpand)
{
*out++ = *begin; // No expansion, copy character
}
else
{
switch (*begin)
{
case Ch('<'):
*out++ = Ch('&'); *out++ = Ch('l'); *out++ = Ch('t'); *out++ = Ch(';');
break;
case Ch('>'):
*out++ = Ch('&'); *out++ = Ch('g'); *out++ = Ch('t'); *out++ = Ch(';');
break;
case Ch('\''):
*out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('p'); *out++ = Ch('o'); *out++ = Ch('s'); *out++ = Ch(';');
break;
case Ch('"'):
*out++ = Ch('&'); *out++ = Ch('q'); *out++ = Ch('u'); *out++ = Ch('o'); *out++ = Ch('t'); *out++ = Ch(';');
break;
case Ch('&'):
*out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('m'); *out++ = Ch('p'); *out++ = Ch(';');
break;
default:
*out++ = *begin; // No expansion, copy character
}
}
++begin; // Step to next character
}
return out;
}
// Fill given output iterator with repetitions of the same character
template<class OutIt, class Ch>
inline OutIt fill_chars(OutIt out, int n, Ch ch)
{
for (int i = 0; i < n; ++i)
*out++ = ch;
return out;
}
// Find character
template<class Ch, Ch ch>
inline bool find_char(const Ch *begin, const Ch *end)
{
while (begin != end)
if (*begin++ == ch)
return true;
return false;
}
///////////////////////////////////////////////////////////////////////////
// Internal printing operations
// Print node
template<class OutIt, class Ch>
inline OutIt print_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
// Print proper node type
switch (node->type())
{
// Document
case node_document:
out = print_children(out, node, flags, indent);
break;
// Element
case node_element:
out = print_element_node(out, node, flags, indent);
break;
// Data
case node_data:
out = print_data_node(out, node, flags, indent);
break;
// CDATA
case node_cdata:
out = print_cdata_node(out, node, flags, indent);
break;
// Declaration
case node_declaration:
out = print_declaration_node(out, node, flags, indent);
break;
// Comment
case node_comment:
out = print_comment_node(out, node, flags, indent);
break;
// Doctype
case node_doctype:
out = print_doctype_node(out, node, flags, indent);
break;
// Pi
case node_pi:
out = print_pi_node(out, node, flags, indent);
break;
// Unknown
default:
assert(0);
break;
}
// If indenting not disabled, add line break after node
if (!(flags & print_no_indenting))
*out = Ch('\n'), ++out;
// Return modified iterator
return out;
}
// Print children of the node
template<class OutIt, class Ch>
inline OutIt print_children(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
for (xml_node<Ch> *child = node->first_node(); child; child = child->next_sibling())
out = print_node(out, child, flags, indent);
return out;
}
// Print attributes of the node
template<class OutIt, class Ch>
inline OutIt print_attributes(OutIt out, const xml_node<Ch> *node, int flags)
{
for (xml_attribute<Ch> *attribute = node->first_attribute(); attribute; attribute = attribute->next_attribute())
{
if (attribute->name() && attribute->value())
{
// Print attribute name
*out = Ch(' '), ++out;
out = copy_chars(attribute->name(), attribute->name() + attribute->name_size(), out);
*out = Ch('='), ++out;
// Print attribute value using appropriate quote type
if (find_char<Ch, Ch('"')>(attribute->value(), attribute->value() + attribute->value_size()))
{
*out = Ch('\''), ++out;
out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('"'), out);
*out = Ch('\''), ++out;
}
else
{
*out = Ch('"'), ++out;
out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('\''), out);
*out = Ch('"'), ++out;
}
}
}
return out;
}
// Print data node
template<class OutIt, class Ch>
inline OutIt print_data_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
assert(node->type() == node_data);
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out);
return out;
}
// Print data node
template<class OutIt, class Ch>
inline OutIt print_cdata_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
assert(node->type() == node_cdata);
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
*out = Ch('<'); ++out;
*out = Ch('!'); ++out;
*out = Ch('['); ++out;
*out = Ch('C'); ++out;
*out = Ch('D'); ++out;
*out = Ch('A'); ++out;
*out = Ch('T'); ++out;
*out = Ch('A'); ++out;
*out = Ch('['); ++out;
out = copy_chars(node->value(), node->value() + node->value_size(), out);
*out = Ch(']'); ++out;
*out = Ch(']'); ++out;
*out = Ch('>'); ++out;
return out;
}
// Print element node
template<class OutIt, class Ch>
inline OutIt print_element_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
assert(node->type() == node_element);
// Print element name and attributes, if any
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
*out = Ch('<'), ++out;
out = copy_chars(node->name(), node->name() + node->name_size(), out);
out = print_attributes(out, node, flags);
// If node is childless
if (node->value_size() == 0 && !node->first_node())
{
// Print childless node tag ending
*out = Ch('/'), ++out;
*out = Ch('>'), ++out;
}
else
{
// Print normal node tag ending
*out = Ch('>'), ++out;
// Test if node contains a single data node only (and no other nodes)
xml_node<Ch> *child = node->first_node();
if (!child)
{
// If node has no children, only print its value without indenting
out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out);
}
else if (child->next_sibling() == 0 && child->type() == node_data)
{
// If node has a sole data child, only print its value without indenting
out = copy_and_expand_chars(child->value(), child->value() + child->value_size(), Ch(0), out);
}
else
{
// Print all children with full indenting
if (!(flags & print_no_indenting))
*out = Ch('\n'), ++out;
out = print_children(out, node, flags, indent + 1);
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
}
// Print node end
*out = Ch('<'), ++out;
*out = Ch('/'), ++out;
out = copy_chars(node->name(), node->name() + node->name_size(), out);
*out = Ch('>'), ++out;
}
return out;
}
// Print declaration node
template<class OutIt, class Ch>
inline OutIt print_declaration_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
// Print declaration start
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
*out = Ch('<'), ++out;
*out = Ch('?'), ++out;
*out = Ch('x'), ++out;
*out = Ch('m'), ++out;
*out = Ch('l'), ++out;
// Print attributes
out = print_attributes(out, node, flags);
// Print declaration end
*out = Ch('?'), ++out;
*out = Ch('>'), ++out;
return out;
}
// Print comment node
template<class OutIt, class Ch>
inline OutIt print_comment_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
assert(node->type() == node_comment);
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
*out = Ch('<'), ++out;
*out = Ch('!'), ++out;
*out = Ch('-'), ++out;
*out = Ch('-'), ++out;
out = copy_chars(node->value(), node->value() + node->value_size(), out);
*out = Ch('-'), ++out;
*out = Ch('-'), ++out;
*out = Ch('>'), ++out;
return out;
}
// Print doctype node
template<class OutIt, class Ch>
inline OutIt print_doctype_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
assert(node->type() == node_doctype);
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
*out = Ch('<'), ++out;
*out = Ch('!'), ++out;
*out = Ch('D'), ++out;
*out = Ch('O'), ++out;
*out = Ch('C'), ++out;
*out = Ch('T'), ++out;
*out = Ch('Y'), ++out;
*out = Ch('P'), ++out;
*out = Ch('E'), ++out;
*out = Ch(' '), ++out;
out = copy_chars(node->value(), node->value() + node->value_size(), out);
*out = Ch('>'), ++out;
return out;
}
// Print pi node
template<class OutIt, class Ch>
inline OutIt print_pi_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
{
assert(node->type() == node_pi);
if (!(flags & print_no_indenting))
out = fill_chars(out, indent, Ch('\t'));
*out = Ch('<'), ++out;
*out = Ch('?'), ++out;
out = copy_chars(node->name(), node->name() + node->name_size(), out);
*out = Ch(' '), ++out;
out = copy_chars(node->value(), node->value() + node->value_size(), out);
*out = Ch('?'), ++out;
*out = Ch('>'), ++out;
return out;
}
}
//! \endcond
///////////////////////////////////////////////////////////////////////////
// Printing
//! Prints XML to given output iterator.
//! \param out Output iterator to print to.
//! \param node Node to be printed. Pass xml_document to print entire document.
//! \param flags Flags controlling how XML is printed.
//! \return Output iterator pointing to position immediately after last character of printed text.
template<class OutIt, class Ch>
inline OutIt print(OutIt out, const xml_node<Ch> &node, int flags = 0)
{
return internal::print_node(out, &node, flags, 0);
}
#ifndef RAPIDXML_NO_STREAMS
//! Prints XML to given output stream.
//! \param out Output stream to print to.
//! \param node Node to be printed. Pass xml_document to print entire document.
//! \param flags Flags controlling how XML is printed.
//! \return Output stream.
template<class Ch>
inline std::basic_ostream<Ch> &print(std::basic_ostream<Ch> &out, const xml_node<Ch> &node, int flags = 0)
{
print(std::ostream_iterator<Ch>(out), node, flags);
return out;
}
//! Prints formatted XML to given output stream. Uses default printing flags. Use print() function to customize printing process.
//! \param out Output stream to print to.
//! \param node Node to be printed.
//! \return Output stream.
template<class Ch>
inline std::basic_ostream<Ch> &operator <<(std::basic_ostream<Ch> &out, const xml_node<Ch> &node)
{
return print(out, node);
}
#endif
}
#endif

View File

@ -1,122 +0,0 @@
#ifndef RAPIDXML_UTILS_HPP_INCLUDED
#define RAPIDXML_UTILS_HPP_INCLUDED
// Copyright (C) 2006, 2009 Marcin Kalicinski
// Version 1.13
// Revision $DateTime: 2009/05/13 01:46:17 $
//! \file rapidxml_utils.hpp This file contains high-level rapidxml utilities that can be useful
//! in certain simple scenarios. They should probably not be used if maximizing performance is the main objective.
#include "rapidxml.hpp"
#include <vector>
#include <string>
#include <fstream>
#include <stdexcept>
namespace rapidxml
{
//! Represents data loaded from a file
template<class Ch = char>
class file
{
public:
//! Loads file into the memory. Data will be automatically destroyed by the destructor.
//! \param filename Filename to load.
file(const char *filename)
{
using namespace std;
// Open stream
basic_ifstream<Ch> stream(filename, ios::binary);
if (!stream)
throw runtime_error(string("cannot open file ") + filename);
stream.unsetf(ios::skipws);
// Determine stream size
stream.seekg(0, ios::end);
size_t size = stream.tellg();
stream.seekg(0);
// Load data and add terminating 0
m_data.resize(size + 1);
stream.read(&m_data.front(), static_cast<streamsize>(size));
m_data[size] = 0;
}
//! Loads file into the memory. Data will be automatically destroyed by the destructor
//! \param stream Stream to load from
file(std::basic_istream<Ch> &stream)
{
using namespace std;
// Load data and add terminating 0
stream.unsetf(ios::skipws);
m_data.assign(istreambuf_iterator<Ch>(stream), istreambuf_iterator<Ch>());
if (stream.fail() || stream.bad())
throw runtime_error("error reading stream");
m_data.push_back(0);
}
//! Gets file data.
//! \return Pointer to data of file.
Ch *data()
{
return &m_data.front();
}
//! Gets file data.
//! \return Pointer to data of file.
const Ch *data() const
{
return &m_data.front();
}
//! Gets file data size.
//! \return Size of file data, in characters.
std::size_t size() const
{
return m_data.size();
}
private:
std::vector<Ch> m_data; // File data
};
//! Counts children of node. Time complexity is O(n).
//! \return Number of children of node
template<class Ch>
inline std::size_t count_children(xml_node<Ch> *node)
{
xml_node<Ch> *child = node->first_node();
std::size_t count = 0;
while (child)
{
++count;
child = child->next_sibling();
}
return count;
}
//! Counts attributes of node. Time complexity is O(n).
//! \return Number of attributes of node
template<class Ch>
inline std::size_t count_attributes(xml_node<Ch> *node)
{
xml_attribute<Ch> *attr = node->first_attribute();
std::size_t count = 0;
while (attr)
{
++count;
attr = attr->next_attribute();
}
return count;
}
}
#endif

View File

@ -1,7 +0,0 @@
cmake_minimum_required(VERSION 2.6)
#if(UNIX)
add_definitions(-fPIC)
#endif(UNIX)
add_library(stb_image stb_image.c)

File diff suppressed because it is too large Load Diff

View File

@ -1,262 +0,0 @@
#pragma once
//// begin header file ////////////////////////////////////////////////////
//
// Limitations:
// - no jpeg progressive support
// - non-HDR formats support 8-bit samples only (jpeg, png)
// - no delayed line count (jpeg) -- IJG doesn't support either
// - no 1-bit BMP
// - GIF always returns *comp=4
//
// Basic usage (see HDR discussion below):
// int x,y,n;
// unsigned char *data = stbi_load(filename, &x, &y, &n, 0);
// // ... process data if not NULL ...
// // ... x = width, y = height, n = # 8-bit components per pixel ...
// // ... replace '0' with '1'..'4' to force that many components per pixel
// // ... but 'n' will always be the number that it would have been if you said 0
// stbi_image_free(data)
//
// Standard parameters:
// int *x -- outputs image width in pixels
// int *y -- outputs image height in pixels
// int *comp -- outputs # of image components in image file
// int req_comp -- if non-zero, # of image components requested in result
//
// The return value from an image loader is an 'unsigned char *' which points
// to the pixel data. The pixel data consists of *y scanlines of *x pixels,
// with each pixel consisting of N interleaved 8-bit components; the first
// pixel pointed to is top-left-most in the image. There is no padding between
// image scanlines or between pixels, regardless of format. The number of
// components N is 'req_comp' if req_comp is non-zero, or *comp otherwise.
// If req_comp is non-zero, *comp has the number of components that _would_
// have been output otherwise. E.g. if you set req_comp to 4, you will always
// get RGBA output, but you can check *comp to easily see if it's opaque.
//
// An output image with N components has the following components interleaved
// in this order in each pixel:
//
// N=#comp components
// 1 grey
// 2 grey, alpha
// 3 red, green, blue
// 4 red, green, blue, alpha
//
// If image loading fails for any reason, the return value will be NULL,
// and *x, *y, *comp will be unchanged. The function stbi_failure_reason()
// can be queried for an extremely brief, end-user unfriendly explanation
// of why the load failed. Define STBI_NO_FAILURE_STRINGS to avoid
// compiling these strings at all, and STBI_FAILURE_USERMSG to get slightly
// more user-friendly ones.
//
// Paletted PNG, BMP, GIF, and PIC images are automatically depalettized.
//
// ===========================================================================
//
// iPhone PNG support:
//
// By default we convert iphone-formatted PNGs back to RGB; nominally they
// would silently load as BGR, except the existing code should have just
// failed on such iPhone PNGs. But you can disable this conversion by
// by calling stbi_convert_iphone_png_to_rgb(0), in which case
// you will always just get the native iphone "format" through.
//
// Call stbi_set_unpremultiply_on_load(1) as well to force a divide per
// pixel to remove any premultiplied alpha *only* if the image file explicitly
// says there's premultiplied data (currently only happens in iPhone images,
// and only if iPhone convert-to-rgb processing is on).
//
// ===========================================================================
//
// HDR image support (disable by defining STBI_NO_HDR)
//
// stb_image now supports loading HDR images in general, and currently
// the Radiance .HDR file format, although the support is provided
// generically. You can still load any file through the existing interface;
// if you attempt to load an HDR file, it will be automatically remapped to
// LDR, assuming gamma 2.2 and an arbitrary scale factor defaulting to 1;
// both of these constants can be reconfigured through this interface:
//
// stbi_hdr_to_ldr_gamma(2.2f);
// stbi_hdr_to_ldr_scale(1.0f);
//
// (note, do not use _inverse_ constants; stbi_image will invert them
// appropriately).
//
// Additionally, there is a new, parallel interface for loading files as
// (linear) floats to preserve the full dynamic range:
//
// float *data = stbi_loadf(filename, &x, &y, &n, 0);
//
// If you load LDR images through this interface, those images will
// be promoted to floating point values, run through the inverse of
// constants corresponding to the above:
//
// stbi_ldr_to_hdr_scale(1.0f);
// stbi_ldr_to_hdr_gamma(2.2f);
//
// Finally, given a filename (or an open file or memory block--see header
// file for details) containing image data, you can query for the "most
// appropriate" interface to use (that is, whether the image is HDR or
// not), using:
//
// stbi_is_hdr(char *filename);
//
// ===========================================================================
//
// I/O callbacks
//
// I/O callbacks allow you to read from arbitrary sources, like packaged
// files or some other source. Data read from callbacks are processed
// through a small internal buffer (currently 128 bytes) to try to reduce
// overhead.
//
// The three functions you must define are "read" (reads some bytes of data),
// "skip" (skips some bytes of data), "eof" (reports if the stream is at the end).
#ifndef STBI_NO_STDIO
#if defined(_MSC_VER) && _MSC_VER >= 0x1400
#define _CRT_SECURE_NO_WARNINGS // suppress bogus warnings about fopen()
#endif
#include <stdio.h>
#endif
#define STBI_VERSION 1
enum
{
STBI_default = 0, // only used for req_comp
STBI_grey = 1,
STBI_grey_alpha = 2,
STBI_rgb = 3,
STBI_rgb_alpha = 4
};
typedef unsigned char stbi_uc;
#ifdef __cplusplus
extern "C" {
#endif
//////////////////////////////////////////////////////////////////////////////
//
// PRIMARY API - works on images of any type
//
//
// load image by filename, open file, or memory buffer
//
extern stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
#ifndef STBI_NO_STDIO
extern stbi_uc *stbi_load (char const *filename, int *x, int *y, int *comp, int req_comp);
extern stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
// for stbi_load_from_file, file pointer is left pointing immediately after image
#endif
typedef struct
{
int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read
void (*skip) (void *user,unsigned n); // skip the next 'n' bytes
int (*eof) (void *user); // returns nonzero if we are at end of file/data
} stbi_io_callbacks;
extern stbi_uc *stbi_load_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp);
#ifndef STBI_NO_HDR
extern float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp);
#ifndef STBI_NO_STDIO
extern float *stbi_loadf (char const *filename, int *x, int *y, int *comp, int req_comp);
extern float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *comp, int req_comp);
#endif
extern float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp);
extern void stbi_hdr_to_ldr_gamma(float gamma);
extern void stbi_hdr_to_ldr_scale(float scale);
extern void stbi_ldr_to_hdr_gamma(float gamma);
extern void stbi_ldr_to_hdr_scale(float scale);
#endif // STBI_NO_HDR
// stbi_is_hdr is always defined
extern int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user);
extern int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len);
#ifndef STBI_NO_STDIO
extern int stbi_is_hdr (char const *filename);
extern int stbi_is_hdr_from_file(FILE *f);
#endif // STBI_NO_STDIO
// get a VERY brief reason for failure
// NOT THREADSAFE
extern const char *stbi_failure_reason (void);
// free the loaded image -- this is just free()
extern void stbi_image_free (void *retval_from_stbi_load);
// get image dimensions & components without fully decoding
extern int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp);
extern int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp);
#ifndef STBI_NO_STDIO
extern int stbi_info (char const *filename, int *x, int *y, int *comp);
extern int stbi_info_from_file (FILE *f, int *x, int *y, int *comp);
#endif
// for image formats that explicitly notate that they have premultiplied alpha,
// we just return the colors as stored in the file. set this flag to force
// unpremultiplication. results are undefined if the unpremultiply overflow.
extern void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply);
// indicate whether we should process iphone images back to canonical format,
// or just pass them through "as-is"
extern void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert);
// ZLIB client - used by PNG, available for other purposes
extern char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen);
extern char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen);
extern int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen);
extern char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen);
extern int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen);
// define faster low-level operations (typically SIMD support)
#ifdef STBI_SIMD
typedef void (*stbi_idct_8x8)(stbi_uc *out, int out_stride, short data[64], unsigned short *dequantize);
// compute an integer IDCT on "input"
// input[x] = data[x] * dequantize[x]
// write results to 'out': 64 samples, each run of 8 spaced by 'out_stride'
// CLAMP results to 0..255
typedef void (*stbi_YCbCr_to_RGB_run)(stbi_uc *output, stbi_uc const *y, stbi_uc const *cb, stbi_uc const *cr, int count, int step);
// compute a conversion from YCbCr to RGB
// 'count' pixels
// write pixels to 'output'; each pixel is 'step' bytes (either 3 or 4; if 4, write '255' as 4th), order R,G,B
// y: Y input channel
// cb: Cb input channel; scale/biased to be 0..255
// cr: Cr input channel; scale/biased to be 0..255
extern void stbi_install_idct(stbi_idct_8x8 func);
extern void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func);
#endif // STBI_SIMD
#ifdef __cplusplus
}
#endif
//
//
//// end header file /////////////////////////////////////////////////////

View File

@ -1,2 +0,0 @@
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "ext/stb_image_write/stb_image_writer.h"

View File

@ -1,511 +0,0 @@
/* stbiw-0.92 - public domain - http://nothings.org/stb/stb_image_write.h
writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010
no warranty implied; use at your own risk
Before including,
#define STB_IMAGE_WRITE_IMPLEMENTATION
in the file that you want to have the implementation.
ABOUT:
This header file is a library for writing images to C stdio. It could be
adapted to write to memory or a general streaming interface; let me know.
The PNG output is not optimal; it is 20-50% larger than the file
written by a decent optimizing implementation. This library is designed
for source code compactness and simplicitly, not optimal image file size
or run-time performance.
USAGE:
There are three functions, one for each image file format:
int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
Each function returns 0 on failure and non-0 on success.
The functions create an image file defined by the parameters. The image
is a rectangle of pixels stored from left-to-right, top-to-bottom.
Each pixel contains 'comp' channels of data stored interleaved with 8-bits
per channel, in the following order: 1=Y, 2=YA, 3=RGB, 4=RGBA. (Y is
monochrome color.) The rectangle is 'w' pixels wide and 'h' pixels tall.
The *data pointer points to the first byte of the top-left-most pixel.
For PNG, "stride_in_bytes" is the distance in bytes from the first byte of
a row of pixels to the first byte of the next row of pixels.
PNG creates output files with the same number of components as the input.
The BMP and TGA formats expand Y to RGB in the file format. BMP does not
output alpha.
PNG supports writing rectangles of data even when the bytes storing rows of
data are not consecutive in memory (e.g. sub-rectangles of a larger image),
by supplying the stride between the beginning of adjacent rows. The other
formats do not. (Thus you cannot write a native-format BMP through the BMP
writer, both because it is in BGR order and because it may have padding
at the end of the line.)
*/
#ifndef INCLUDE_STB_IMAGE_WRITE_H
#define INCLUDE_STB_IMAGE_WRITE_H
#ifdef __cplusplus
extern "C" {
#endif
extern int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
extern int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
extern int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
#ifdef __cplusplus
}
#endif
#endif//INCLUDE_STB_IMAGE_WRITE_H
#ifdef STB_IMAGE_WRITE_IMPLEMENTATION
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
typedef unsigned int stbiw_uint32;
typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1];
static void writefv(FILE *f, const char *fmt, va_list v)
{
while (*fmt) {
switch (*fmt++) {
case ' ': break;
case '1': { unsigned char x = (unsigned char) va_arg(v, int); fputc(x,f); break; }
case '2': { int x = va_arg(v,int); unsigned char b[2];
b[0] = (unsigned char) x; b[1] = (unsigned char) (x>>8);
fwrite(b,2,1,f); break; }
case '4': { stbiw_uint32 x = va_arg(v,int); unsigned char b[4];
b[0]=(unsigned char)x; b[1]=(unsigned char)(x>>8);
b[2]=(unsigned char)(x>>16); b[3]=(unsigned char)(x>>24);
fwrite(b,4,1,f); break; }
default:
assert(0);
return;
}
}
}
static void write3(FILE *f, unsigned char a, unsigned char b, unsigned char c)
{
unsigned char arr[3];
arr[0] = a, arr[1] = b, arr[2] = c;
fwrite(arr, 3, 1, f);
}
static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad)
{
unsigned char bg[3] = { 255, 0, 255}, px[3];
stbiw_uint32 zero = 0;
int i,j,k, j_end;
if (y <= 0)
return;
if (vdir < 0)
j_end = -1, j = y-1;
else
j_end = y, j = 0;
for (; j != j_end; j += vdir) {
for (i=0; i < x; ++i) {
unsigned char *d = (unsigned char *) data + (j*x+i)*comp;
if (write_alpha < 0)
fwrite(&d[comp-1], 1, 1, f);
switch (comp) {
case 1:
case 2: write3(f, d[0],d[0],d[0]);
break;
case 4:
if (!write_alpha) {
// composite against pink background
for (k=0; k < 3; ++k)
px[k] = bg[k] + ((d[k] - bg[k]) * d[3])/255;
write3(f, px[1-rgb_dir],px[1],px[1+rgb_dir]);
break;
}
/* FALLTHROUGH */
case 3:
write3(f, d[1-rgb_dir],d[1],d[1+rgb_dir]);
break;
}
if (write_alpha > 0)
fwrite(&d[comp-1], 1, 1, f);
}
fwrite(&zero,scanline_pad,1,f);
}
}
static int outfile(char const *filename, int rgb_dir, int vdir, int x, int y, int comp, void *data, int alpha, int pad, const char *fmt, ...)
{
FILE *f;
if (y < 0 || x < 0) return 0;
f = fopen(filename, "wb");
if (f) {
va_list v;
va_start(v, fmt);
writefv(f, fmt, v);
va_end(v);
write_pixels(f,rgb_dir,vdir,x,y,comp,data,alpha,pad);
fclose(f);
}
return f != NULL;
}
int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data)
{
int pad = (-x*3) & 3;
return outfile(filename,-1,-1,x,y,comp,(void *) data,0,pad,
"11 4 22 4" "4 44 22 444444",
'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header
40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header
}
int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data)
{
int has_alpha = !(comp & 1);
return outfile(filename, -1,-1, x, y, comp, (void *) data, has_alpha, 0,
"111 221 2222 11", 0,0,2, 0,0,0, 0,0,x,y, 24+8*has_alpha, 8*has_alpha);
}
// stretchy buffer; stbi__sbpush() == vector<>::push_back() -- stbi__sbcount() == vector<>::size()
#define stbi__sbraw(a) ((int *) (a) - 2)
#define stbi__sbm(a) stbi__sbraw(a)[0]
#define stbi__sbn(a) stbi__sbraw(a)[1]
#define stbi__sbneedgrow(a,n) ((a)==0 || stbi__sbn(a)+n >= stbi__sbm(a))
#define stbi__sbmaybegrow(a,n) (stbi__sbneedgrow(a,(n)) ? stbi__sbgrow(a,n) : 0)
#define stbi__sbgrow(a,n) stbi__sbgrowf((void **) &(a), (n), sizeof(*(a)))
#define stbi__sbpush(a, v) (stbi__sbmaybegrow(a,1), (a)[stbi__sbn(a)++] = (v))
#define stbi__sbcount(a) ((a) ? stbi__sbn(a) : 0)
#define stbi__sbfree(a) ((a) ? free(stbi__sbraw(a)),0 : 0)
static void *stbi__sbgrowf(void **arr, int increment, int itemsize)
{
int m = *arr ? 2*stbi__sbm(*arr)+increment : increment+1;
void *p = realloc(*arr ? stbi__sbraw(*arr) : 0, itemsize * m + sizeof(int)*2);
assert(p);
if (p) {
if (!*arr) ((int *) p)[1] = 0;
*arr = (void *) ((int *) p + 2);
stbi__sbm(*arr) = m;
}
return *arr;
}
static unsigned char *stbi__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount)
{
while (*bitcount >= 8) {
stbi__sbpush(data, (unsigned char) *bitbuffer);
*bitbuffer >>= 8;
*bitcount -= 8;
}
return data;
}
static int stbi__zlib_bitrev(int code, int codebits)
{
int res=0;
while (codebits--) {
res = (res << 1) | (code & 1);
code >>= 1;
}
return res;
}
static unsigned int stbi__zlib_countm(unsigned char *a, unsigned char *b, int limit)
{
int i;
for (i=0; i < limit && i < 258; ++i)
if (a[i] != b[i]) break;
return i;
}
static unsigned int stbi__zhash(unsigned char *data)
{
stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16);
hash ^= hash << 3;
hash += hash >> 5;
hash ^= hash << 4;
hash += hash >> 17;
hash ^= hash << 25;
hash += hash >> 6;
return hash;
}
#define stbi__zlib_flush() (out = stbi__zlib_flushf(out, &bitbuf, &bitcount))
#define stbi__zlib_add(code,codebits) \
(bitbuf |= (code) << bitcount, bitcount += (codebits), stbi__zlib_flush())
#define stbi__zlib_huffa(b,c) stbi__zlib_add(stbi__zlib_bitrev(b,c),c)
// default huffman tables
#define stbi__zlib_huff1(n) stbi__zlib_huffa(0x30 + (n), 8)
#define stbi__zlib_huff2(n) stbi__zlib_huffa(0x190 + (n)-144, 9)
#define stbi__zlib_huff3(n) stbi__zlib_huffa(0 + (n)-256,7)
#define stbi__zlib_huff4(n) stbi__zlib_huffa(0xc0 + (n)-280,8)
#define stbi__zlib_huff(n) ((n) <= 143 ? stbi__zlib_huff1(n) : (n) <= 255 ? stbi__zlib_huff2(n) : (n) <= 279 ? stbi__zlib_huff3(n) : stbi__zlib_huff4(n))
#define stbi__zlib_huffb(n) ((n) <= 143 ? stbi__zlib_huff1(n) : stbi__zlib_huff2(n))
#define stbi__ZHASH 16384
unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
{
static unsigned short lengthc[] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258, 259 };
static unsigned char lengtheb[]= { 0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 };
static unsigned short distc[] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 32768 };
static unsigned char disteb[] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 };
unsigned int bitbuf=0;
int i,j, bitcount=0;
unsigned char *out = NULL;
unsigned char **hash_table[stbi__ZHASH]; // 64KB on the stack!
if (quality < 5) quality = 5;
stbi__sbpush(out, 0x78); // DEFLATE 32K window
stbi__sbpush(out, 0x5e); // FLEVEL = 1
stbi__zlib_add(1,1); // BFINAL = 1
stbi__zlib_add(1,2); // BTYPE = 1 -- fixed huffman
for (i=0; i < stbi__ZHASH; ++i)
hash_table[i] = NULL;
i=0;
while (i < data_len-3) {
// hash next 3 bytes of data to be compressed
int h = stbi__zhash(data+i)&(stbi__ZHASH-1), best=3;
unsigned char *bestloc = 0;
unsigned char **hlist = hash_table[h];
int n = stbi__sbcount(hlist);
for (j=0; j < n; ++j) {
if (hlist[j]-data > i-32768) { // if entry lies within window
int d = stbi__zlib_countm(hlist[j], data+i, data_len-i);
if (d >= best) best=d,bestloc=hlist[j];
}
}
// when hash table entry is too long, delete half the entries
if (hash_table[h] && stbi__sbn(hash_table[h]) == 2*quality) {
memcpy(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality);
stbi__sbn(hash_table[h]) = quality;
}
stbi__sbpush(hash_table[h],data+i);
if (bestloc) {
// "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal
h = stbi__zhash(data+i+1)&(stbi__ZHASH-1);
hlist = hash_table[h];
n = stbi__sbcount(hlist);
for (j=0; j < n; ++j) {
if (hlist[j]-data > i-32767) {
int e = stbi__zlib_countm(hlist[j], data+i+1, data_len-i-1);
if (e > best) { // if next match is better, bail on current match
bestloc = NULL;
break;
}
}
}
}
if (bestloc) {
int d = data+i - bestloc; // distance back
assert(d <= 32767 && best <= 258);
for (j=0; best > lengthc[j+1]-1; ++j);
stbi__zlib_huff(j+257);
if (lengtheb[j]) stbi__zlib_add(best - lengthc[j], lengtheb[j]);
for (j=0; d > distc[j+1]-1; ++j);
stbi__zlib_add(stbi__zlib_bitrev(j,5),5);
if (disteb[j]) stbi__zlib_add(d - distc[j], disteb[j]);
i += best;
} else {
stbi__zlib_huffb(data[i]);
++i;
}
}
// write out final bytes
for (;i < data_len; ++i)
stbi__zlib_huffb(data[i]);
stbi__zlib_huff(256); // end of block
// pad with 0 bits to byte boundary
while (bitcount)
stbi__zlib_add(0,1);
for (i=0; i < stbi__ZHASH; ++i)
(void) stbi__sbfree(hash_table[i]);
{
// compute adler32 on input
unsigned int i=0, s1=1, s2=0, blocklen = data_len % 5552;
int j=0;
while (j < data_len) {
for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1;
s1 %= 65521, s2 %= 65521;
j += blocklen;
blocklen = 5552;
}
stbi__sbpush(out, (unsigned char) (s2 >> 8));
stbi__sbpush(out, (unsigned char) s2);
stbi__sbpush(out, (unsigned char) (s1 >> 8));
stbi__sbpush(out, (unsigned char) s1);
}
*out_len = stbi__sbn(out);
// make returned pointer freeable
memmove(stbi__sbraw(out), out, *out_len);
return (unsigned char *) stbi__sbraw(out);
}
unsigned int stbi__crc32(unsigned char *buffer, int len)
{
static unsigned int crc_table[256];
unsigned int crc = ~0u;
int i,j;
if (crc_table[1] == 0)
for(i=0; i < 256; i++)
for (crc_table[i]=i, j=0; j < 8; ++j)
crc_table[i] = (crc_table[i] >> 1) ^ (crc_table[i] & 1 ? 0xedb88320 : 0);
for (i=0; i < len; ++i)
crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
return ~crc;
}
#define stbi__wpng4(o,a,b,c,d) ((o)[0]=(unsigned char)(a),(o)[1]=(unsigned char)(b),(o)[2]=(unsigned char)(c),(o)[3]=(unsigned char)(d),(o)+=4)
#define stbi__wp32(data,v) stbi__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v));
#define stbi__wptag(data,s) stbi__wpng4(data, s[0],s[1],s[2],s[3])
static void stbi__wpcrc(unsigned char **data, int len)
{
unsigned int crc = stbi__crc32(*data - len - 4, len+4);
stbi__wp32(*data, crc);
}
static unsigned char stbi__paeth(int a, int b, int c)
{
int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c);
if (pa <= pb && pa <= pc) return (unsigned char) a;
if (pb <= pc) return (unsigned char) b;
return (unsigned char) c;
}
unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
{
int ctype[5] = { -1, 0, 4, 2, 6 };
unsigned char sig[8] = { 137,80,78,71,13,10,26,10 };
unsigned char *out,*o, *filt, *zlib;
signed char *line_buffer;
int i,j,k,p,zlen;
if (stride_bytes == 0)
stride_bytes = x * n;
filt = (unsigned char *) malloc((x*n+1) * y); if (!filt) return 0;
line_buffer = (signed char *) malloc(x * n); if (!line_buffer) { free(filt); return 0; }
for (j=0; j < y; ++j) {
static int mapping[] = { 0,1,2,3,4 };
static int firstmap[] = { 0,1,0,5,6 };
int *mymap = j ? mapping : firstmap;
int best = 0, bestval = 0x7fffffff;
for (p=0; p < 2; ++p) {
for (k= p?best:0; k < 5; ++k) {
int type = mymap[k],est=0;
unsigned char *z = pixels + stride_bytes*j;
for (i=0; i < n; ++i)
switch (type) {
case 0: line_buffer[i] = z[i]; break;
case 1: line_buffer[i] = z[i]; break;
case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break;
case 4: line_buffer[i] = (signed char) (z[i] - stbi__paeth(0,z[i-stride_bytes],0)); break;
case 5: line_buffer[i] = z[i]; break;
case 6: line_buffer[i] = z[i]; break;
}
for (i=n; i < x*n; ++i) {
switch (type) {
case 0: line_buffer[i] = z[i]; break;
case 1: line_buffer[i] = z[i] - z[i-n]; break;
case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break;
case 4: line_buffer[i] = z[i] - stbi__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break;
case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break;
case 6: line_buffer[i] = z[i] - stbi__paeth(z[i-n], 0,0); break;
}
}
if (p) break;
for (i=0; i < x*n; ++i)
est += abs((signed char) line_buffer[i]);
if (est < bestval) { bestval = est; best = k; }
}
}
// when we get here, best contains the filter type, and line_buffer contains the data
filt[j*(x*n+1)] = (unsigned char) best;
memcpy(filt+j*(x*n+1)+1, line_buffer, x*n);
}
free(line_buffer);
zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, 8); // increase 8 to get smaller but use more memory
free(filt);
if (!zlib) return 0;
// each tag requires 12 bytes of overhead
out = (unsigned char *) malloc(8 + 12+13 + 12+zlen + 12);
if (!out) return 0;
*out_len = 8 + 12+13 + 12+zlen + 12;
o=out;
memcpy(o,sig,8); o+= 8;
stbi__wp32(o, 13); // header length
stbi__wptag(o, "IHDR");
stbi__wp32(o, x);
stbi__wp32(o, y);
*o++ = 8;
*o++ = (unsigned char) ctype[n];
*o++ = 0;
*o++ = 0;
*o++ = 0;
stbi__wpcrc(&o,13);
stbi__wp32(o, zlen);
stbi__wptag(o, "IDAT");
memcpy(o, zlib, zlen); o += zlen; free(zlib);
stbi__wpcrc(&o, zlen);
stbi__wp32(o,0);
stbi__wptag(o, "IEND");
stbi__wpcrc(&o,0);
assert(o == out + *out_len);
return out;
}
int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes)
{
FILE *f;
int len;
unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
if (!png) return 0;
f = fopen(filename, "wb");
if (!f) { free(png); return 0; }
fwrite(png, 1, len, f);
fclose(f);
free(png);
return 1;
}
#endif // STB_IMAGE_WRITE_IMPLEMENTATION
/* Revision history
0.92 (2010-08-01)
casts to unsigned char to fix warnings
0.91 (2010-07-17)
first public release
0.90 first internal release
*/

View File

@ -1,10 +0,0 @@
cmake_minimum_required(VERSION 2.6)
#if(UNIX)
add_definitions(-fPIC)
add_definitions(-g)
add_definitions(-O2)
add_definitions(-Wall)
#endif(UNIX)
add_library(stb_vorbis stb_vorbis.c)

File diff suppressed because it is too large Load Diff

View File

@ -1,329 +0,0 @@
//////////////////////////////////////////////////////////////////////////////
//
// HEADER BEGINS HERE
//
#ifndef STB_VORBIS_INCLUDE_STB_VORBIS_H
#define STB_VORBIS_INCLUDE_STB_VORBIS_H
#if defined(STB_VORBIS_NO_CRT) && !defined(STB_VORBIS_NO_STDIO)
#define STB_VORBIS_NO_STDIO 1
#endif
#ifndef STB_VORBIS_NO_STDIO
#include <stdio.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/////////// THREAD SAFETY
// Individual stb_vorbis* handles are not thread-safe; you cannot decode from
// them from multiple threads at the same time. However, you can have multiple
// stb_vorbis* handles and decode from them independently in multiple thrads.
/////////// MEMORY ALLOCATION
// normally stb_vorbis uses malloc() to allocate memory at startup,
// and alloca() to allocate temporary memory during a frame on the
// stack. (Memory consumption will depend on the amount of setup
// data in the file and how you set the compile flags for speed
// vs. size. In my test files the maximal-size usage is ~150KB.)
//
// You can modify the wrapper functions in the source (setup_malloc,
// setup_temp_malloc, temp_malloc) to change this behavior, or you
// can use a simpler allocation model: you pass in a buffer from
// which stb_vorbis will allocate _all_ its memory (including the
// temp memory). "open" may fail with a VORBIS_outofmem if you
// do not pass in enough data; there is no way to determine how
// much you do need except to succeed (at which point you can
// query get_info to find the exact amount required. yes I know
// this is lame).
//
// If you pass in a non-NULL buffer of the type below, allocation
// will occur from it as described above. Otherwise just pass NULL
// to use malloc()/alloca()
typedef struct
{
char *alloc_buffer;
int alloc_buffer_length_in_bytes;
} stb_vorbis_alloc;
/////////// FUNCTIONS USEABLE WITH ALL INPUT MODES
typedef struct stb_vorbis stb_vorbis;
typedef struct
{
unsigned int sample_rate;
int channels;
unsigned int setup_memory_required;
unsigned int setup_temp_memory_required;
unsigned int temp_memory_required;
int max_frame_size;
} stb_vorbis_info;
// get general information about the file
extern stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f);
// get the last error detected (clears it, too)
extern int stb_vorbis_get_error(stb_vorbis *f);
// close an ogg vorbis file and free all memory in use
extern void stb_vorbis_close(stb_vorbis *f);
// this function returns the offset (in samples) from the beginning of the
// file that will be returned by the next decode, if it is known, or -1
// otherwise. after a flush_pushdata() call, this may take a while before
// it becomes valid again.
// NOT WORKING YET after a seek with PULLDATA API
extern int stb_vorbis_get_sample_offset(stb_vorbis *f);
// returns the current seek point within the file, or offset from the beginning
// of the memory buffer. In pushdata mode it returns 0.
extern unsigned int stb_vorbis_get_file_offset(stb_vorbis *f);
/////////// PUSHDATA API
#ifndef STB_VORBIS_NO_PUSHDATA_API
// this API allows you to get blocks of data from any source and hand
// them to stb_vorbis. you have to buffer them; stb_vorbis will tell
// you how much it used, and you have to give it the rest next time;
// and stb_vorbis may not have enough data to work with and you will
// need to give it the same data again PLUS more. Note that the Vorbis
// specification does not bound the size of an individual frame.
extern stb_vorbis *stb_vorbis_open_pushdata(
unsigned char *datablock, int datablock_length_in_bytes,
int *datablock_memory_consumed_in_bytes,
int *error,
stb_vorbis_alloc *alloc_buffer);
// create a vorbis decoder by passing in the initial data block containing
// the ogg&vorbis headers (you don't need to do parse them, just provide
// the first N bytes of the file--you're told if it's not enough, see below)
// on success, returns an stb_vorbis *, does not set error, returns the amount of
// data parsed/consumed on this call in *datablock_memory_consumed_in_bytes;
// on failure, returns NULL on error and sets *error, does not change *datablock_memory_consumed
// if returns NULL and *error is VORBIS_need_more_data, then the input block was
// incomplete and you need to pass in a larger block from the start of the file
extern int stb_vorbis_decode_frame_pushdata(
stb_vorbis *f, unsigned char *datablock, int datablock_length_in_bytes,
int *channels, // place to write number of float * buffers
float ***output, // place to write float ** array of float * buffers
int *samples // place to write number of output samples
);
// decode a frame of audio sample data if possible from the passed-in data block
//
// return value: number of bytes we used from datablock
// possible cases:
// 0 bytes used, 0 samples output (need more data)
// N bytes used, 0 samples output (resynching the stream, keep going)
// N bytes used, M samples output (one frame of data)
// note that after opening a file, you will ALWAYS get one N-bytes,0-sample
// frame, because Vorbis always "discards" the first frame.
//
// Note that on resynch, stb_vorbis will rarely consume all of the buffer,
// instead only datablock_length_in_bytes-3 or less. This is because it wants
// to avoid missing parts of a page header if they cross a datablock boundary,
// without writing state-machiney code to record a partial detection.
//
// The number of channels returned are stored in *channels (which can be
// NULL--it is always the same as the number of channels reported by
// get_info). *output will contain an array of float* buffers, one per
// channel. In other words, (*output)[0][0] contains the first sample from
// the first channel, and (*output)[1][0] contains the first sample from
// the second channel.
extern void stb_vorbis_flush_pushdata(stb_vorbis *f);
// inform stb_vorbis that your next datablock will not be contiguous with
// previous ones (e.g. you've seeked in the data); future attempts to decode
// frames will cause stb_vorbis to resynchronize (as noted above), and
// once it sees a valid Ogg page (typically 4-8KB, as large as 64KB), it
// will begin decoding the _next_ frame.
//
// if you want to seek using pushdata, you need to seek in your file, then
// call stb_vorbis_flush_pushdata(), then start calling decoding, then once
// decoding is returning you data, call stb_vorbis_get_sample_offset, and
// if you don't like the result, seek your file again and repeat.
#endif
////////// PULLING INPUT API
#ifndef STB_VORBIS_NO_PULLDATA_API
// This API assumes stb_vorbis is allowed to pull data from a source--
// either a block of memory containing the _entire_ vorbis stream, or a
// FILE * that you or it create, or possibly some other reading mechanism
// if you go modify the source to replace the FILE * case with some kind
// of callback to your code. (But if you don't support seeking, you may
// just want to go ahead and use pushdata.)
#if !defined(STB_VORBIS_NO_STDIO) && !defined(STB_VORBIS_NO_INTEGER_CONVERSION)
extern int stb_vorbis_decode_filename(char *filename, int *channels, short **output);
#endif
extern int stb_vorbis_decode_memory(unsigned char *mem, int len, int *channels, short **output);
// decode an entire file and output the data interleaved into a malloc()ed
// buffer stored in *output. The return value is the number of samples
// decoded, or -1 if the file could not be opened or was not an ogg vorbis file.
// When you're done with it, just free() the pointer returned in *output.
extern stb_vorbis * stb_vorbis_open_memory(unsigned char *data, int len,
int *error, stb_vorbis_alloc *alloc_buffer);
// create an ogg vorbis decoder from an ogg vorbis stream in memory (note
// this must be the entire stream!). on failure, returns NULL and sets *error
#ifndef STB_VORBIS_NO_STDIO
extern stb_vorbis * stb_vorbis_open_filename(char *filename,
int *error, stb_vorbis_alloc *alloc_buffer);
// create an ogg vorbis decoder from a filename via fopen(). on failure,
// returns NULL and sets *error (possibly to VORBIS_file_open_failure).
extern stb_vorbis * stb_vorbis_open_file(FILE *f, int close_handle_on_close,
int *error, stb_vorbis_alloc *alloc_buffer);
// create an ogg vorbis decoder from an open FILE *, looking for a stream at
// the _current_ seek point (ftell). on failure, returns NULL and sets *error.
// note that stb_vorbis must "own" this stream; if you seek it in between
// calls to stb_vorbis, it will become confused. Morever, if you attempt to
// perform stb_vorbis_seek_*() operations on this file, it will assume it
// owns the _entire_ rest of the file after the start point. Use the next
// function, stb_vorbis_open_file_section(), to limit it.
extern stb_vorbis * stb_vorbis_open_file_section(FILE *f, int close_handle_on_close,
int *error, stb_vorbis_alloc *alloc_buffer, unsigned int len);
// create an ogg vorbis decoder from an open FILE *, looking for a stream at
// the _current_ seek point (ftell); the stream will be of length 'len' bytes.
// on failure, returns NULL and sets *error. note that stb_vorbis must "own"
// this stream; if you seek it in between calls to stb_vorbis, it will become
// confused.
#endif
extern int stb_vorbis_seek_frame(stb_vorbis *f, unsigned int sample_number);
extern int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number);
// NOT WORKING YET
// these functions seek in the Vorbis file to (approximately) 'sample_number'.
// after calling seek_frame(), the next call to get_frame_*() will include
// the specified sample. after calling stb_vorbis_seek(), the next call to
// stb_vorbis_get_samples_* will start with the specified sample. If you
// do not need to seek to EXACTLY the target sample when using get_samples_*,
// you can also use seek_frame().
extern void stb_vorbis_seek_start(stb_vorbis *f);
// this function is equivalent to stb_vorbis_seek(f,0), but it
// actually works
extern unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f);
extern float stb_vorbis_stream_length_in_seconds(stb_vorbis *f);
// these functions return the total length of the vorbis stream
extern int stb_vorbis_get_frame_float(stb_vorbis *f, int *channels, float ***output);
// decode the next frame and return the number of samples. the number of
// channels returned are stored in *channels (which can be NULL--it is always
// the same as the number of channels reported by get_info). *output will
// contain an array of float* buffers, one per channel. These outputs will
// be overwritten on the next call to stb_vorbis_get_frame_*.
//
// You generally should not intermix calls to stb_vorbis_get_frame_*()
// and stb_vorbis_get_samples_*(), since the latter calls the former.
#ifndef STB_VORBIS_NO_INTEGER_CONVERSION
extern int stb_vorbis_get_frame_short_interleaved(stb_vorbis *f, int num_c, short *buffer, int num_shorts);
extern int stb_vorbis_get_frame_short (stb_vorbis *f, int num_c, short **buffer, int num_samples);
#endif
// decode the next frame and return the number of samples per channel. the
// data is coerced to the number of channels you request according to the
// channel coercion rules (see below). You must pass in the size of your
// buffer(s) so that stb_vorbis will not overwrite the end of the buffer.
// The maximum buffer size needed can be gotten from get_info(); however,
// the Vorbis I specification implies an absolute maximum of 4096 samples
// per channel. Note that for interleaved data, you pass in the number of
// shorts (the size of your array), but the return value is the number of
// samples per channel, not the total number of samples.
// Channel coercion rules:
// Let M be the number of channels requested, and N the number of channels present,
// and Cn be the nth channel; let stereo L be the sum of all L and center channels,
// and stereo R be the sum of all R and center channels (channel assignment from the
// vorbis spec).
// M N output
// 1 k sum(Ck) for all k
// 2 * stereo L, stereo R
// k l k > l, the first l channels, then 0s
// k l k <= l, the first k channels
// Note that this is not _good_ surround etc. mixing at all! It's just so
// you get something useful.
extern int stb_vorbis_get_samples_float_interleaved(stb_vorbis *f, int channels, float *buffer, int num_floats);
extern int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, int num_samples);
// gets num_samples samples, not necessarily on a frame boundary--this requires
// buffering so you have to supply the buffers. DOES NOT APPLY THE COERCION RULES.
// Returns the number of samples stored per channel; it may be less than requested
// at the end of the file. If there are no more samples in the file, returns 0.
#ifndef STB_VORBIS_NO_INTEGER_CONVERSION
extern int stb_vorbis_get_samples_short_interleaved(stb_vorbis *f, int channels, short *buffer, int num_shorts);
extern int stb_vorbis_get_samples_short(stb_vorbis *f, int channels, short **buffer, int num_samples);
#endif
// gets num_samples samples, not necessarily on a frame boundary--this requires
// buffering so you have to supply the buffers. Applies the coercion rules above
// to produce 'channels' channels. Returns the number of samples stored per channel;
// it may be less than requested at the end of the file. If there are no more
// samples in the file, returns 0.
#endif
//////// ERROR CODES
enum STBVorbisError
{
VORBIS__no_error,
VORBIS_need_more_data=1, // not a real error
VORBIS_invalid_api_mixing, // can't mix API modes
VORBIS_outofmem, // not enough memory
VORBIS_feature_not_supported, // uses floor 0
VORBIS_too_many_channels, // STB_VORBIS_MAX_CHANNELS is too small
VORBIS_file_open_failure, // fopen() failed
VORBIS_seek_without_length, // can't seek in unknown-length file
VORBIS_unexpected_eof=10, // file is truncated?
VORBIS_seek_invalid, // seek past EOF
// decoding errors (corrupt/invalid stream) -- you probably
// don't care about the exact details of these
// vorbis errors:
VORBIS_invalid_setup=20,
VORBIS_invalid_stream,
// ogg errors:
VORBIS_missing_capture_pattern=30,
VORBIS_invalid_stream_structure_version,
VORBIS_continued_packet_flag_invalid,
VORBIS_incorrect_stream_serial_number,
VORBIS_invalid_first_page,
VORBIS_bad_packet_type,
VORBIS_cant_find_last_page,
VORBIS_seek_failed,
};
#ifdef __cplusplus
}
#endif
#endif // STB_VORBIS_INCLUDE_STB_VORBIS_H
//
// HEADER ENDS HERE
//
//////////////////////////////////////////////////////////////////////////////

View File

@ -1,89 +0,0 @@
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <commdlg.h>
#include <string>
#include "util/text/utf8.h"
// For desktop operating systems only. Stubbed out on Android.
// Simplified as this will only be used in utilities / temp code.
// An false returned means cancel;
bool OpenFileDialog(const char *title, const char *extension, std::string *filename)
{
std::wstring wtitle = ConvertUTF8ToWString(std::string(title));
std::wstring wext = ConvertUTF8ToWString(std::string(extension));
OPENFILENAME of;
memset(&of, 0, sizeof(of));
wchar_t buffer[512] = {0};
of.lStructSize = sizeof(OPENFILENAME);
of.hInstance = 0;
of.hwndOwner = GetActiveWindow();
// These weird strings with zeroes in them can't be dealt with using normal string
// functions, so here we go - evil hackery.
wchar_t filter[256] = L"XXX files\0*.XXX\0\0";
memcpy(filter, wext.c_str(), 3 * sizeof(wchar_t));
memcpy(filter + 12, wext.c_str(), 3 * sizeof(wchar_t));
of.lpstrFilter = filter;
of.lpstrDefExt = wext.c_str();
of.lpstrFile = buffer;
of.nMaxFile = 511;
of.Flags = OFN_FILEMUSTEXIST;
if (!GetOpenFileName(&of)) return false;
*filename = ConvertWStringToUTF8(of.lpstrFile);
return true;
}
bool SaveFileDialog(const char *title, const char *extension, std::string *filename) {
std::wstring wtitle = ConvertUTF8ToWString(std::string(title));
std::wstring wext = ConvertUTF8ToWString(std::string(extension));
OPENFILENAME of;
memset(&of, 0, sizeof(of));
wchar_t buffer[512] = {0};
of.lStructSize = sizeof(OPENFILENAME);
of.hInstance = 0;
of.hwndOwner = GetActiveWindow();
// These weird strings with zeroes in them can't be dealt with using normal string
// functions, so here we go - evil hackery.
wchar_t filter[256] = L"XXX files\0*.XXX\0\0";
memcpy(filter, wext.c_str(), 3 * sizeof(wchar_t));
memcpy(filter + 12, wext.c_str(), 3 * sizeof(wchar_t));
of.lpstrFilter = filter;
of.lpstrDefExt = wext.c_str();
of.lpstrFile = buffer;
of.nMaxFile = 511;
of.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
if (!GetSaveFileName(&of))
return false;
*filename = ConvertWStringToUTF8(of.lpstrFile);
return true;
}
#else
#include <string>
#include "base/basictypes.h"
#include "base/logging.h"
bool OpenFileDialog(const char *title, const char *extension, std::string *filename)
{
ELOG("Asked for OpenFileDialog, not present on this platform.");
return false;
}
bool SaveFileDialog(const char *title, const char *extension, std::string *filename)
{
ELOG("Asked for SaveFileDialog, not present on this platform.");
return false;
}
#endif

View File

@ -1,10 +0,0 @@
#pragma once
#pragma once
#include <string>
#include "file/dialog.h"
bool OpenFileDialog(const char *title, const char *extension, std::string *filename);
bool SaveFileDialog(const char *title, const char *extension, std::string *filename);

View File

@ -1,9 +1,7 @@
set(SRCS
gl_debug_log.cpp
gl_lost_manager.cpp
texture.cpp
texture_atlas.cpp
texture_gen.cpp)
texture_atlas.cpp)
set(SRCS ${SRCS})

View File

@ -1,376 +0,0 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "ext/rg_etc1/rg_etc1.h"
#include "ext/jpge/jpgd.h"
#include "image/png_load.h"
#include "image/zim_load.h"
#include "base/logging.h"
#include "gfx/texture.h"
#include "gfx/texture_gen.h"
#include "gfx/gl_debug_log.h"
#include "gfx/gl_lost_manager.h"
#include "gfx/gl_common.h"
#include "gfx_es2/gpu_features.h"
Texture::Texture() : id_(0) {
CheckGLExtensions();
register_gl_resource_holder(this);
}
Texture::~Texture() {
unregister_gl_resource_holder(this);
Destroy();
}
void Texture::Destroy() {
if (id_) {
glDeleteTextures(1, &id_);
id_ = 0;
}
}
void Texture::GLLost() {
if (!filename_.empty()) {
Load(filename_.c_str());
ILOG("Reloaded lost texture %s", filename_.c_str());
} else {
WLOG("Texture %p cannot be restored - has no filename", this);
Destroy();
}
}
static void SetTextureParameters(int zim_flags) {
GLenum wrap = GL_REPEAT;
if (zim_flags & ZIM_CLAMP)
wrap = GL_CLAMP_TO_EDGE;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap);
GL_CHECK();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if ((zim_flags & (ZIM_HAS_MIPS | ZIM_GEN_MIPS))) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
GL_CHECK();
}
bool Texture::Load(const char *filename) {
// hook for generated textures
if (!memcmp(filename, "gen:", 4)) {
int bpp, w, h;
bool clamp;
uint8_t *data = generateTexture(filename, bpp, w, h, clamp);
if (!data)
return false;
glGenTextures(1, &id_);
glBindTexture(GL_TEXTURE_2D, id_);
if (bpp == 1) {
if (gl_extensions.IsGLES) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, w, h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
} else {
glTexImage2D(GL_TEXTURE_2D, 0, 1, w, h, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
}
} else {
FLOG("unsupported");
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp ? GL_CLAMP_TO_EDGE : GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
delete [] data;
return true;
}
filename_ = filename;
// Currently here are a bunch of project-specific workarounds.
// They shouldn't really hurt anything else very much though.
size_t len = strlen(filename);
char fn[1024];
strncpy(fn, filename, sizeof(fn));
fn[1023] = 0;
bool zim = false;
if (!strcmp("dds", &filename[len-3])) {
strcpy(&fn[len-3], "zim");
zim = true;
}
if (!strcmp("6TX", &filename[len-3]) || !strcmp("6tx", &filename[len-3])) {
ILOG("Detected 6TX %s", filename);
strcpy(&fn[len-3], "zim");
zim = true;
}
for (int i = 0; i < (int)strlen(fn); i++) {
if (fn[i] == '\\') fn[i] = '/';
}
if (fn[0] == 'm') fn[0] = 'M';
const char *name = fn;
if (zim && 0==memcmp(name, "Media/textures/", strlen("Media/textures"))) name += strlen("Media/textures/");
len = strlen(name);
if (!strcmp("png", &name[len-3]) || !strcmp("PNG", &name[len-3])) {
if (!LoadPNG(fn)) {
WLOG("WARNING: Failed to load .png %s, falling back to ugly gray XOR pattern!", fn);
LoadXOR();
return false;
} else {
return true;
}
} else if (!strcmp("zim", &name[len-3])) {
if (LoadZIM(name)) {
return true;
} else {
WLOG("WARNING: Failed to load .zim texture %s, falling back to ugly gray XOR pattern!", fn);
LoadXOR();
return false;
}
} else if (!strcmp("jpg", &name[len-3]) || !strcmp("JPG", &name[len-3]) ||
!strcmp("jpeg", &name[len-4]) || !strcmp("JPEG", &name[len-4])) {
if (!LoadJPEG(fn)) {
WLOG("WARNING: Failed to load jpeg %s, falling back to ugly gray XOR pattern!", fn);
LoadXOR();
return false;
} else {
return true;
}
} else if (!name || !strlen(name)) {
ELOG("Failed to identify image file %s by extension", name);
} else {
ELOG("Cannot load a texture with an empty filename");
}
LoadXOR();
return false;
}
bool Texture::LoadPNG(const char *filename, bool genMips) {
unsigned char *image_data;
if (1 != pngLoad(filename, &width_, &height_, &image_data, false)) {
return false;
}
GL_CHECK();
glGenTextures(1, &id_);
glBindTexture(GL_TEXTURE_2D, id_);
SetTextureParameters(genMips ? ZIM_GEN_MIPS : ZIM_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0,
GL_RGBA, GL_UNSIGNED_BYTE, image_data);
if (genMips) {
if (gl_extensions.ARB_framebuffer_object) {
glGenerateMipmap(GL_TEXTURE_2D);
} else {
#ifndef USING_GLES2
glGenerateMipmapEXT(GL_TEXTURE_2D);
#endif
}
}
GL_CHECK();
free(image_data);
return true;
}
bool Texture::LoadJPEG(const char *filename, bool genMips) {
ILOG("Loading jpeg %s", filename);
unsigned char *image_data;
int actual_comps;
image_data = jpgd::decompress_jpeg_image_from_file(filename, &width_, &height_, &actual_comps, 4);
if (!image_data) {
ELOG("jpeg: image data returned was 0");
return false;
}
ILOG("Jpeg decoder failed to get RGB, got: %i x %i x %i", actual_comps, width_, height_);
ILOG("First four bytes: %i %i %i %i", image_data[0], image_data[1], image_data[2], image_data[3]);
GL_CHECK();
glGenTextures(1, &id_);
glBindTexture(GL_TEXTURE_2D, id_);
SetTextureParameters(genMips ? ZIM_GEN_MIPS : ZIM_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
if (genMips) {
if (gl_extensions.ARB_framebuffer_object) {
glGenerateMipmap(GL_TEXTURE_2D);
} else {
#ifndef USING_GLES2
glGenerateMipmapEXT(GL_TEXTURE_2D);
#endif
}
}
GL_CHECK();
free(image_data);
return true;
}
bool Texture::LoadPNG(const uint8_t *data, size_t size, bool genMips) {
unsigned char *image_data;
if (1 != pngLoadPtr(data, size, &width_, &height_, &image_data, false)) {
return false;
}
GL_CHECK();
// TODO: should check for power of 2 tex size and disallow genMips when not.
glGenTextures(1, &id_);
glBindTexture(GL_TEXTURE_2D, id_);
SetTextureParameters(genMips ? ZIM_GEN_MIPS : ZIM_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data);
if (genMips) {
if (gl_extensions.ARB_framebuffer_object) {
glGenerateMipmap(GL_TEXTURE_2D);
} else {
#ifndef USING_GLES2
glGenerateMipmapEXT(GL_TEXTURE_2D);
#endif
}
}
GL_CHECK();
free(image_data);
return true;
}
bool Texture::LoadXOR() {
width_ = height_ = 256;
unsigned char *buf = new unsigned char[width_*height_*4];
for (int y = 0; y < 256; y++) {
for (int x = 0; x < 256; x++) {
buf[(y*width_ + x)*4 + 0] = x^y;
buf[(y*width_ + x)*4 + 1] = x^y;
buf[(y*width_ + x)*4 + 2] = x^y;
buf[(y*width_ + x)*4 + 3] = 0xFF;
}
}
GL_CHECK();
glGenTextures(1, &id_);
glBindTexture(GL_TEXTURE_2D, id_);
SetTextureParameters(ZIM_GEN_MIPS);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0,
GL_RGBA, GL_UNSIGNED_BYTE, buf);
if(gl_extensions.ARB_framebuffer_object){
glGenerateMipmap(GL_TEXTURE_2D);
}else{
#ifndef USING_GLES2
glGenerateMipmapEXT(GL_TEXTURE_2D);
#endif
}
GL_CHECK();
delete [] buf;
return true;
}
#if !defined(USING_GLES2) || defined(IOS)
// Allocates using new[], doesn't free.
uint8_t *ETC1ToRGBA(uint8_t *etc1, int width, int height) {
uint8_t *rgba = new uint8_t[width * height * 4];
memset(rgba, 0xFF, width * height * 4);
for (int y = 0; y < height; y += 4) {
for (int x = 0; x < width; x += 4) {
rg_etc1::unpack_etc1_block(etc1 + ((y / 4) * width/4 + (x / 4)) * 8,
(uint32_t *)rgba + (y * width + x), width, false);
}
}
return rgba;
}
#endif
bool Texture::LoadZIM(const char *filename) {
uint8_t *image_data[ZIM_MAX_MIP_LEVELS];
int width[ZIM_MAX_MIP_LEVELS];
int height[ZIM_MAX_MIP_LEVELS];
int flags;
int num_levels = ::LoadZIM(filename, &width[0], &height[0], &flags, &image_data[0]);
if (!num_levels)
return false;
if (num_levels >= ZIM_MAX_MIP_LEVELS)
return false;
width_ = width[0];
height_ = height[0];
int data_type = GL_UNSIGNED_BYTE;
int colors = GL_RGBA;
int storage = GL_RGBA;
bool compressed = false;
switch (flags & ZIM_FORMAT_MASK) {
case ZIM_RGBA8888:
data_type = GL_UNSIGNED_BYTE;
break;
case ZIM_RGBA4444:
data_type = GL_UNSIGNED_SHORT_4_4_4_4;
break;
case ZIM_RGB565:
data_type = GL_UNSIGNED_SHORT_5_6_5;
colors = GL_RGB;
storage = GL_RGB;
break;
case ZIM_ETC1:
compressed = true;
break;
}
GL_CHECK();
glGenTextures(1, &id_);
glBindTexture(GL_TEXTURE_2D, id_);
SetTextureParameters(flags);
if (compressed) {
for (int l = 0; l < num_levels; l++) {
int data_w = width[l];
int data_h = height[l];
if (data_w < 4) data_w = 4;
if (data_h < 4) data_h = 4;
#if defined(USING_GLES2) && !defined(IOS)
int compressed_image_bytes = data_w * data_h / 2;
glCompressedTexImage2D(GL_TEXTURE_2D, l, GL_ETC1_RGB8_OES, width[l], height[l], 0, compressed_image_bytes, image_data[l]);
GL_CHECK();
#else
// TODO: OpenGL 4.3+ accepts ETC1 so we should not have to do this anymore on those cards.
// Also, iOS does not have support for ETC1 compressed textures so we just decompress.
// TODO: Use PVR texture compression on iOS.
image_data[l] = ETC1ToRGBA(image_data[l], data_w, data_h);
glTexImage2D(GL_TEXTURE_2D, l, GL_RGBA, width[l], height[l], 0,
GL_RGBA, GL_UNSIGNED_BYTE, image_data[l]);
#endif
}
GL_CHECK();
#if !defined(USING_GLES2)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, num_levels - 2);
#endif
} else {
for (int l = 0; l < num_levels; l++) {
glTexImage2D(GL_TEXTURE_2D, l, storage, width[l], height[l], 0,
colors, data_type, image_data[l]);
}
if (num_levels == 1 && (flags & ZIM_GEN_MIPS)) {
if(gl_extensions.ARB_framebuffer_object) {
glGenerateMipmap(GL_TEXTURE_2D);
}else{
#ifndef USING_GLES2
glGenerateMipmapEXT(GL_TEXTURE_2D);
#endif
}
}
}
SetTextureParameters(flags);
GL_CHECK();
// Only free the top level, since the allocation is used for all of them.
free(image_data[0]);
return true;
}
void Texture::Bind(int stage) {
GL_CHECK();
if (stage != -1)
glActiveTexture(GL_TEXTURE0 + stage);
glBindTexture(GL_TEXTURE_2D, id_);
GL_CHECK();
}
void Texture::Unbind(int stage) {
GL_CHECK();
if (stage != -1)
glActiveTexture(GL_TEXTURE0 + stage);
glBindTexture(GL_TEXTURE_2D, 0);
GL_CHECK();
}

View File

@ -1,54 +0,0 @@
#pragma once
// Load and manage OpenGL textures easily. Supports ETC1 compressed texture with mipmaps
// in the custom ZIM format.
// This is deprecated - start using Thin3D instead.
#include <string>
#include "base/basictypes.h"
#include "gfx/gl_lost_manager.h"
class Texture : public GfxResourceHolder {
public:
Texture();
~Texture();
// Deduces format from the filename.
// If loading fails, will load a 256x256 XOR texture.
// If filename begins with "gen:", will defer to texture_gen.cpp/h.
// When format is known, it's fine to use LoadZIM etc directly.
// Those will NOT auto-fall back to xor texture however!
bool Load(const char *filename);
void Bind(int stage = -1);
void Destroy();
// PNG from memory buffer
bool LoadPNG(const uint8_t *data, size_t size, bool genMips = true);
bool LoadZIM(const char *filename);
bool LoadPNG(const char *filename, bool genMips = true);
bool LoadJPEG(const char *filename, bool genMips = true);
unsigned int Handle() const {
return id_;
}
virtual void GLLost();
std::string filename() const { return filename_; }
static void Unbind(int stage = -1);
int Width() const { return width_; }
int Height() const { return height_; }
private:
bool LoadXOR(); // Loads a placeholder texture.
std::string filename_;
#ifdef METRO
ID3D11Texture2D *tex_;
#endif
unsigned int id_;
int width_, height_;
};

View File

@ -1,271 +0,0 @@
// WIP, please ignore
#include <d3d11_1.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#if !defined(USING_GLES2)
#include "image/png_load.h"
#include "ext/etcpack/etcdec.h"
#endif
#include "image/zim_load.h"
#include "base/logging.h"
#include "gfx/texture.h"
#include "gfx/texture_gen.h"
#include "gfx/gl_debug_log.h"
#include "gfx/gl_lost_manager.h"
Texture::Texture() : tex_(0) {
register_gl_resource_holder(this);
}
void Texture::Destroy() {
if (tex_) {
tex_->Release();
tex_ = 0;
}
}
void Texture::GLLost() {
ILOG("Reloading lost texture %s", filename_.c_str());
Load(filename_.c_str());
}
Texture::~Texture() {
unregister_gl_resource_holder(this);
Destroy();
}
static void SetTextureParameters(int zim_flags) {
/*
GLenum wrap = GL_REPEAT;
if (zim_flags & ZIM_CLAMP) wrap = GL_CLAMP_TO_EDGE;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap);
GL_CHECK();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if ((zim_flags & (ZIM_HAS_MIPS | ZIM_GEN_MIPS))) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
GL_CHECK();*/
}
bool Texture::Load(const char *filename) {
// hook for generated textures
if (!memcmp(filename, "gen:", 4)) {
// TODO
// return false;
tex_ = (LPVOID)generateTexture(filename);
if (tex_) {
this->filename_ = filename;
}
return true;
}
filename_ = filename;
// Currently contains many Rollerball-specific workarounds.
// They shouldn't really hurt anything else very much though.
int len = strlen(filename);
char fn[256];
strcpy(fn, filename);
bool zim = false;
if (!strcmp("dds", &filename[len-3])) {
strcpy(&fn[len-3], "zim");
zim = true;
}
if (!strcmp("6TX", &filename[len-3]) || !strcmp("6tx", &filename[len-3])) {
ILOG("Detected 6TX %s", filename);
strcpy(&fn[len-3], "zim");
zim = true;
}
for (int i = 0; i < (int)strlen(fn); i++) {
if (fn[i] == '\\') fn[i] = '/';
}
if (fn[0] == 'm') fn[0] = 'M';
const char *name = fn;
if (zim && 0 == memcmp(name, "Media/textures/", strlen("Media/textures"))) name += strlen("Media/textures/");
len = strlen(name);
#if !defined(USING_GLES2)
if (!strcmp("png", &name[len-3]) ||
!strcmp("PNG", &name[len-3])) {
if (!LoadPNG(fn)) {
LoadXOR();
return false;
} else {
return true;
}
} else
#endif
if (!strcmp("zim", &name[len-3])) {
if (!LoadZIM(name)) {
LoadXOR();
return false;
} else {
return true;
}
}
LoadXOR();
return false;
}
#ifndef METRO
#if !defined(USING_GLES2)
bool Texture::LoadPNG(const char *filename) {
unsigned char *image_data;
if (1 != pngLoad(filename, &width_, &height_, &image_data, false)) {
return false;
}
GL_CHECK();
glGenTextures(1, &id_);
glBindTexture(GL_TEXTURE_2D, id_);
SetTextureParameters(ZIM_GEN_MIPS);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0,
GL_RGBA, GL_UNSIGNED_BYTE, image_data);
glGenerateMipmap(GL_TEXTURE_2D);
GL_CHECK();
free(image_data);
return true;
}
#endif
#endif
bool Texture::LoadXOR() {
width_ = height_ = 256;
unsigned char *buf = new unsigned char[width_*height_*4];
for (int y = 0; y < 256; y++) {
for (int x = 0; x < 256; x++) {
buf[(y*width_ + x)*4 + 0] = x^y;
buf[(y*width_ + x)*4 + 1] = x^y;
buf[(y*width_ + x)*4 + 2] = x^y;
buf[(y*width_ + x)*4 + 3] = 0xFF;
}
}
GL_CHECK();
ID3D11Device *ctx;
D3D11_TEXTURE2D_DESC desc;
desc.Width = width_;
desc.Height = height_;
desc.MipLevels = 0;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.CPUAccessFlags = 0;
desc.MiscFlags = 0;
if (FAILED(ctx->CreateTexture2D(&desc, 0, &tex_))) {
FLOG("Failed creating XOR texture");
}
SetTextureParameters(ZIM_GEN_MIPS);
GL_CHECK();
delete [] buf;
return true;
}
#if !defined(USING_GLES2)
// Allocates using new[], doesn't free.
uint8_t *ETC1ToRGBA(uint8_t *etc1, int width, int height) {
uint8_t *rgba = new uint8_t[width * height * 4];
memset(rgba, 0xFF, width * height * 4);
for (int y = 0; y < height; y += 4) {
for (int x = 0; x < width; x += 4) {
DecompressBlock(etc1 + ((y / 4) * width/4 + (x / 4)) * 8,
rgba + (y * width + x) * 4, width, 255);
}
}
return rgba;
}
#endif
bool Texture::LoadZIM(const char *filename) {
uint8_t *image_data[ZIM_MAX_MIP_LEVELS];
int width[ZIM_MAX_MIP_LEVELS];
int height[ZIM_MAX_MIP_LEVELS];
int flags;
int num_levels = ::LoadZIM(filename, &width[0], &height[0], &flags, &image_data[0]);
if (!num_levels)
return false;
width_ = width[0];
height_ = height[0];
int data_type = GL_UNSIGNED_BYTE;
int colors = GL_RGBA;
int storage = GL_RGBA;
bool compressed = false;
switch (flags & ZIM_FORMAT_MASK) {
case ZIM_RGBA8888:
data_type = GL_UNSIGNED_BYTE;
break;
case ZIM_RGBA4444:
data_type = DXGI_FORMAT_B4G4R4A4_UNORM;
break;
case ZIM_RGB565:
data_type = DXGI_FORMAT_B5G6R5_UNORM;
colors = GL_RGB;
storage = GL_RGB;
break;
case ZIM_ETC1:
compressed = true;
break;
}
GL_CHECK();
//glGenTextures(1, &id_);
//glBindTexture(GL_TEXTURE_2D, id_);
SetTextureParameters(flags);
if (compressed) {
for (int l = 0; l < num_levels; l++) {
int data_w = width[l];
int data_h = height[l];
if (data_w < 4) data_w = 4;
if (data_h < 4) data_h = 4;
#if defined(USING_GLES2)
int compressed_image_bytes = data_w * data_h / 2;
glCompressedTexImage2D(GL_TEXTURE_2D, l, GL_ETC1_RGB8_OES, width[l], height[l], 0, compressed_image_bytes, image_data[l]);
GL_CHECK();
#else
//image_data[l] = ETC1ToRGBA(image_data[l], data_w, data_h);
//glTexImage2D(GL_TEXTURE_2D, l, GL_RGBA, width[l], height[l], 0,
// GL_RGBA, GL_UNSIGNED_BYTE, image_data[l]);
#endif
}
GL_CHECK();
#if !defined(USING_GLES2)
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, num_levels - 2);
#endif
} else {
for (int l = 0; l < num_levels; l++) {
//glTexImage2D(GL_TEXTURE_2D, l, storage, width[l], height[l], 0,
// colors, data_type, image_data[l]);
}
if (num_levels == 1 && (flags & ZIM_GEN_MIPS)) {
//glGenerateMipmap(GL_TEXTURE_2D);
}
}
SetTextureParameters(flags);
GL_CHECK();
// Only free the top level, since the allocation is used for all of them.
delete [] image_data[0];
return true;
}
void Texture::Bind(int stage) {
GL_CHECK();
//if (stage != -1)
// glActiveTexture(GL_TEXTURE0 + stage);
// glBindTexture(GL_TEXTURE_2D, id_);
GL_CHECK();
}

View File

@ -1,55 +0,0 @@
// Minimal procedural texture generator to generate some usual textures like circles and vignette textures.
// "Gen" textures have filenames like this: "gen:256:256:vignette:0.1"
//
// These must be VERY VERY fast to not slow down loading. Could multicore this in the
// future.
#include <cmath>
#include <cstdio>
#include <cstring>
#include "base/basictypes.h"
#include "gfx/texture.h"
uint8_t *generateTexture(const char *filename, int &bpp, int &w, int &h, bool &clamp) {
char name_and_params[256];
// security check :)
if (strlen(filename) > 200)
return 0;
sscanf(filename, "gen:%i:%i:%s", &w, &h, name_and_params);
uint8_t *data;
if (!strcmp(name_and_params, "vignette")) {
bpp = 1;
data = new uint8_t[w*h];
for (int y = 0; y < h; ++y) {
for (int x = 0; x < w; x++) {
float dx = (float)(x - w/2) / (w/2);
float dy = (float)(y - h/2) / (h/2);
float dist = sqrtf(dx * dx + dy * dy);
dist /= 1.414f;
float val = 1.0 - powf(dist, 1.4f);
data[y*w + x] = val * 255;
}
}
} else if (!strcmp(name_and_params, "circle")) {
bpp = 1;
// TODO
data = new uint8_t[w*h];
for (int y = 0; y < h; ++y) {
for (int x = 0; x < w; x++) {
float dx = (float)(x - w/2) / (w/2);
float dy = (float)(y - h/2) / (h/2);
float dist = sqrtf(dx * dx + dy * dy);
dist /= 1.414f;
float val = 1.0 - powf(dist, 1.4f);
data[y*w + x] = val * 255;
}
}
} else {
data = NULL;
}
return data;
}

View File

@ -1,6 +0,0 @@
// Minimal procedural texture generator to generate some useful but unnecessary-to-store textures like circles.
// "Gen" textures have filenames like this: "gen:256:256:4444:vignette:0.1"
#include "gfx/texture.h"
uint8_t *generateTexture(const char *filename, int &bpp, int &w, int &h, bool &clamp);

View File

@ -1,11 +1,9 @@
set(SRCS
draw_buffer.cpp
draw_text.cpp
fbo.cpp
glsl_program.cpp
gpu_features.cpp
gl_state.cpp
vertex_format.cpp)
gl_state.cpp)
set(SRCS ${SRCS})

View File

@ -3,7 +3,7 @@
// "Immediate mode"-lookalike buffered drawing. Very fast way to draw 2D.
#include "base/basictypes.h"
#include "base/color.h"
#include "base/colorutil.h"
#include "gfx/gl_lost_manager.h"
#include "gfx/texture_atlas.h"
#include "math/geom2d.h"

View File

@ -1,71 +0,0 @@
#include "base/logging.h"
#include "gfx_es2/glsl_program.h"
#include "gfx_es2/vertex_format.h"
static const GLuint formatLookup[16] = {
GL_FLOAT,
0, //GL_HALF_FLOAT_EXT,
GL_UNSIGNED_SHORT,
GL_UNSIGNED_BYTE,
0, //GL_UNSIGNED_INT_10_10_10_2,
0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
void SetVertexFormat(const GLSLProgram *program, uint32_t vertexFormat) {
// First special case our favorites
if (vertexFormat == (POS_FLOAT | NRM_FLOAT | UV0_FLOAT)) {
const int vertexSize = 3*4 + 3*4 + 2*4;
glUniform1i(program->sampler0, 0);
glEnableVertexAttribArray(program->a_position);
glEnableVertexAttribArray(program->a_normal);
glEnableVertexAttribArray(program->a_texcoord0);
glVertexAttribPointer(program->a_position, 3, GL_FLOAT, GL_FALSE, vertexSize, (void *)0);
glVertexAttribPointer(program->a_normal, 3, GL_FLOAT, GL_FALSE, vertexSize, (void *)12);
glVertexAttribPointer(program->a_texcoord0, 2, GL_FLOAT, GL_FALSE, vertexSize, (void *)24);
return;
}
// Then have generic code here.
int vertexSize = 0;
FLOG("TODO: Write generic code.");
if (vertexFormat & UV0_MASK) {
glUniform1i(program->sampler0, 0);
}
glEnableVertexAttribArray(program->a_position);
glVertexAttribPointer(program->a_position, 3, GL_FLOAT, GL_FALSE, vertexSize, (void *)0);
if (vertexFormat & NRM_MASK) {
glEnableVertexAttribArray(program->a_normal);
glVertexAttribPointer(program->a_normal, 3, GL_FLOAT, GL_FALSE, vertexSize, (void *)12);
}
if (vertexFormat & UV0_MASK) {
glEnableVertexAttribArray(program->a_texcoord0);
glVertexAttribPointer(program->a_texcoord0, 2, GL_FLOAT, GL_FALSE, vertexSize, (void *)24);
}
if (vertexFormat & UV1_MASK) {
glEnableVertexAttribArray(program->a_texcoord1);
glVertexAttribPointer(program->a_texcoord1, 2, GL_FLOAT, GL_FALSE, vertexSize, (void *)24);
}
if (vertexFormat & RGBA_MASK) {
glEnableVertexAttribArray(program->a_color);
glVertexAttribPointer(program->a_color, 4, GL_FLOAT, GL_FALSE, vertexSize, (void *)28);
}
}
// TODO: Save state so that we can get rid of this.
void UnsetVertexFormat(const GLSLProgram *program, uint32_t vertexFormat) {
glDisableVertexAttribArray(program->a_position);
if (vertexFormat & NRM_MASK)
glDisableVertexAttribArray(program->a_normal);
if (vertexFormat & UV0_MASK)
glDisableVertexAttribArray(program->a_texcoord0);
if (vertexFormat & UV1_MASK)
glDisableVertexAttribArray(program->a_texcoord1);
if (vertexFormat & RGBA_MASK)
glDisableVertexAttribArray(program->a_color);
}

View File

@ -1,51 +0,0 @@
#pragma once
// TODO: Actually use for something :)
#include "base/basictypes.h"
// Vertex format flags
enum VtxFmt {
POS_FLOAT = 1,
POS_FLOAT16 = 2,
POS_UINT16 = 3,
POS_UINT8 = 4,
POS_101010 = 5,
NRM_FLOAT = 1 << 4,
NRM_FLOAT16 = 2 << 4,
NRM_SINT16 = 3 << 4,
NRM_UINT8 = 4 << 4,
NRM_101010 = 5 << 4,
TANGENT_FLOAT = 1 << 8,
//....
UV0_NONE = 1 << 12,
UV0_FLOAT = 1 << 12,
// ....
UV1_NONE = 1 << 16,
UV1_FLOAT = 1 << 16,
RGBA_NONE = 0 << 20,
RGBA_FLOAT = 1 << 20,
RGBA_FLOAT16 = 2 << 20,
RGBA_UINT16 = 3 << 20,
RGBA_UINT8 = 4 << 20,
RGBA_101010 = 5 << 20,
POS_MASK = 0x0000000F,
NRM_MASK = 0x000000F0,
TANGENT_MASK = 0x00000F00,
UV0_MASK = 0x0000F000,
UV1_MASK = 0x000F0000,
RGBA_MASK = 0x00F00000,
// Can add more here, such as a generic AUX or something. Don't know what to use it for though. Hardness for cloth sim?
};
struct GLSLProgram;
// When calling this, the relevant vertex buffer must be bound to GL_ARRAY_BUFFER.
void SetVertexFormat(const GLSLProgram *program, uint32_t format);
void UnsetVertexFormat(const GLSLProgram *program, uint32_t format);

View File

@ -2,7 +2,6 @@ set(SRCS
lin/matrix4x4.cpp
lin/vec3.cpp
lin/quat.cpp
lin/aabb.cpp
curves.cpp
math_util.cpp
)

View File

@ -1,268 +0,0 @@
#include "math/lin/aabb.h"
#include "math/lin/ray.h"
#include "math/lin/plane.h"
#define NUMDIM 3
#define RIGHT 0
#define LEFT 1
#define MIDDLE 2
static const float flt_plus_inf = -logf(0); // let's keep C and C++ compilers happy.
AABB::AABB() : minB(0,0,0),maxB(0,0,0) {
}
void AABB::Add(const Vec3 &pt) {
for (int i=0; i<3; i++)
{
if (pt[i] < minB[i])
minB[i] = pt[i];
if (pt[i] > maxB[i])
maxB[i] = pt[i];
}
}
bool AABB::Contains(const Vec3 &pt) const {
for (int i=0; i<3; i++)
{
if (pt[i] < minB[i])
return false;
if (pt[i] > maxB[i])
return false;
}
return true;
}
bool AABB::IntersectRay(const Ray &ray, float &tnear, float &tfar) const {
float tNear=-flt_plus_inf, tFar=flt_plus_inf;
//For each pair of planes P associated with X, Y, and Z do:
//(example using X planes)
for (int i=0; i<3; i++)
{
float min = minB[i];
float max = maxB[i];
if (ray.dir[i] == 0.0f) //parallell! ARGH!
if (ray.origin[i] < min || ray.origin[i] > max)
return false;
//Intersect with slab
float T1 = (min - ray.origin[i]) * ray.invdir[i];
float T2 = (max - ray.origin[i]) * ray.invdir[i];
//Swap if necessary
if (T1 > T2)
{
float temp=T1; T1=T2; T2=temp;
}
//Save closest/farthest hits
if (T1 > tNear) tNear = T1;
if (T2 < tFar) tFar = T2;
}
if (tNear > tFar)
return false; //missed the box
else
{
if (tFar < 0)
return false; //behind camera
tnear = tNear;
tfar = tFar;
}
return true;
}
// Possible orientation of the splitting plane in the interior node of the kd-tree,
// "No axis" denotes a leaf.
enum Axes
{
Xaxis,
Yaxis,
Zaxis,
Noaxis
};
int AABB::GetShortestAxis() const
{
Vec3 delta = maxB-minB;
if (delta.y<delta.x)
{
if (delta.z<delta.y)
return 2;
else
return 1;
}
else
{
if (delta.z<delta.x)
return 2;
else
return 0;
}
}
int AABB::GetLongestAxis() const
{
Vec3 delta = maxB-minB;
if (fabsf(delta.y) > fabsf(delta.x))
{
if (fabsf(delta.z) > fabsf(delta.y))
return 2;
else
return 1;
}
else
{
if (fabsf(delta.z) > fabsf(delta.x))
return 2;
else
return 0;
}
}
inline void FINDMINMAX(float x0, float x1, float x2, float &min, float &max )
{
min = max = x0;
if(x1<min)
min=x1;
if(x1>max)
max=x1;
if(x2<min)
min=x2;
if(x2>max)
max=x2;
}
// X-tests
#define AXISTEST_X01( a, b, fa, fb ) \
p0 = a * v0[1] - b * v0[2], p2 = a * v2[1] - b * v2[2]; \
if (p0 < p2) { min = p0; max = p2;} else { min = p2; max = p0; } \
rad = fa * a_BoxHalfsize[1] + fb * a_BoxHalfsize[2]; \
if (min > rad || max < -rad) return 0;
#define AXISTEST_X2( a, b, fa, fb ) \
p0 = a * v0[1] - b * v0[2], p1 = a * v1[1] - b * v1[2]; \
if (p0 < p1) { min = p0; max = p1; } else { min = p1; max = p0;} \
rad = fa * a_BoxHalfsize[1] + fb * a_BoxHalfsize[2]; \
if(min>rad || max<-rad) return 0;
// Y-tests
#define AXISTEST_Y02( a, b, fa, fb ) \
p0 = -a * v0[0] + b * v0[2], p2 = -a * v2[0] + b * v2[2]; \
if(p0 < p2) { min = p0; max = p2; } else { min = p2; max = p0; } \
rad = fa * a_BoxHalfsize[0] + fb * a_BoxHalfsize[2]; \
if (min > rad || max < -rad) return 0;
#define AXISTEST_Y1( a, b, fa, fb ) \
p0 = -a * v0[0] + b * v0[2], p1 = -a * v1[0] + b * v1[2]; \
if (p0 < p1) { min = p0; max = p1; } else { min = p1; max = p0; } \
rad = fa * a_BoxHalfsize[0] + fb * a_BoxHalfsize[2]; \
if (min > rad || max < -rad) return 0;
// Z-tests
#define AXISTEST_Z12( a, b, fa, fb ) \
p1 = a * v1[0] - b * v1[1], p2 = a * v2[0] - b * v2[1]; \
if(p2 < p1) { min = p2; max = p1; } else { min = p1; max = p2; } \
rad = fa * a_BoxHalfsize[0] + fb * a_BoxHalfsize[1]; \
if (min > rad || max < -rad) return 0;
#define AXISTEST_Z0( a, b, fa, fb ) \
p0 = a * v0[0] - b * v0[1], p1 = a * v1[0] - b * v1[1]; \
if(p0 < p1) { min = p0; max = p1; } else { min = p1; max = p0; } \
rad = fa * a_BoxHalfsize[0] + fb * a_BoxHalfsize[1]; \
if (min > rad || max < -rad) return 0;
bool PlaneBoxOverlap(const Vec3& a_Normal, const Vec3& a_Vert, const Vec3& a_MaxBox )
{
Vec3 vmin, vmax;
for (int q = 0; q < 3; q++)
{
float v = a_Vert[q];
if (a_Normal[q] > 0.0f)
{
vmin[q] = -a_MaxBox[q] - v;
vmax[q] = a_MaxBox[q] - v;
}
else
{
vmin[q] = a_MaxBox[q] - v;
vmax[q] = -a_MaxBox[q] - v;
}
}
if (( a_Normal * vmin) > 0.0f)
return false;
if (( a_Normal * vmax) >= 0.0f)
return true;
return false;
}
bool AABB::IntersectsTriangle(const Vec3& a_V0, const Vec3& a_V1, const Vec3& a_V2 ) const
{
Vec3 a_BoxCentre = GetMidpoint();
Vec3 a_BoxHalfsize = GetExtents() / 2.0f;
Vec3 v0, v1, v2, normal, e0, e1, e2;
float min, max, p0, p1, p2, rad, fex, fey, fez;
v0 = a_V0 - a_BoxCentre;
v1 = a_V1 - a_BoxCentre;
v2 = a_V2 - a_BoxCentre;
e0 = v1 - v0, e1 = v2 - v1, e2 = v0 - v2;
fex = fabsf(e0[0]);
fey = fabsf(e0[1]);
fez = fabsf(e0[2]);
AXISTEST_X01( e0[2], e0[1], fez, fey );
AXISTEST_Y02( e0[2], e0[0], fez, fex );
AXISTEST_Z12( e0[1], e0[0], fey, fex );
fex = fabsf(e1[0]);
fey = fabsf(e1[1]);
fez = fabsf(e1[2]);
AXISTEST_X01( e1[2], e1[1], fez, fey );
AXISTEST_Y02( e1[2], e1[0], fez, fex );
AXISTEST_Z0 ( e1[1], e1[0], fey, fex );
fex = fabsf(e2[0]);
fey = fabsf(e2[1]);
fez = fabsf(e2[2]);
AXISTEST_X2 ( e2[2], e2[1], fez, fey );
AXISTEST_Y1 ( e2[2], e2[0], fez, fex );
AXISTEST_Z12( e2[1], e2[0], fey, fex );
FINDMINMAX( v0[0], v1[0], v2[0], min, max );
if (min > a_BoxHalfsize[0] || max < -a_BoxHalfsize[0])
return false;
FINDMINMAX( v0[1], v1[1], v2[1], min, max );
if (min > a_BoxHalfsize[1] || max < -a_BoxHalfsize[1])
return false;
FINDMINMAX( v0[2], v1[2], v2[2], min, max );
if (min > a_BoxHalfsize[2] || max < -a_BoxHalfsize[2])
return false;
normal = e0 % e1;
if (!PlaneBoxOverlap( normal, v0, a_BoxHalfsize ))
return false;
return true;
}
bool AABB::BehindPlane(const Plane &plane) const {
if (plane.Distance(minB) > 0)
return false;
if (plane.Distance(maxB) > 0)
return false;
if (plane.Distance(maxB.x, minB.y, minB.z) > 0)
return false;
if (plane.Distance(maxB.x, maxB.y, minB.z) > 0)
return false;
if (plane.Distance(maxB.x, minB.y, maxB.z) > 0)
return false;
if (plane.Distance(minB.x, maxB.y, minB.z) > 0)
return false;
if (plane.Distance(minB.x, minB.y, maxB.z) > 0)
return false;
if (plane.Distance(minB.x, maxB.y, maxB.z) > 0)
return false;
return true;
}

View File

@ -1,40 +0,0 @@
#pragma once
#include "math/lin/vec3.h"
struct Ray;
class Plane;
struct AABB {
Vec3 minB;
int pad;
Vec3 maxB;
int pad2;
AABB();
bool Contains(const Vec3 &pt) const;
bool IntersectRay(const Ray &ray, float &tnear, float &tfar) const;
// Doesn't currently work.
bool IntersectRay2(const Ray &ray, float &tnear, float &tfar) const;
bool IntersectsTriangle(const Vec3& a_V0, const Vec3& a_V1, const Vec3& a_V2) const;
void Add(const Vec3 &pt);
int GetShortestAxis() const;
int GetLongestAxis() const;
float GetSize(int axis) const {
return maxB[axis] - minB[axis];
}
float GetMidpoint(int axis) const {
return (minB[axis] + maxB[axis]) / 2;
}
Vec3 GetMidpoint() const {
return (minB + maxB) / 2;
}
Vec3 GetExtents() const {
return maxB - minB;
}
bool BehindPlane(const Plane &plane) const;
};

View File

@ -1,12 +0,0 @@
set(SRCS
midi_input.cpp
)
set(SRCS ${SRCS})
add_library(midi STATIC ${SRCS})
if(UNIX)
add_definitions(-fPIC)
endif(UNIX)

View File

@ -1,90 +0,0 @@
#ifdef _WIN32
// Windows implementation.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <MMSystem.h>
#include <vector>
#include <string>
#include "base/basictypes.h"
#include "base/logging.h"
#include "midi/midi_input.h"
#include "util/text/utf8.h"
std::vector<std::string> MidiInGetDevices() {
int numDevs = midiInGetNumDevs();
std::vector<std::string> devices;
for (int i = 0; i < numDevs; i++) {
MIDIINCAPS caps;
midiInGetDevCaps(i, &caps, sizeof(caps));
devices.push_back(ConvertWStringToUTF8(caps.szPname));
}
return devices;
}
static void CALLBACK MidiCallback(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) {
MidiListener *listener = (MidiListener*)dwInstance;
uint8_t cmd[3] = {0};
switch (wMsg) {
case MM_MIM_OPEN:
ILOG("Got MIDI Open message");
break;
case MM_MIM_CLOSE:
ILOG("Got MIDI Close message");
break;
case MM_MIM_DATA:
cmd[0] = dwParam1 & 0xFF;
cmd[1] = (dwParam1 >> 8) & 0xFF;
cmd[2] = (dwParam1 >> 16) & 0xFF;
// time = dwParam2 & 0xFFFF;
ILOG("Got MIDI Data: %02x %02x %02x", cmd[0], cmd[1], cmd[2]);
listener->midiEvent(cmd);
break;
default:
WLOG("Got unexpected MIDI message: %08x", (uint32_t)wMsg);
break;
}
}
MidiDevice MidiInStart(int deviceID, MidiListener *listener) {
HMIDIIN hMidiIn;
MMRESULT result = midiInOpen(&hMidiIn, deviceID, (DWORD_PTR)(&MidiCallback), (DWORD_PTR)listener, CALLBACK_FUNCTION);
midiInStart(hMidiIn);
return (MidiDevice)hMidiIn;
}
void MidiInStop(MidiDevice device) {
HMIDIIN hMidiIn = (HMIDIIN)device;
midiInStop(hMidiIn);
midiInClose(hMidiIn);
}
#else
#include <vector>
#include <string>
#include "base/basictypes.h"
#include "base/logging.h"
#include "midi/midi_input.h"
// Stubs for other platforms.
std::vector<std::string> MidiInGetDevices() {
return std::vector<std::string>();
}
MidiDevice MidiInStart(int deviceID, MidiListener *listener) {
FLOG("Invalid MIDI device");
return 0;
}
void MidiInStop(MidiDevice device) {
FLOG("Invalid MIDI device");
}
#endif

View File

@ -1,27 +0,0 @@
// MIDI input.
//
// Currently, this is just a platform-clean wrapper around the Win32 MIDI input facilities.
// Thus, it only supports Windows. Other platforms will get an empty list of midi in devices.
#pragma once
#include <vector>
#include <string>
#include "base/basictypes.h"
typedef void *MidiDevice;
// Listeners inherit from this. Pass them into MidiInStart.
class MidiListener
{
public:
virtual ~MidiListener() {}
virtual void midiEvent(const uint8_t *cmd) = 0;
};
// Gets the names of the devices in a vector. The device identifier is the index in the vector.
std::vector<std::string> MidiInGetDevices();
MidiDevice MidiInStart(int deviceID, MidiListener *listener);
void MidiInStop(MidiDevice device);

View File

@ -187,24 +187,16 @@
<None Include="math\fast\fast_matrix_neon.S" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="audio\mixer.h" />
<ClInclude Include="audio\wav_read.h" />
<ClInclude Include="base\backtrace.h" />
<ClInclude Include="base\basictypes.h" />
<ClInclude Include="base\buffer.h" />
<ClInclude Include="base\color.h" />
<ClInclude Include="base\colorutil.h" />
<ClInclude Include="base\compat.h" />
<ClInclude Include="base\display.h" />
<ClInclude Include="base\error_context.h" />
<ClInclude Include="base\fastlist.h" />
<ClInclude Include="base\functional.h" />
<ClInclude Include="base\linked_ptr.h" />
<ClInclude Include="base\logging.h" />
<ClInclude Include="base\mutex.h" />
<ClInclude Include="base\NativeApp.h" />
<ClInclude Include="base\scoped_ptr.h" />
<ClInclude Include="base\stats.h" />
<ClInclude Include="base\stringutil.h" />
<ClInclude Include="base\timeutil.h" />
<ClInclude Include="data\compression.h" />
@ -225,11 +217,9 @@
<ClInclude Include="ext\libzip\zipint.h" />
<ClInclude Include="ext\rg_etc1\rg_etc1.h" />
<ClInclude Include="ext\sha1\sha1.h" />
<ClInclude Include="ext\stb_vorbis\stb_vorbis.h" />
<ClInclude Include="ext\vjson\block_allocator.h" />
<ClInclude Include="ext\vjson\json.h" />
<ClInclude Include="file\chunk_file.h" />
<ClInclude Include="file\dialog.h" />
<ClInclude Include="file\easy_file.h" />
<ClInclude Include="file\fd_util.h" />
<ClInclude Include="file\file_util.h" />
@ -240,15 +230,12 @@
<ClInclude Include="gfx\gl_common.h" />
<ClInclude Include="gfx\gl_debug_log.h" />
<ClInclude Include="gfx\gl_lost_manager.h" />
<ClInclude Include="gfx\texture_gen.h" />
<ClInclude Include="gfx\texture.h" />
<ClInclude Include="gfx\texture_atlas.h" />
<ClInclude Include="gfx_es2\draw_buffer.h" />
<ClInclude Include="gfx_es2\draw_text.h" />
<ClInclude Include="gfx_es2\gl3stub.h" />
<ClInclude Include="gfx_es2\glsl_program.h" />
<ClInclude Include="gfx_es2\gpu_features.h" />
<ClInclude Include="gfx_es2\vertex_format.h" />
<ClInclude Include="i18n\i18n.h" />
<ClInclude Include="image\png_load.h" />
<ClInclude Include="image\zim_load.h" />
@ -260,7 +247,6 @@
<ClInclude Include="math\curves.h" />
<ClInclude Include="math\expression_parser.h" />
<ClInclude Include="math\geom2d.h" />
<ClInclude Include="math\lin\aabb.h" />
<ClInclude Include="math\lin\matrix4x4.h" />
<ClInclude Include="math\lin\plane.h" />
<ClInclude Include="math\lin\quat.h" />
@ -268,7 +254,6 @@
<ClInclude Include="math\math_util.h" />
<ClInclude Include="math\fast\fast_math.h" />
<ClInclude Include="math\fast\fast_matrix.h" />
<ClInclude Include="midi\midi_input.h" />
<ClInclude Include="net\http_client.h" />
<ClInclude Include="net\http_headers.h" />
<ClInclude Include="net\http_server.h" />
@ -289,8 +274,6 @@
<ClInclude Include="ui\view.h" />
<ClInclude Include="ui\viewgroup.h" />
<ClInclude Include="ui\virtual_input.h" />
<ClInclude Include="util\bits\bits.h" />
<ClInclude Include="util\random\perlin.h" />
<ClInclude Include="util\random\rng.h" />
<ClInclude Include="util\text\parsers.h" />
<ClInclude Include="util\text\shiftjis.h" />
@ -298,8 +281,6 @@
<ClInclude Include="util\text\utf8.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="audio\mixer.cpp" />
<ClCompile Include="audio\wav_read.cpp" />
<ClCompile Include="base\backtrace.cpp" />
<ClCompile Include="base\BlackberryMain.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
@ -311,7 +292,6 @@
<ClCompile Include="base\colorutil.cpp" />
<ClCompile Include="base\compat.cpp" />
<ClCompile Include="base\display.cpp" />
<ClCompile Include="base\error_context.cpp" />
<ClCompile Include="base\PCMain.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
@ -693,11 +673,9 @@
</ClCompile>
<ClCompile Include="ext\rg_etc1\rg_etc1.cpp" />
<ClCompile Include="ext\sha1\sha1.cpp" />
<ClCompile Include="ext\stb_vorbis\stb_vorbis.c" />
<ClCompile Include="ext\vjson\block_allocator.cpp" />
<ClCompile Include="ext\vjson\json.cpp" />
<ClCompile Include="file\chunk_file.cpp" />
<ClCompile Include="file\dialog.cpp" />
<ClCompile Include="file\easy_file.cpp" />
<ClCompile Include="file\fd_util.cpp" />
<ClCompile Include="file\file_util.cpp" />
@ -706,9 +684,7 @@
<ClCompile Include="file\zip_read.cpp" />
<ClCompile Include="gfx\gl_debug_log.cpp" />
<ClCompile Include="gfx\gl_lost_manager.cpp" />
<ClCompile Include="gfx\texture.cpp" />
<ClCompile Include="gfx\texture_atlas.cpp" />
<ClCompile Include="gfx\texture_gen.cpp" />
<ClCompile Include="gfx_es2\draw_buffer.cpp" />
<ClCompile Include="gfx_es2\draw_text.cpp" />
<ClCompile Include="gfx_es2\gl3stub.c">
@ -719,7 +695,6 @@
</ClCompile>
<ClCompile Include="gfx_es2\glsl_program.cpp" />
<ClCompile Include="gfx_es2\gpu_features.cpp" />
<ClCompile Include="gfx_es2\vertex_format.cpp" />
<ClCompile Include="i18n\i18n.cpp" />
<ClCompile Include="image\png_load.cpp" />
<ClCompile Include="image\zim_load.cpp" />
@ -729,7 +704,6 @@
<ClCompile Include="json\json_writer.cpp" />
<ClCompile Include="math\curves.cpp" />
<ClCompile Include="math\expression_parser.cpp" />
<ClCompile Include="math\lin\aabb.cpp" />
<ClCompile Include="math\lin\matrix4x4.cpp" />
<ClCompile Include="math\lin\plane.cpp" />
<ClCompile Include="math\lin\quat.cpp" />
@ -740,7 +714,6 @@
<ClCompile Include="math\fast\fast_matrix_sse.c">
<AssemblerOutput Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AssemblyAndSourceCode</AssemblerOutput>
</ClCompile>
<ClCompile Include="midi\midi_input.cpp" />
<ClCompile Include="net\http_client.cpp" />
<ClCompile Include="net\http_headers.cpp" />
<ClCompile Include="net\http_server.cpp" />
@ -762,12 +735,7 @@
<ClCompile Include="ui\view.cpp" />
<ClCompile Include="ui\viewgroup.cpp" />
<ClCompile Include="ui\virtual_input.cpp" />
<ClCompile Include="util\bits\bits.cpp" />
<ClCompile Include="util\hash\hash.cpp" />
<ClCompile Include="util\random\perlin.cpp">
<AssemblerOutput Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AssemblyAndSourceCode</AssemblerOutput>
<AssemblerOutput Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AssemblyAndSourceCode</AssemblerOutput>
</ClCompile>
<ClCompile Include="util\text\parsers.cpp" />
<ClCompile Include="util\text\utf8.cpp" />
</ItemGroup>

View File

@ -30,9 +30,6 @@
<ClInclude Include="gfx\gl_debug_log.h">
<Filter>gfx</Filter>
</ClInclude>
<ClInclude Include="base\color.h">
<Filter>image</Filter>
</ClInclude>
<ClInclude Include="image\png_load.h">
<Filter>image</Filter>
</ClInclude>
@ -57,12 +54,6 @@
<ClInclude Include="gfx_es2\glsl_program.h">
<Filter>gfx</Filter>
</ClInclude>
<ClInclude Include="audio\wav_read.h">
<Filter>audio</Filter>
</ClInclude>
<ClInclude Include="audio\mixer.h">
<Filter>audio</Filter>
</ClInclude>
<ClInclude Include="profiler\profiler.h">
<Filter>profiler</Filter>
</ClInclude>
@ -84,12 +75,6 @@
<ClInclude Include="base\basictypes.h">
<Filter>base</Filter>
</ClInclude>
<ClInclude Include="base\scoped_ptr.h">
<Filter>base</Filter>
</ClInclude>
<ClInclude Include="base\stats.h">
<Filter>base</Filter>
</ClInclude>
<ClInclude Include="gfx\gl_lost_manager.h">
<Filter>gfx</Filter>
</ClInclude>
@ -102,12 +87,6 @@
<ClInclude Include="base\timeutil.h">
<Filter>base</Filter>
</ClInclude>
<ClInclude Include="base\error_context.h">
<Filter>base</Filter>
</ClInclude>
<ClInclude Include="gfx\texture.h">
<Filter>gfx</Filter>
</ClInclude>
<ClInclude Include="input\gesture_detector.h">
<Filter>input</Filter>
</ClInclude>
@ -120,9 +99,6 @@
<ClInclude Include="base\colorutil.h">
<Filter>base</Filter>
</ClInclude>
<ClInclude Include="gfx\texture_gen.h">
<Filter>gfx</Filter>
</ClInclude>
<ClInclude Include="json\json_writer.h">
<Filter>json</Filter>
</ClInclude>
@ -132,9 +108,6 @@
<ClInclude Include="file\path.h">
<Filter>file</Filter>
</ClInclude>
<ClInclude Include="gfx_es2\vertex_format.h">
<Filter>gfx</Filter>
</ClInclude>
<ClInclude Include="base\NativeApp.h">
<Filter>base</Filter>
</ClInclude>
@ -144,18 +117,9 @@
<ClInclude Include="ui\ui.h">
<Filter>ui</Filter>
</ClInclude>
<ClInclude Include="midi\midi_input.h">
<Filter>midi</Filter>
</ClInclude>
<ClInclude Include="file\dialog.h">
<Filter>file</Filter>
</ClInclude>
<ClInclude Include="base\mutex.h">
<Filter>base</Filter>
</ClInclude>
<ClInclude Include="util\bits\bits.h">
<Filter>util</Filter>
</ClInclude>
<ClInclude Include="data\listable.h">
<Filter>data</Filter>
</ClInclude>
@ -183,18 +147,9 @@
<ClInclude Include="base\backtrace.h">
<Filter>base</Filter>
</ClInclude>
<ClInclude Include="base\fastlist.h">
<Filter>base</Filter>
</ClInclude>
<ClInclude Include="math\lin\aabb.h">
<Filter>math</Filter>
</ClInclude>
<ClInclude Include="math\lin\plane.h">
<Filter>math</Filter>
</ClInclude>
<ClInclude Include="util\random\perlin.h">
<Filter>util</Filter>
</ClInclude>
<ClInclude Include="util\random\rng.h">
<Filter>util</Filter>
</ClInclude>
@ -207,9 +162,6 @@
<ClInclude Include="ui\ui_context.h">
<Filter>ui</Filter>
</ClInclude>
<ClInclude Include="ext\stb_vorbis\stb_vorbis.h">
<Filter>ext</Filter>
</ClInclude>
<ClInclude Include="gfx_es2\gpu_features.h">
<Filter>gfx</Filter>
</ClInclude>
@ -383,12 +335,6 @@
<ClCompile Include="gfx_es2\glsl_program.cpp">
<Filter>gfx</Filter>
</ClCompile>
<ClCompile Include="audio\wav_read.cpp">
<Filter>audio</Filter>
</ClCompile>
<ClCompile Include="audio\mixer.cpp">
<Filter>audio</Filter>
</ClCompile>
<ClCompile Include="profiler\profiler.cpp">
<Filter>profiler</Filter>
</ClCompile>
@ -410,12 +356,6 @@
<ClCompile Include="base\timeutil.cpp">
<Filter>base</Filter>
</ClCompile>
<ClCompile Include="base\error_context.cpp">
<Filter>base</Filter>
</ClCompile>
<ClCompile Include="gfx\texture.cpp">
<Filter>gfx</Filter>
</ClCompile>
<ClCompile Include="input\gesture_detector.cpp">
<Filter>input</Filter>
</ClCompile>
@ -425,9 +365,6 @@
<ClCompile Include="base\colorutil.cpp">
<Filter>base</Filter>
</ClCompile>
<ClCompile Include="gfx\texture_gen.cpp">
<Filter>gfx</Filter>
</ClCompile>
<ClCompile Include="json\json_writer.cpp">
<Filter>json</Filter>
</ClCompile>
@ -437,24 +374,12 @@
<ClCompile Include="file\path.cpp">
<Filter>file</Filter>
</ClCompile>
<ClCompile Include="gfx_es2\vertex_format.cpp">
<Filter>gfx</Filter>
</ClCompile>
<ClCompile Include="base\display.cpp">
<Filter>base</Filter>
</ClCompile>
<ClCompile Include="ui\ui.cpp">
<Filter>ui</Filter>
</ClCompile>
<ClCompile Include="midi\midi_input.cpp">
<Filter>midi</Filter>
</ClCompile>
<ClCompile Include="file\dialog.cpp">
<Filter>file</Filter>
</ClCompile>
<ClCompile Include="util\bits\bits.cpp">
<Filter>util</Filter>
</ClCompile>
<ClCompile Include="math\math_util.cpp">
<Filter>math</Filter>
</ClCompile>
@ -479,15 +404,9 @@
<ClCompile Include="base\backtrace.cpp">
<Filter>base</Filter>
</ClCompile>
<ClCompile Include="math\lin\aabb.cpp">
<Filter>math</Filter>
</ClCompile>
<ClCompile Include="math\lin\plane.cpp">
<Filter>math</Filter>
</ClCompile>
<ClCompile Include="util\random\perlin.cpp">
<Filter>util</Filter>
</ClCompile>
<ClCompile Include="ui\virtual_input.cpp">
<Filter>ui</Filter>
</ClCompile>
@ -499,9 +418,6 @@
</ClCompile>
<ClCompile Include="base\BlackberryMain.cpp" />
<ClCompile Include="base\PCMain.cpp" />
<ClCompile Include="ext\stb_vorbis\stb_vorbis.c">
<Filter>ext</Filter>
</ClCompile>
<ClCompile Include="base\BlackberryMain.cpp">
<Filter>base</Filter>
</ClCompile>
@ -835,9 +751,6 @@
<Filter Include="ext">
<UniqueIdentifier>{5c54b5e2-1bb2-4783-9df6-de4ff7105570}</UniqueIdentifier>
</Filter>
<Filter Include="audio">
<UniqueIdentifier>{4ea45f6c-de87-44a9-95b2-e1ec7e3601d0}</UniqueIdentifier>
</Filter>
<Filter Include="profiler">
<UniqueIdentifier>{c57b41dd-cc33-46ac-b479-19676455ae54}</UniqueIdentifier>
</Filter>
@ -859,9 +772,6 @@
<Filter Include="ui">
<UniqueIdentifier>{d738c2d1-749d-4b60-b98f-f3da0bbbf40c}</UniqueIdentifier>
</Filter>
<Filter Include="midi">
<UniqueIdentifier>{4710a9a2-d1fa-4920-ba1b-a7527902be53}</UniqueIdentifier>
</Filter>
<Filter Include="util">
<UniqueIdentifier>{e36ca540-863c-496b-b0f4-b1ece3e72feb}</UniqueIdentifier>
</Filter>

View File

@ -25,6 +25,7 @@
#include "base/buffer.h"
#include "file/fd_util.h"
#include "net/http_server.h"
#include "thread/executor.h"
namespace http {

View File

@ -109,10 +109,8 @@ void ScreenManager::render() {
iter--;
iter--;
Layer backback = *iter;
UIDisableBegin();
// Also shift to the right somehow...
backback.screen->render();
UIDisableEnd();
stack_.back().screen->render();
break;
}

View File

@ -8,7 +8,6 @@
#include "base/colorutil.h"
#include "ui/ui.h"
#include "ui/ui_context.h"
#include "gfx/texture.h"
#include "gfx/texture_atlas.h"
#include "gfx_es2/draw_buffer.h"
@ -16,70 +15,10 @@
DrawBuffer ui_draw2d;
DrawBuffer ui_draw2d_front;
// This one, though, is OK.
UIState uistate;
UIState savedUistate;
// Theme.
static const Atlas *themeAtlas;
static UITheme theme;
void UIInit(const Atlas *atlas, const UITheme &ui_theme) {
ui_draw2d.SetAtlas(atlas);
ui_draw2d_front.SetAtlas(atlas);
themeAtlas = atlas;
theme = ui_theme;
memset(&uistate, 0, sizeof(uistate));
}
void UIDisableBegin()
{
savedUistate = uistate;
memset(&uistate, 0, sizeof(uistate));
}
void UIDisableEnd()
{
uistate = savedUistate;
}
void UIUpdateMouse(int i, float x, float y, bool down) {
if (down && !uistate.mousedown[i]) {
uistate.mousepressed[i] = 1;
uistate.mouseStartX[i] = x;
uistate.mouseStartY[i] = y;
} else {
uistate.mousepressed[i] = 0;
}
uistate.mousex[i] = x;
uistate.mousey[i] = y;
uistate.mousedown[i] = down;
if (uistate.mousedown[i])
uistate.mouseframesdown[i]++;
else
uistate.mouseframesdown[i] = 0;
}
void UIReset() {
memset(&uistate, 0, sizeof(uistate));
}
bool UIRegionHit(int i, int x, int y, int w, int h, int margin) {
// Input handling
if (uistate.mousex[i] < x - margin ||
uistate.mousey[i] < y - margin ||
uistate.mousex[i] >= x + w + margin ||
uistate.mousey[i] >= y + h + margin) {
return false;
} else {
return true;
}
}
void UIBegin(Thin3DShaderSet *shaderSet) {
for (int i = 0; i < MAX_POINTERS; i++)
uistate.hotitem[i] = 0;
ui_draw2d.Begin(shaderSet);
ui_draw2d_front.Begin(shaderSet);
}
@ -90,520 +29,10 @@ void UIFlush() {
}
void UIEnd() {
for (int i = 0; i < MAX_POINTERS; i++) {
if (uistate.mousedown[i] == 0) {
uistate.activeitem[i] = 0;
} else {
if (uistate.activeitem[i] == 0) {
uistate.activeitem[i] = -1;
}
}
}
ui_draw2d.End();
ui_draw2d_front.End();
if (uistate.ui_tick > 0)
uistate.ui_tick--;
ui_draw2d.Flush();
ui_draw2d_front.Flush();
}
void UIText(int x, int y, const char *text, uint32_t color, float scale, int align) {
UIText(theme.uiFont, x, y, text, color, scale, align);
}
void UIText(int font, int x, int y, const char *text, uint32_t color, float scale, int align) {
ui_draw2d.SetFontScale(scale, scale);
ui_draw2d.DrawTextShadow(font, text, x, y, color, align);
ui_draw2d.SetFontScale(1.0f, 1.0f);
}
void UIText(int font, const LayoutManager &layout, const char *text, uint32_t color, float scale, int align)
{
ui_draw2d.SetFontScale(scale, scale);
float w, h;
ui_draw2d.MeasureText(font, text, &w, &h);
float x, y;
layout.GetPos(&w, &h, &x, &y);
UIText(font, x, y, text, color, scale, 0);
ui_draw2d.SetFontScale(1.0f, 1.0f);
}
int UIButton(int id, const LayoutManager &layout, float w, float h, const char *text, int button_align) {
if (h == 0.0f)
h = themeAtlas->images[theme.buttonImage].h;
float x, y;
layout.GetPos(&w, &h, &x, &y);
if (button_align & ALIGN_HCENTER) x -= w / 2;
if (button_align & ALIGN_VCENTER) y -= h / 2;
if (button_align & ALIGN_RIGHT) x -= w;
if (button_align & ALIGN_BOTTOM) y -= h;
int txOffset = 0;
int clicked = 0;
for (int i = 0; i < MAX_POINTERS; i++) {
// Check whether the button should be hot, use a generous margin for touch ease
if (UIRegionHit(i, x, y, w, h, 8)) {
uistate.hotitem[i] = id;
if (uistate.activeitem[i] == 0 && uistate.mousedown[i]) {
uistate.activeitem[i] = id;
}
}
if (uistate.hotitem[i] == id) {
if (uistate.activeitem[i] == id) {
// Button is both 'hot' and 'active'
txOffset = 2;
} else {
// Button is merely 'hot'
}
} else {
// button is not hot, but it may be active
}
// If button is hot and active, but mouse button is not
// down, the user must have clicked the button.
if (uistate.mousedown[i] == 0 &&
uistate.hotitem[i] == id &&
uistate.activeitem[i] == id) {
clicked = 1;
}
}
// Render button
if (h == themeAtlas->images[theme.buttonImage].h)
ui_draw2d.DrawImage2GridH((txOffset && theme.buttonSelected) ? theme.buttonSelected : theme.buttonImage, x, y, x + w);
else
ui_draw2d.DrawImage4Grid((txOffset && theme.buttonSelected) ? theme.buttonSelected : theme.buttonImage, x, y, x + w, y + h);
ui_draw2d.DrawTextShadow(theme.uiFont, text, x + w/2, y + h/2 + txOffset, 0xFFFFFFFF, ALIGN_HCENTER | ALIGN_VCENTER);
uistate.lastwidget = id;
return clicked;
}
int UIImageButton(int id, const LayoutManager &layout, float w, int image, int button_align) {
float h = 64;
float x, y;
layout.GetPos(&w, &h, &x, &y);
if (button_align & ALIGN_HCENTER) x -= w / 2;
if (button_align & ALIGN_VCENTER) y -= h / 2;
if (button_align & ALIGN_RIGHT) x -= w;
if (button_align & ALIGN_BOTTOMRIGHT) y -= h;
int txOffset = 0;
int clicked = 0;
for (int i = 0; i < MAX_POINTERS; i++) {
// Check whether the button should be hot, use a generous margin for touch ease
if (UIRegionHit(i, x, y, w, h, 8)) {
uistate.hotitem[i] = id;
if (uistate.activeitem[i] == 0 && uistate.mousedown[i])
uistate.activeitem[i] = id;
}
if (uistate.hotitem[i] == id) {
if (uistate.activeitem[i] == id) {
// Button is both 'hot' and 'active'
txOffset = 2;
} else {
// Button is merely 'hot'
}
} else {
// button is not hot, but it may be active
}
// If button is hot and active, but mouse button is not
// down, the user must have clicked the button.
if (uistate.mousedown[i] == 0 &&
uistate.hotitem[i] == id &&
uistate.activeitem[i] == id) {
clicked = 1;
}
}
// Render button
ui_draw2d.DrawImage2GridH(theme.buttonImage, x, y, x + w);
ui_draw2d.DrawImage(image, x + w/2, y + h/2 + txOffset, 1.0f, 0xFFFFFFFF, ALIGN_HCENTER | ALIGN_VCENTER);
uistate.lastwidget = id;
return clicked;
}
int UITextureButton(UIContext *ctx, int id, const LayoutManager &layout, float w, float h, Texture *texture, int button_align, uint32_t color, int drop_shadow) // uses current UI atlas for fetching images.
{
float x, y;
layout.GetPos(&w, &h, &x, &y);
if (button_align & ALIGN_HCENTER) x -= w / 2;
if (button_align & ALIGN_VCENTER) y -= h / 2;
if (button_align & ALIGN_RIGHT) x -= w;
if (button_align & ALIGN_BOTTOMRIGHT) y -= h;
int txOffset = 0;
int clicked = 0;
for (int i = 0; i < MAX_POINTERS; i++) {
// Check whether the button should be hot, use a generous margin for touch ease
if (UIRegionHit(i, x, y, w, h, 8)) {
uistate.hotitem[i] = id;
if (uistate.activeitem[i] == 0 && uistate.mousedown[i])
uistate.activeitem[i] = id;
}
if (uistate.hotitem[i] == id) {
if (uistate.activeitem[i] == id) {
// Button is both 'hot' and 'active'
txOffset = 2;
} else {
// Button is merely 'hot'
}
} else {
// button is not hot, but it may be active
}
// If button is hot and active, but mouse button is not
// down, the user must have clicked the button.
if (uistate.mousedown[i] == 0 &&
uistate.hotitem[i] == id &&
uistate.activeitem[i] == id) {
clicked = 1;
}
}
if (texture) {
float tw = texture->Width();
float th = texture->Height();
// Adjust position so we don't stretch the image vertically or horizontally.
// TODO: Add a param to specify fit? The below assumes it's never too wide.
float nw = h * tw / th;
x += (w - nw) / 2.0f;
w = nw;
}
// Render button
int dropsize = 10;
if (drop_shadow && texture)
{
if (txOffset) {
dropsize = 3;
y += txOffset * 2;
}
ui_draw2d.DrawImage4Grid(drop_shadow, x - dropsize, y, x+w + dropsize, y+h+dropsize*1.5,
blackAlpha(0.5f), 1.0f);
ui_draw2d.Flush(true);
}
if (texture) {
texture->Bind(0);
} else {
ui_draw2d.DrawImage2GridH(theme.buttonImage, x, y, x + w, color);
ui_draw2d.Flush();
Texture::Unbind();
}
ui_draw2d.DrawTexRect(x, y, x+w, y+h, 0, 0, 1, 1, color);
ui_draw2d.Flush();
ctx->RebindTexture();
uistate.lastwidget = id;
return clicked;
}
int UICheckBox(int id, int x, int y, const char *text, int align, bool *value) {
#ifdef _WIN32
const int h = 32;
#else
const int h = 48;
#endif
float tw, th;
ui_draw2d.MeasureText(theme.uiFont, text, &tw, &th);
int w = themeAtlas->images[theme.checkOn].w + UI_SPACE + tw;
if (align & ALIGN_HCENTER) x -= w / 2;
if (align & ALIGN_VCENTER) y -= h / 2;
if (align & ALIGN_RIGHT) x -= w;
if (align & ALIGN_BOTTOMRIGHT) y -= h;
int txOffset = 0;
int clicked = 0;
for (int i = 0; i < MAX_POINTERS; i++) {
// Check whether the button should be hot
if (UIRegionHit(i, x, y, w, h, 8)) {
uistate.hotitem[i] = id;
if (uistate.activeitem[i] == 0 && uistate.mousedown[i])
uistate.activeitem[i] = id;
}
// Render button
if (uistate.hotitem[i] == id) {
if (uistate.activeitem[i] == id) {
// Button is both 'hot' and 'active'
txOffset = 2;
} else {
// Button is merely 'hot'
}
} else {
// button is not hot, but it may be active
}
// If button is hot and active, but mouse button is not
// down, the user must have clicked the button.
if (uistate.mousedown[i] == 0 &&
uistate.hotitem[i] == id &&
uistate.activeitem[i] == id) {
*value = !(*value);
clicked = 1;
}
}
ui_draw2d.DrawImage((*value) ? theme.checkOn : theme.checkOff, x, y+h/2, 1.0f, 0xFFFFFFFF, ALIGN_LEFT | ALIGN_VCENTER);
ui_draw2d.DrawTextShadow(theme.uiFont, text, x + themeAtlas->images[theme.checkOn].w + UI_SPACE, y + txOffset + h/2, 0xFFFFFFFF, ALIGN_LEFT | ALIGN_VCENTER);
uistate.lastwidget = id;
return clicked;
}
void StringVectorListAdapter::drawItem(int item, int x, int y, int w, int h, bool selected) const
{
ui_draw2d.DrawImage2GridH(theme.buttonImage, x, y, x + w);
ui_draw2d.DrawTextShadow(theme.uiFont, (*items_)[item].c_str(), x + UI_SPACE , y, 0xFFFFFFFF, ALIGN_LEFT | ALIGN_VCENTER);
}
UIList::UIList()
: scrollY(0.0f), startDragY(0.0f), dragFinger(-1), selected(-1) {
movedDistanceX = 0.0f;
movedDistanceY = 0.0f;
scrolling = false;
inertiaY = 0.0f;
}
void UIList::pointerDown(int pointer, float x, float y) {
// Instantly halt on pointerDown if inertia-scrolling
scrolling = false;
inertiaY = 0.0f;
startScrollY = scrollY;
startDragY = y;
movedDistanceX = 0.0f;
movedDistanceY = 0.0f;
}
const int holdFramesClick = 3;
const int holdFramesScroll = 10;
void UIList::pointerMove(int pointer, float x, float y, bool inside) {
float deltaX = x - lastX;
float deltaY = y - lastY;
movedDistanceY += fabsf(deltaY);
movedDistanceX += fabsf(deltaX);
if (inertiaY <= 0.0f && deltaY > 0.0f) {
inertiaY = -deltaY;
} else if (inertiaY >= 0.0f && deltaY < 0.0f) {
inertiaY = -deltaY;
} else {
inertiaY = 0.8 * inertiaY + 0.2 * -deltaY;
}
const int deadzone = 30 * holdFramesScroll;
if (inside && movedDistanceY * uistate.mouseframesdown[0] > deadzone && !scrolling) {
scrolling = true;
}
}
void UIList::pointerUp(int pointer, float x, float y, bool inside) {
// printf("PointerUp %f %f\n", x, y);
}
int UIList::Do(int id, int x, int y, int w, int h, UIListAdapter *adapter) {
int clicked = 0;
// Pointer and focus handling
// UIList only cares about the first pointer for simplicity.
// Probably not much need to scroll one of these while dragging something
// else.
// TODO: Abstract this stuff out into EmulatePointerEvents
for (int i = 0; i < 1; i++) {
// Check for hover
bool isInside = false;
if (UIRegionHit(i, x, y, w, h, 0)) {
isInside = true;
uistate.hotitem[i] = id;
if (uistate.activeitem[i] == 0 && uistate.mousedown[i]) {
// Mousedown
uistate.activeitem[i] = id;
pointerDown(i, uistate.mousex[i], uistate.mousey[i]);
}
}
if (uistate.activeitem[i] == id) {
// NOTE: won't work with multiple pointers
if (uistate.mousex[i] != lastX || uistate.mousey[i] != lastY) {
pointerMove(i, uistate.mousex[i], uistate.mousey[i], isInside);
}
}
// If button is hot and active, but mouse button is not
// down, the user must have clicked a list item (unless after the last item).
if (uistate.mousedown[i] == 0 &&
uistate.activeitem[i] == id &&
selected != -1) {
if (uistate.hotitem[i] == id) {
clicked = 1;
}
pointerUp(i, uistate.mousex[i], uistate.mousey[i], isInside);
}
}
int itemHeight = adapter->itemHeight(0);
int numItems = (int)adapter->getCount();
// Cap total inertia
if (inertiaY > 20) inertiaY = 20;
if (inertiaY < -20) inertiaY = -20;
if (!uistate.mousedown[0]) {
// Let it slide if the pointer is not down
scrollY += inertiaY;
} else if (scrolling /* && mouseY > y && mouseY < y + h*/ ) {
// Pointer is down so stick to it
scrollY = startScrollY - (uistate.mousey[0] - startDragY);
}
// Inertia gradually trails off
inertiaY *= 0.92f;
if (scrolling && fabsf(inertiaY) < 0.001f)
scrolling = false;
// Cap top and bottom softly.
float maxScrollY = numItems * itemHeight - h;
if (maxScrollY < 0.0f) maxScrollY = 0.0f;
if (scrollY > maxScrollY) {
scrollY -= 0.4f * (scrollY - maxScrollY);
} else if (scrollY < 0.0f) {
scrollY += 0.4f * -scrollY;
}
lastX = uistate.mousex[0];
lastY = uistate.mousey[0];
uistate.lastwidget = id;
// Drawing and item hittesting
// render items
for (int i = 0; i < numItems; i++) {
int item_y = y + i * itemHeight - scrollY;
if (item_y >= y - itemHeight && item_y <= y + h) {
for (int k = 0; k < 1; k++) { // MAX_POINTERS if we add back multitouch
if (uistate.mousedown[k] &&
uistate.mouseframesdown[k] >= holdFramesClick &&
adapter->itemEnabled(i) &&
!scrolling &&
selected == -1 &&
UIRegionHit(k, x, item_y, w, itemHeight, 0)) {
selected = i;
} else if (scrolling) {
selected = -1;
}
}
adapter->drawItem(i, x, item_y, w, itemHeight, i == selected);
}
}
// Prevent scroll-clicks from registering
if (selected == -1) clicked = 0;
// Otherwise, no clicky.
return clicked;
}
/*
struct SlideItem {
const char *text;
int image;
uint32_t bgColor;
};
struct SlideState
{
float scroll;
};
void UISlideChoice(int id, int y, const SlideItem *items, int numItems, SlideState *state)
}*/
// TODO
int UIHSlider(int id, int x, int y, int w, int max, int *value) {
// Calculate mouse cursor's relative y offset
int xpos = ((256 - 16) * *value) / max;
for (int i = 0; i < MAX_POINTERS; i++) {
// Check for hotness
if (UIRegionHit(i, x+8, y+8, 16, 255, 0)) {
uistate.hotitem[i] = id;
if (uistate.activeitem[i] == 0 && uistate.mousedown[i])
uistate.activeitem[i] = id;
}
// Update widget value
if (uistate.activeitem[i] == id) {
int mousepos = uistate.mousey[i] - (y + 8);
if (mousepos < 0) mousepos = 0;
if (mousepos > 255) mousepos = 255;
int v = (mousepos * max) / 255;
if (v != *value) {
*value = v;
return 1;
}
}
}
// Render the scrollbar
ui_draw2d.Rect(x, y, 32, 256+16, 0x777777);
ui_draw2d.Rect(x+8+xpos, y+8, 16, 16, 0xffffff);
return 0;
}
/*
// TODO
int UIVSlider(int id, int x, int y, int h, int max, int *value) {
// Calculate mouse cursor's relative y offset
int ypos = ((256 - 16) * *value) / max;
// Check for hotness
if (UIRegionHit(x+8, y+8, 16, 255, 0)) {
uistate.hotitem = id;
if (uistate.activeitem == 0 && uistate.mousedown)
uistate.activeitem = id;
}
// Update widget value
if (uistate.activeitem == id) {
int mousepos = uistate.mousey - (y + 8);
if (mousepos < 0) mousepos = 0;
if (mousepos > 255) mousepos = 255;
int v = (mousepos * max) / 255;
if (v != *value) {
*value = v;
return 1;
}
}
// Render the scrollbar
ui_draw2d.Rect(x, y, 32, 256+16, 0x777777);
ui_draw2d.Rect(x+8, y+8 + ypos, 16, 16, 0xffffff);
return 0;
}
*/

View File

@ -29,135 +29,8 @@
#include "gfx_es2/draw_buffer.h"
#include "input/input_state.h"
class Texture;
class UIContext;
class LayoutManager {
public:
virtual void GetPos(float *w, float *h, float *x, float *y) const = 0;
};
class Pos : public LayoutManager {
public:
Pos(float x, float y) : x_(x), y_(y) {}
virtual void GetPos(float *w, float *h, float *x, float *y) const {
*x = x_;
*y = y_;
}
private:
float x_;
float y_;
};
class HLinear : public LayoutManager {
public:
HLinear(float x, float y, float spacing = 2.0f) : x_(x), y_(y), spacing_(spacing) {}
virtual void GetPos(float *w, float *h, float *x, float *y) const {
*x = x_;
*y = y_;
x_ += *w + spacing_;
}
void Space(float x) {
x_ += x;
}
private:
mutable float x_;
float y_;
float spacing_;
};
class VLinear : public LayoutManager {
public:
VLinear(float x, float y, float spacing = 2.0f) : x_(x), y_(y), spacing_(spacing) {}
virtual void GetPos(float *w, float *h, float *x, float *y) const {
*x = x_;
*y = y_;
y_ += *h + spacing_;
}
private:
float x_;
mutable float y_;
float spacing_;
};
class HGrid : public LayoutManager {
public:
HGrid(float x, float y, float xMax, float xSpacing = 2.0f, float ySpacing = 2.0f)
: x_(x), y_(y), xInit_(x), xMax_(xMax), xSpacing_(xSpacing), ySpacing_(ySpacing) {}
virtual void GetPos(float *w, float *h, float *x, float *y) const {
*x = x_;
*y = y_;
x_ += *w + xSpacing_;
if (x_ >= xMax_) {
x_ = xInit_;
y_ += *h + ySpacing_;
}
}
private:
mutable float x_;
mutable float y_;
float xInit_;
float xMax_;
float xSpacing_;
float ySpacing_;
};
class VGrid : public LayoutManager {
public:
VGrid(float x, float y, float yMax, float xSpacing = 2.0f, float ySpacing = 2.0f)
: x_(x), y_(y), yInit_(y), yMax_(yMax), xSpacing_(xSpacing), ySpacing_(ySpacing) {}
virtual void GetPos(float *w, float *h, float *x, float *y) const {
*x = x_;
*y = y_;
y_ += *h + ySpacing_;
if (y_ + *h >= yMax_) {
x_ += *w + xSpacing_;
y_ = yInit_;
}
}
private:
mutable float x_;
mutable float y_;
float yInit_;
float yMax_;
float xSpacing_;
float ySpacing_;
};
// "Mouse" out of habit, applies just as well to touch events.
// TODO: Change to "pointer"
// This struct is zeroed on init, so should be valid at that state.
// Never inherit from this.
struct UIState {
int mousex[MAX_POINTERS];
int mousey[MAX_POINTERS];
bool mousedown[MAX_POINTERS];
bool mousepressed[MAX_POINTERS];
short mouseframesdown[MAX_POINTERS];
int mouseStartX[MAX_POINTERS];
int mouseStartY[MAX_POINTERS];
int hotitem[MAX_POINTERS];
int activeitem[MAX_POINTERS];
// keyboard focus, not currently used
int kbdwidget;
int lastwidget;
int ui_tick;
// deprecated: tempfloat
float tempfloat;
};
// This needs to be extern so that additional UI controls can be developed outside this file.
extern UIState uistate;
struct Atlas;
// This is the drawbuffer used for UI. Remember to flush it at the end of the frame.
@ -165,41 +38,7 @@ struct Atlas;
extern DrawBuffer ui_draw2d;
extern DrawBuffer ui_draw2d_front; // for things that need to be on top of the rest
struct UITheme {
int uiFont;
int uiFontSmall;
int uiFontSmaller;
int buttonImage;
int buttonSelected;
int checkOn;
int checkOff;
};
// The atlas needs to stick around, the theme is copied.
void UIInit(const Atlas *atlas, const UITheme &theme);
// Between these, UI components won't see pointer events.
void UIDisableBegin();
void UIDisableEnd();
// Just lets you retrieve the theme that was passed into UIInit, for your own controls for example.
UITheme &UIGetTheme();
// TODO: These don't really belong here.
const int UI_SPACE = 32;
const int SMALL_BUTTON_WIDTH = 128;
const int LARGE_BUTTON_WIDTH = 192;
const int BUTTON_HEIGHT = 72;
struct SlideItem {
const char *text;
int image;
uint32_t bgColor;
};
struct UISlideState {
float scroll;
};
// Implement this interface to style your lists
class UIListAdapter {
@ -221,9 +60,6 @@ private:
};
// Utility functions, useful when implementing your own controls
bool UIRegionHit(int pointerId, int x, int y, int w, int h, int margin);
// Call at start of frame
void UIBegin(Thin3DShaderSet *shaderSet);
@ -232,69 +68,3 @@ void UIBegin(Thin3DShaderSet *shaderSet);
void UIEnd();
void UIFlush();
void UIUpdateMouse(int i, float x, float y, bool down);
// Call when you switch screens
void UIReset();
// Returns 1 if clicked
int UIButton(int id, const LayoutManager &layout, float w, float h, const char *text, int button_align);
int UIImageButton(int id, const LayoutManager &layout, float w, int image_id, int button_align); // uses current UI atlas for fetching images.
int UITextureButton(UIContext *ctx, int id, const LayoutManager &layout, float w, float h, Texture *texture, int button_align, uint32_t color, int drop_shadow=0); // uses current UI atlas for fetching images.
// Returns 1 if clicked, puts the value in *value (where it also gets the current state).
int UICheckBox(int id, int x, int y, const char *text, int align, bool *value);
// Vertical slider. Not yet working.
// int UIVSlider(int id, int x, int y, int h, int max, int *value);
// Horizontal slider. Not yet working.
int UIHSlider(int id, int x, int y, int w, int max, int *value);
// Draws static text, that does not participate in any focusing scheme etc, it just is.
void UIText(int font, int x, int y, const char *text, uint32_t color, float scale = 1.0f, int align = ALIGN_TOPLEFT);
void UIText(int x, int y, const char *text, uint32_t color, float scale = 1.0f, int align = ALIGN_TOPLEFT);
void UIText(int font, const LayoutManager &layout, const char *text, uint32_t color, float scale = 1.0f, int align = ALIGN_TOPLEFT);
// Slide choice, like the Angry Birds level selector. Not yet working.
void UISlideChoice(int id, int y, const SlideItem *items, int numItems, UISlideState *state);
class UIList {
public:
UIList();
bool scrolling;
int activePointer;
float startScrollY;
float scrollY;
float lastX;
float lastY;
float startDragY;
float movedDistanceX;
float movedDistanceY;
float inertiaY;
int dragFinger;
int selected;
// List view.
// return -1 = no selection
int Do(int id, int x, int y, int w, int h, UIListAdapter *adapter);
// Call this when the content has changed, to reset scroll position etc.
void contentChanged() {
scrollY = 0.0f;
inertiaY = 0.0f;
}
void scrollRelative(float delta) {
scrollY += delta;
}
private:
// TODO: Migrate to using these directly.
void pointerDown(int pointer, float x, float y);
void pointerUp(int pointer, float x, float y, bool inside);
void pointerMove(int pointer, float x, float y, bool inside);
DISALLOW_COPY_AND_ASSIGN(UIList);
};

View File

@ -7,7 +7,6 @@
#include "input/input_state.h"
#include "input/keycodes.h"
#include "gfx_es2/draw_buffer.h"
#include "gfx/texture.h"
#include "gfx/texture_atlas.h"
#include "util/text/utf8.h"
#include "ui/ui.h"
@ -573,28 +572,6 @@ void ImageView::Draw(UIContext &dc) {
dc.Draw()->DrawImage(atlasImage_, bounds_.x, bounds_.y, scale, 0xFFFFFFFF, ALIGN_TOPLEFT);
}
void TextureView::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
// TODO: involve sizemode
if (texture_) {
w = (float)texture_->Width();
h = (float)texture_->Height();
} else {
w = 16;
h = 16;
}
}
void TextureView::Draw(UIContext &dc) {
// TODO: involve sizemode
if (texture_) {
dc.Flush();
texture_->Bind(0);
dc.Draw()->Rect(bounds_.x, bounds_.y, bounds_.w, bounds_.h, color_);
dc.Flush();
dc.RebindTexture();
}
}
void Thin3DTextureView::GetContentDimensions(const UIContext &dc, float &w, float &h) const {
// TODO: involve sizemode
if (texture_) {

View File

@ -11,12 +11,12 @@
#include <vector>
#include <cmath>
#include <cstdio>
#include <memory>
#include "base/logging.h"
#include "base/functional.h"
#include "base/mutex.h"
#include "base/basictypes.h"
#include "base/scoped_ptr.h"
#include "gfx/texture_atlas.h"
#include "math/lin/matrix4x4.h"
#include "math/math_util.h"
@ -24,6 +24,10 @@
#undef small
#ifdef __SYMBIAN32__
#define unique_ptr auto_ptr
#endif
struct KeyInput;
struct TouchInput;
struct AxisInput;
@ -365,7 +369,7 @@ public:
protected:
// Inputs to layout
scoped_ptr<LayoutParams> layoutParams_;
std::unique_ptr<LayoutParams> layoutParams_;
std::string tag_;
Visibility visibility_;
@ -377,7 +381,7 @@ protected:
// Outputs of layout. X/Y are absolute screen coordinates, hierarchy is "gone" here.
Bounds bounds_;
scoped_ptr<Matrix4x4> transform_;
std::unique_ptr<Matrix4x4> transform_;
private:
bool *enabledPtr_;
@ -741,25 +745,6 @@ private:
ImageSizeMode sizeMode_;
};
// TextureView takes a texture that is assumed to be alive during the lifetime
// of the view.
class TextureView : public InertView {
public:
TextureView(Texture *texture, ImageSizeMode sizeMode, LayoutParams *layoutParams = 0)
: InertView(layoutParams), texture_(texture), sizeMode_(sizeMode) {}
void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
void Draw(UIContext &dc) override;
void SetTexture(Texture *texture) { texture_ = texture; }
void SetColor(uint32_t color) { color_ = color; }
private:
Texture *texture_;
uint32_t color_;
ImageSizeMode sizeMode_;
};
// TextureView takes a texture that is assumed to be alive during the lifetime
// of the view.
class Thin3DTextureView : public InertView {

View File

@ -1,7 +1,5 @@
set(SRCS
bits/bits.cpp
bits/varint.cpp
random/perlin.cpp
hash/hash.cpp
text/utf8.cpp
)

View File

@ -1,40 +0,0 @@
#include "util/bits/bits.h"
namespace bits {
// See http://graphics.stanford.edu/~seander/bithacks.html
static const unsigned char BitsSetTable256[] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
};
int CountBits8(uint8_t v) {
return BitsSetTable256[v];
}
int CountBits16(uint16_t v) {
return BitsSetTable256[v & 0xFF] + BitsSetTable256[v >> 8];
}
int CountBits32(uint32_t v) {
v = v - ((v >> 1) & 0x55555555); // reuse input as temporary
v = (v & 0x33333333) + ((v >> 2) & 0x33333333); // temp
return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count
}
} // namespace bits

View File

@ -1,65 +0,0 @@
#ifndef _UTIL_BITS_BITS
#define _UTIL_BITS_BITS
#include "base/basictypes.h"
namespace bits {
int CountBits8(uint8_t v);
int CountBits16(uint16_t v);
int CountBits32(uint32_t v);
// where mask is 0, the result is a.
// where mask is 1, the result is b.
inline uint32_t MixBits(uint32_t a, uint32_t b, uint32_t mask) {
return a ^ ((a ^ b) & mask);
}
inline uint32_t ComputeParity(uint32_t v) {
v ^= v >> 16;
v ^= v >> 8;
v ^= v >> 4;
v &= 0xf;
return (0x6996 >> v) & 1;
}
} // namespace bits
#ifndef _MSC_VER
// These are built-ins in MSVC, let's define them for other OS:es as well.
inline uint32_t _rotl(uint32_t val, int shift) {
return (val << shift) | (val >> (31 - shift));
}
inline uint32_t _rotr(uint32_t val, int shift) {
return (val << shift) | (val >> (31 - shift));
}
/*
template <int SZ>
class BitArray {
public:
BitArray() {
memset(data, 0, sizeof(data));
}
BitArray And(const BitArray &other) {
BitArray<SZ> retVal;
for (int i = 0; i < DATACOUNT; i++) {
retVal.data[i] = data[i] & other.data[i];
}
}
private:
uint32 data[(SZ + 31) / 32];
enum {
DATACOUNT = (SZ + 31) / 32;
};
};
*/
#endif
#endif

View File

@ -1,27 +0,0 @@
#ifndef _UTIL_BITS_HAMMING
#define _UTIL_BITS_HAMMING
#include <string>
#include "base/logging.h"
inline int Hamming(const std::string &a, const std::string &b) {
CHECK_EQ(a.size(), b.size());
int hamming = 0;
for (size_t i = 0; i < a.size(); i++)
hamming += a[i] == b[i];
return hamming;
}
inline int Hamming4(const std::string &a, const std::string &b) {
CHECK_EQ(a.size(), b.size());
int hamming = 0;
const uint32 *au = (const uint32 *)a.data();
const uint32 *bu = (const uint32 *)b.data();
for (size_t i = 0; i < a.size() / 4; i++)
hamming += au[i] == bu[i];
return hamming * 4;
}
#endif // _UTIL_BITS_HAMMING

View File

@ -1,35 +0,0 @@
#include "util/bits/varint.h"
namespace varint {
void Encode32(uint32_t value, char **dest) {
// Simple varint
char *p = *dest;
while (value > 127) {
*p++ = (value & 127);
value >>= 7;
}
*p++ = value | 0x80;
*dest = p;
}
uint32_t Decode32(const char **ptr) {
uint32_t value = 0;
const char *p = *ptr;
while (true) {
uint8_t b = *p++;
if (b & 0x80) {
*ptr = p;
return value | (b & 0x7F);
} else {
value |= *p++;
value <<= 7;
}
}
*ptr = p;
return value;
}
} // namespace varint

View File

@ -1,13 +0,0 @@
#ifndef _UTIL_BITS_VARINT
#define _UTIL_BITS_VARINT
#include "base/basictypes.h"
namespace varint {
void Encode32(uint32_t value, char **dest);
uint32_t Decode32(const char **ptr);
} // namespace varint
#endif // _UTIL_BITS_VARINT

View File

@ -1,72 +0,0 @@
#include "util/random/perlin.h"
#include <math.h>
// This should go in the const section of the binary.
static const int p[512] = {
151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
};
inline float fade(float t) {
return t * t * t * (t * (t * 6 - 15) + 10);
}
inline float lerp(float t, float a, float b) {
return a + t * (b - a);
}
inline float grad(int hash, float x, float y, float z) {
int h = hash & 15; // CONVERT LO 4 BITS OF HASH CODE
float u = h < 8 ? x : y; // INTO 12 GRADIENT DIRECTIONS.
float v = h < 4 ? y : (h == 12 || h == 14 ? x : z);
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
}
float Noise(double iz, double iy, double ix) {
double fx = floor(ix), fy = floor(iy), fz = floor(iz);
int X = (int)fx & 255, // FIND UNIT CUBE THAT
Y = (int)fy & 255, // CONTAINS POINT.
Z = (int)fz & 255;
float x = (float)(ix - fx); // FIND RELATIVE X,Y,Z
float y = (float)(iy - fy); // OF POINT IN CUBE.
float z = (float)(iz - fz);
float u = fade(x); // COMPUTE FADE CURVES
float v = fade(y); // FOR EACH OF X,Y,Z.
float w = fade(z);
int A = p[X ]+Y, B = p[X+1]+Y;
int AA = p[A]+Z, AB = p[A+1]+Z; // HASH COORDINATES OF
int BA = p[B]+Z, BB = p[B+1]+Z; // THE 8 CUBE CORNERS,
return lerp(w, lerp(v, lerp(u, grad(p[AA ], x , y , z ), // AND ADD
grad(p[BA ], x-1, y , z )), // BLENDED
lerp(u, grad(p[AB ], x , y-1, z ), // RESULTS
grad(p[BB ], x-1, y-1, z ))), // FROM 8
lerp(v, lerp(u, grad(p[AA+1], x , y , z-1 ), // CORNERS
grad(p[BA+1], x-1, y , z-1 )), // OF CUBE
lerp(u, grad(p[AB+1], x , y-1, z-1 ),
grad(p[BB+1], x-1, y-1, z-1 ))));
}

View File

@ -1,6 +0,0 @@
#pragma once
// Implementation of "Improved Noise"
// http://mrl.nyu.edu/~perlin/noise/
// doubles are only used at the very start, not a big performance worry
float Noise(double x, double y, double z);