buildscripts/build.generic
elif [ "$1" == "generic" ]; then
buildscripts/build.generic
+elif [ "$1" == "android" ]; then
+ buildscripts/build.android
elif [ "$1" == "clean" ]; then
rm -rf bin
- echo "Removed bin directory."
+ echo "RM bin"
+ cd external/Android
+ echo "NDK-CLEAN external/Android"
+ ndk-build clean > /dev/null
+ echo "ANT-CLEAN external/Android"
+ ant clean > /dev/null
+ cd ../../
else
echo "Targets: mingw32, mingw64, linux, generic"
echo "linux32 target was removed. Build in a chroot."
--- /dev/null
+#!/bin/bash
+
+##
+## Use this build script to build for
+## android. GLES2 support is required.
+##
+
+source buildscripts/mk
+
+ROOT=`pwd`
+
+# Extra parameter sets 'we're android' value.
+gith vndc/include/gitrev.hpp "#define WITH_ANDROID 1"
+echo "COPY vndc/*/* -> external/Android/jni/src"
+cp -r $ROOT/vndc/*/* $ROOT/external/Android/jni/src/ > /dev/null 2>&1
+echo "COPY external/zero/*/* -> external/Android/jni/src"
+cp -r $ROOT/external/zero/*/* $ROOT/external/Android/jni/src/ > /dev/null 2>&1
+
+cd $ROOT/external/Android
+
+echo "NDK-BUILD external/Android"
+ndk-build > /dev/null
+echo "ANT-BUILD external/Android"
+ant debug > /dev/null
+
+cd $ROOT
SRC=$ROOT/
LIB=$ROOT/external/lib
BIN=$ROOT/bin
-CXXFLAGS="-DGIT_REV=\"$(git rev-parse HEAD)\""
+
+CXXFLAGS="`pkg-config sdl2 --cflags` `pkg-config SDL2_mixer --cflags` `pkg-config SDL2_image --cflags` `pkg-config SDL2_ttf --cflags`"
+LDFLAGS="`pkg-config sdl2 --libs` `pkg-config SDL2_image --libs` `pkg-config SDL2_ttf --libs` `pkg-config SDL2_mixer --libs`"
+INCLUDE="-I$ROOT/external/zero/include -I$ROOT/vndc/include"
source buildscripts/mk
-LDFLAGS="`pkg-config sdl2 --libs-only-l --libs-only-L` `pkg-config SDL2_image --libs-only-l --libs-only-L` `pkg-config SDL2_ttf --libs-only-l --libs-only-L` `pkg-config SDL2_mixer --libs-only-l --libs-only-L`"
-INCLUDE="-I$ROOT/external/zero/include -I$ROOT/external/out/include -I$ROOT/vndc/include"
+gith vndc/include/gitrev.hpp
newtd
mkmcc external/zero/src
ROOT=`pwd`
SRC=$ROOT/
BIN=$ROOT/bin
-CXXFLAGS="-I$ROOT/external/Windows/i686-w64-mingw32/include -DGIT_REV=\"$(git rev-parse HEAD)\""
+CXXFLAGS="-I$ROOT/external/Windows/i686-w64-mingw32/include"
CROSS=i686-w64-mingw32
LDFLAGS="-L$ROOT/external/Windows/i686-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -lSDL2_mixer -lSDL2_image -lSDL2_ttf -Dmain=SDL_main -Wl,--no-undefined -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -static-libgcc -static-libstdc++ -mwindows"
INCLUDE="-I$ROOT/external/zero/include -I$ROOT/vndc/include"
+gith vndc/include/gitrev.hpp
+
newtd
mkmcc external/zero/src
mkmcc vndc/src
SRC=$ROOT/
BIN=$ROOT/bin
-CXXFLAGS="-I$ROOT/external/Windows/x86_64-w64-mingw32/include -DGIT_REV=\"$(git rev-parse HEAD)\""
+CXXFLAGS="-I$ROOT/external/Windows/x86_64-w64-mingw32/include"
CROSS=x86_64-w64-mingw32
LDFLAGS="-L$ROOT/external/Windows/x86_64-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -lSDL2_mixer -lSDL2_image -lSDL2_ttf -Dmain=SDL_main -Wl,--no-undefined -lm -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -static-libgcc -static-libstdc++"
INCLUDE="-I$ROOT/external/zero/include -I$ROOT/vndc/include"
+gith vndc/include/gitrev.hpp
+
newtd
mkmcc external/zero/src
mkmcc vndc/src
# This is all auxillary functions to simplify the build script.
# I hate makefiles, and cmake so shell scripts work.
-CXX="${CROSS}-g++"
+if [ ! -z "${CROSS}" ]; then
+ CXX="${CROSS}-g++"
+ LD="${CROSS}-g++"
+ AR="${CROSS}-ar rcs"
+else
+ CXX="g++"
+ LD="g++"
+ AR="ar rcs"
+fi
+
CXXFLAGS="$CXXFLAGS -std=gnu++11 -Wall -Werror -Wno-error=pointer-arith"
-LD="${CROSS}-g++"
LDFLAGS="$LDFLAGS -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf"
-AR="${CROSS}-ar rcs"
CA_CMD="$CXX $CXXFLAGS $LDFLAGS"
cd ..
rm -rf td
}
+
+function gith {
+ echo "PROP $1"
+ echo "#ifndef GIT_REV_HDR" > "$ROOT/$1"
+ echo "#define GIT_REV_HDR" >> "$ROOT/$1"
+ echo "#define GIT_REV \"$(git rev-parse HEAD)\"" >> "$ROOT/$1"
+ echo "$2" >> "$ROOT/$1"
+ echo "#endif" >> "$ROOT/$1"
+}
com.gamemaker.game
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="org.libsdl.app"
+ package="com.github.chaoskagami.vnds"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="auto">
android:allowBackup="true"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:hardwareAccelerated="true" >
- <activity android:name="SDLActivity"
+ <activity android:name="VNDCActivity"
android:label="@string/app_name"
android:configChanges="keyboardHidden|orientation"
>
</application>
<!-- Android 2.3.3 -->
- <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="12" />
+ <uses-sdk android:minSdkVersion="12" android:targetSdkVersion="12" />
<!-- OpenGL ES 2.0 -->
<uses-feature android:glEsVersion="0x00020000" />
<?xml version="1.0" encoding="UTF-8"?>
<!-- This should be changed to the name of your project -->
-<project name="SDLActivity" default="help">
+<project name="VNDCActivity" default="help">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked into
# APP_STL := stlport_static
APP_ABI := armeabi armeabi-v7a x86
+APP_STL := gnustl_shared
# Enable this if you want to support loading WebP images
# The library path should be a relative path to this directory.
-SUPPORT_WEBP := true
+SUPPORT_WEBP := false
WEBP_LIBRARY_PATH := external/libwebp-0.3.0
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_CFLAGS := -DLOAD_BMP -DLOAD_GIF -DLOAD_LBM -DLOAD_PCX -DLOAD_PNM \
-DLOAD_TGA -DLOAD_XCF -DLOAD_XPM -DLOAD_XV
-LOCAL_CFLAGS += -O3 -fstrict-aliasing -fprefetch-loop-arrays
+LOCAL_CFLAGS += -O3 -fstrict-aliasing
LOCAL_SRC_FILES := $(notdir $(filter-out %/showimage.c, $(wildcard $(LOCAL_PATH)/*.c)))
$(JPG_LIBRARY_PATH)/jfdctfst.c \
$(JPG_LIBRARY_PATH)/jfdctint.c \
$(JPG_LIBRARY_PATH)/jidctflt.c \
- $(JPG_LIBRARY_PATH)/jidctfst.S \
+ $(JPG_LIBRARY_PATH)/jidctfst.c \
$(JPG_LIBRARY_PATH)/jidctint.c \
$(JPG_LIBRARY_PATH)/jquant1.c \
$(JPG_LIBRARY_PATH)/jquant2.c \
jddctmgr.c jdhuff.c jdinput.c jdmainct.c jdmarker.c jdmaster.c \
jdmerge.c jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c \
jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c jquant1.c \
- jquant2.c jutils.c jmemmgr.c \
- jmem-android.c
+ jquant2.c jutils.c jmemmgr.c jmem-android.c jidctint.c jidctfst.c
-# the assembler is only for the ARM version, don't break the Linux sim
-ifneq ($(TARGET_ARCH),arm)
-ANDROID_JPEG_NO_ASSEMBLER := true
-endif
-
-# temp fix until we understand why this broke cnn.com
-#ANDROID_JPEG_NO_ASSEMBLER := true
-
-ifeq ($(strip $(ANDROID_JPEG_NO_ASSEMBLER)),true)
-LOCAL_SRC_FILES += jidctint.c jidctfst.c
-else
-LOCAL_SRC_FILES += jidctint.c jidctfst.S
-endif
LOCAL_CFLAGS += -DAVOID_TABLES
LOCAL_CFLAGS += -O3 -fstrict-aliasing -fprefetch-loop-arrays
+++ /dev/null
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <machine/cpu-features.h>
-
- .text
- .align
-
- .global jpeg_idct_ifast
- .func jpeg_idct_ifast
-
-// NOTE: sb=r9, fp=r11 ip=r12, sp=r13, lr=r14, pc=r15
-
-// jpeg_idct_ifast (j_decompress_ptr cinfo,
-// jpeg_component_info * compptr,
-// short* coef_block,
-// unsigned char* output_buf,
-// int output_col)
-
-#define local_TMP0123 sp
-#define local_TMP0 [sp, #0]
-#define local_TMP1 [sp, #4]
-#define local_TMP2 [sp, #8]
-#define local_TMP3 [sp, #12]
-#define local_RANGE_TABLE [sp, #16]
-#define local_OUTPUT_COL [sp, #20]
-#define local_OUTPUT_BUF [sp, #24]
-#define local_UNUSED [sp, #28]
-#define off_WORKSPACE 32
-#define local_WORKSPACE [sp, #offWORKSPACE]
-#define local_SIZE (off_WORKSPACE + 8*8*4)
-
-#define off_DECOMPRESS_range_limit_base 324
-#define off_COMPINFO_quanttable 80
-
-#define DCTSIZE 8
-#define VY(x) ((x)*DCTSIZE*2)
-#define QY(x) ((x)*DCTSIZE*4)
-
-#define VX(x) ((x)*2)
-#define QX(x) ((x)*4)
-
-#define FIX_1_414213562 #362
-#define FIX_1_082392200 #277
-#define FIX_1_847759065 #473
-#define FIX_2_613125930 #669
-
-#define RANGE_MASK 1023
-
-
-
-jpeg_idct_ifast:
- PLD [r2, #0]
- stmdb sp!, {r4,r5, r6,r7, r8,r9, r10,r11, r12,lr}
- ldr r4, [sp, #4*10]
- sub sp, #local_SIZE
-
- ldr r10,[r1, #off_COMPINFO_quanttable] // r10 = quanttable
- str r4, local_OUTPUT_COL
- str r3, local_OUTPUT_BUF
- ldr r5, [r0, #off_DECOMPRESS_range_limit_base]
- add r5, r5, #128
- str r5, local_RANGE_TABLE
- mov fp, r2 // fp = coef_block
- add ip, sp, #off_WORKSPACE
-
-VLoopTail:
- ldrsh r0, [fp, #VY(0)]
- ldrsh r1, [fp, #VY(1)]
- ldrsh r2, [fp, #VY(2)]
- ldrsh r3, [fp, #VY(3)]
- ldrsh r4, [fp, #VY(4)]
- ldrsh r5, [fp, #VY(5)]
- ldrsh r6, [fp, #VY(6)]
- ldrsh r7, [fp, #VY(7)]
-
- cmp r1, #0
- orreqs r8, r2, r3
- orreqs r8, r4, r5
- orreqs r8, r6, r7
- beq VLoopHeadZero
-
-VLoopHead:
- // tmp0 = DEQUANTIZE(in[DCTSIZE*0], quant[DCTSIZE*0] (r0)
- // tmp2 = DEQUANTIZE(in[DCTSIZE*4], quant[DCTSIZE*4] (r4)
- // tmp1 = DEQUANTIZE(in[DCTSIZE*2], quant[DCTSIZE*2] (r2)
- // tmp3 = DEQUANTIZE(in[DCTSIZE*6], quant[DCTSIZE*6] (r6)
- // tmp10 = tmp0 + tmp2 (r0)
- // tmp11 = tmp0 - tmp2 (r4)
-
- ldr r9, [r10, #QY(4)]
- ldr r8, [r10, #QY(0)]
-#if __ARM_HAVE_HALFWORD_MULTIPLY
- smulbb r4, r9, r4
- smlabb r0, r8, r0, r4
-#else
- mul r4, r9, r4
- mul r0, r8, r0
- add r0, r4
-#endif
- ldr r9, [r10, #QY(6)]
- ldr r8, [r10, #QY(2)]
- sub r4, r0, r4, lsl #1
-#if __ARM_HAVE_HALFWORD_MULTIPLY
- smulbb r6, r9, r6
- smlabb r2, r8, r2, r6
-#else
- mul r6, r9, r6
- mul r2, r8, r2
- add r2, r6
-#endif
-
- // tmp13 = tmp1 + tmp3 (r2)
- // tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13 (r6)
- // FIX_1_4142... = 362 = 45*8 + 2
- sub r6, r2, r6, lsl #1
- mov r8, #360
- add r8, r8, #2
- mul r9, r6, r8
-
- // tmp0 = tmp10 + tmp13; (r0)
- // tmp3 = tmp10 - tmp13; (r8)
- // tmp1 = tmp11 + tmp12; (r4)
- // tmp2 = tmp11 - tmp12; (r6)
- add r0, r0, r2
- rsb r6, r2, r9, asr #8
- sub r8, r0, r2, lsl #1
- add r4, r4, r6
- sub r6, r4, r6, lsl #1
-
- stmia local_TMP0123, {r0, r4, r6, r8}
-
- // NOTE: be sure to not user r0,r4,r6,r8 soon after stm above
-
- // odd part
- // tmp4 = DEQUANTIZE( in[DCTSIZE*1], quant[DCTSIZE*1] ) (r1)
- // tmp6 = DEQUANTIZE( in[DCTSIZE*5], quant[DCTSIZE*5] ) (r5)
- // tmp5 = DEQUANTIZE( in[DCTSIZE*3], quant[DCTSIZE*3] ) (r3)
- // tmp7 = DEQUANTIZE( in[DCTSIZE*7], quant[DCTSIZE*7] ) (r7)
- // z13 = tmp6 + tmp5; (r0)
- // z10 = tmp6 - tmp5; (r2)
- // z11 = tmp4 + tmp7; (r4)
- // z12 = tmp4 - tmp7; (r6)
-
- ldr r2, [r10, #QY(1)]
- ldr r9, [r10, #QY(5)]
-#if __ARM_HAVE_HALFWORD_MULTIPLY
- smulbb r1, r2, r1
-#else
- mul r1, r2, r1
-#endif
- ldr r2, [r10, #QY(3)]
-#if __ARM_HAVE_HALFWORD_MULTIPLY
- smulbb r5, r9, r5
-#else
- mul r5, r9, r5
-#endif
- ldr r9, [r10, #QY(7)]
-#if __ARM_HAVE_HALFWORD_MULTIPLY
- smlabb r0, r2, r3, r5
- smlabb r4, r9, r7, r1
-#else
- mul r0, r2, r3
- add r0, r5
- mul r4, r9, r7
- add r4, r1
-#endif
- rsb r2, r0, r5, lsl #1
- rsb r6, r4, r1, lsl #1
-
- // tmp7 = z11 + z13; (r7)
- // tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); (r1)
- // FIX_... = 360 + 2
- add r7, r4, r0
- sub r1, r4, r0
- mov r8, #360
- add r8, r8, #2
- mul r1, r8, r1
-
- // z5 = MULTIPLY(z10 + z12, FIX_1_847759065); (r8)
- // tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; (r0)
- // tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; (r2)
- // FIX_1_8477... = 473 = 472 + 1
- // FIX_1_082... = 277 = 276 + 1
- // FIX_2_... = 669 = 668 + 1
- add r8, r2, r6
- mov r9, #472
- mla r8, r9, r8, r8
- mov r9, #276
- mla r0, r6, r9, r6
- mov r9, #668
- mla r2, r9, r2, r2
- sub r0, r0, r8
- rsb r2, r2, r8
-
- // tmp6 = tmp12 - tmp7; (r6)
- // tmp5 = tmp11 - tmp6; (r5)
- // tmp4 = tmp10 + tmp5; (r4)
- rsb r6, r7, r2, asr #8
- rsb r5, r6, r1, asr #8
- add r4, r5, r0, asr #8
-
- ldmia local_TMP0123, {r0, r1, r2, r3}
-
- // wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7);
- // wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7);
- // wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6);
- // wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6);
- // wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5);
- // wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5);
- // wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4);
- // wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4);
-
- add r0, r0, r7
- sub r7, r0, r7, lsl #1
- add r1, r1, r6
- sub r6, r1, r6, lsl #1
- add r2, r2, r5
- sub r5, r2, r5, lsl #1
- sub r3, r3, r4
- add r4, r3, r4, lsl #1
-
- str r0, [ip, #QY(0)]
- str r1, [ip, #QY(1)]
- str r2, [ip, #QY(2)]
- str r3, [ip, #QY(3)]
- str r4, [ip, #QY(4)]
- str r5, [ip, #QY(5)]
- str r6, [ip, #QY(6)]
- str r7, [ip, #QY(7)]
-
- // inptr++; /* advance pointers to next column */
- // quantptr++;
- // wsptr++;
- add fp, fp, #2
- add r10, r10, #4
- add ip, ip, #4
- add r0, sp, #(off_WORKSPACE + 4*8)
- cmp ip, r0
- bne VLoopTail
-
-
-
-HLoopStart:
- // reset pointers
- PLD [sp, #off_WORKSPACE]
- add ip, sp, #off_WORKSPACE
- ldr r10, local_RANGE_TABLE
-
-HLoopTail:
- // output = *output_buf++ + output_col
- ldr r0, local_OUTPUT_BUF
- ldr r1, local_OUTPUT_COL
- ldr r2, [r0], #4
- str r0, local_OUTPUT_BUF
- add fp, r2, r1
-
- PLD [ip, #32]
- ldmia ip!, {r0-r7}
-
- cmp r1, #0
- orreqs r8, r2, r3
- orreqs r8, r4, r5
- orreqs r8, r6, r7
- beq HLoopTailZero
-
-HLoopHead:
- // tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]); (r0)
- // tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]); (r4)
- add r0, r0, r4
- sub r4, r0, r4, lsl #1
-
- // tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]); (r2)
- // tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562) - tmp13; (r6)
- // FIX_... = 360 + 2
- add r2, r2, r6
- sub r6, r2, r6, lsl #1
- mov r8, #360
- add r8, r8, #2
- mul r6, r8, r6
-
- // tmp0 = tmp10 + tmp13; (r0)
- // tmp3 = tmp10 - tmp13; (r8)
- // tmp1 = tmp11 + tmp12; (r4)
- // tmp2 = tmp11 - tmp12; (r6)
- add r0, r0, r2
- rsb r6, r2, r6, asr #8
- sub r8, r0, r2, lsl #1
- add r4, r4, r6
- sub r6, r4, r6, lsl #1
-
- stmia local_TMP0123, {r0, r4, r6, r8}
-
- // Odd part
-
- // z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3]; (r0)
- // z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3]; (r2)
- // z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7]; (r4)
- // z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7]; (r6)
- add r0, r5, r3
- sub r2, r5, r3
- add r4, r1, r7
- sub r6, r1, r7
-
- // tmp7 = z11 + z13; (r7)
- // tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); (r1)
- // FIX_... = 360 + 2
- add r7, r4, r0
- sub r1, r4, r0
- mov r8, #360
- add r8, r8, #2
- mul r1, r8, r1
-
- // z5 = MULTIPLY(z10 + z12, FIX_1_847759065); (r8)
- // tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; (r0)
- // tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; (r2)
- // FIX_1_8477... = 473 = 472 + 1
- // FIX_1_082... = 277 = 276 + 1
- // FIX_2_... = 669 = 668 + 1
- add r8, r2, r6
- mov r9, #472
- mla r8, r9, r8, r8
- mov r9, #276
- mla r0, r6, r9, r6
- mov r9, #668
- mla r2, r9, r2, r2
- sub r0, r0, r8
- sub r2, r8, r2
-
- // tmp6 = tmp12 - tmp7; (r6)
- // tmp5 = tmp11 - tmp6; (r5)
- // tmp4 = tmp10 + tmp5; (r4)
- rsb r6, r7, r2, asr #8
- rsb r5, r6, r1, asr #8
- add r4, r5, r0, asr #8
-
- ldmia local_TMP0123, {r0, r1, r2, r3}
-
- // outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3) & RANGE_MASK];
- // outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3) & RANGE_MASK];
- // outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3) & RANGE_MASK];
- // outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3) & RANGE_MASK];
- // outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3) & RANGE_MASK];
- // outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3) & RANGE_MASK];
- // outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3) & RANGE_MASK];
- // outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3) & RANGE_MASK];
-
- mov r8, #128
- add r0, r0, r7
- sub r7, r0, r7, lsl #1
- add r0, r8, r0, asr #5
- add r7, r8, r7, asr #5
- add r1, r1, r6
- sub r6, r1, r6, lsl #1
- add r1, r8, r1, asr #5
- add r6, r8, r6, asr #5
- add r2, r2, r5
- sub r5, r2, r5, lsl #1
- add r2, r8, r2, asr #5
- add r5, r8, r5, asr #5
- sub r3, r3, r4
- add r4, r3, r4, lsl #1
- add r3, r8, r3, asr #5
- add r4, r8, r4, asr #5
-
-#if __ARM_ARCH__ >= 6
- usat r0, #8, r0
- usat r1, #8, r1
- usat r2, #8, r2
- usat r3, #8, r3
- usat r4, #8, r4
- usat r5, #8, r5
- usat r6, #8, r6
- usat r7, #8, r7
-#else
- cmp r0, #255
- mvnhi r0, r0, asr #31
- andhi r0, #255
- cmp r7, #255
- mvnhi r7, r7, asr #31
- cmp r1, #255
- mvnhi r1, r1, asr #31
- andhi r1, #255
- cmp r6, #255
- mvnhi r6, r6, asr #31
- andhi r6, #255
- cmp r2, #255
- mvnhi r2, r2, asr #31
- andhi r2, #255
- cmp r5, #255
- mvnhi r5, r5, asr #31
- andhi r5, #255
- cmp r3, #255
- mvnhi r3, r3, asr #31
- cmp r4, #255
- mvnhi r4, r4, asr #31
- andhi r4, #255
-#endif
-
- // r3 r2 r1 r0
- orr r0, r0, r1, lsl #8
- orr r0, r0, r2, lsl #16
- orr r0, r0, r3, lsl #24
-
- // r7 r6 r5 r4
- orr r1, r4, r5, lsl #8
- orr r1, r1, r6, lsl #16
- orr r1, r1, r7, lsl #24
- stmia fp, {r0, r1}
-
- add r0, sp, #(off_WORKSPACE + 8*8*4)
- cmp ip, r0
- bne HLoopTail
-
-Exit:
- add sp, sp, #local_SIZE
- ldmia sp!, {r4,r5, r6,r7, r8,r9, r10,r11, r12,lr}
- bx lr
-
-
-VLoopHeadZero:
-// ok, all AC coefficients are 0
- ldr r1, [r10, #QY(0)]
- add fp, fp, #2
- add r10, r10, #4
- mul r0, r1, r0
- str r0, [ip, #QY(0)]
- str r0, [ip, #QY(1)]
- str r0, [ip, #QY(2)]
- str r0, [ip, #QY(3)]
- str r0, [ip, #QY(4)]
- str r0, [ip, #QY(5)]
- str r0, [ip, #QY(6)]
- str r0, [ip, #QY(7)]
- add ip, ip, #4
- add r0, sp, #(off_WORKSPACE + 4*8)
- cmp ip, r0
- beq HLoopStart
- b VLoopTail
-
-HLoopTailZero:
- mov r0, r0, asr #5
- add r0, #128
-
-#if __ARM_ARCH__ >= 6
- usat r0, #8, r0
-#else
- cmp r0, #255
- mvnhi r0, r0, asr #31
- andhi r0, r0, #255
-#endif
-
- orr r0, r0, lsl #8
- orr r0, r0, lsl #16
- mov r1, r0
- stmia fp, {r0, r1}
-
- add r0, sp, #(off_WORKSPACE + 64*4)
- cmp ip, r0
- beq Exit
- b HLoopTail
-
- .endfunc
#include "jpeglib.h"
#include "jdct.h" /* Private declarations for DCT subsystem */
-#ifdef DCT_IFAST_SUPPORTED
-
/*
* This module is specialized to the case DCTSIZE = 8.
*/
-#if DCTSIZE != 8
- Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
-#endif
+# if DCTSIZE != 8
+ Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+# endif
/* Scaling decisions are generally the same as in the LL&M algorithm;
* are fewer one-bits in the constants).
*/
-#if BITS_IN_JSAMPLE == 8
-#define CONST_BITS 8
-#define PASS1_BITS 2
-#else
-#define CONST_BITS 8
-#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
-#endif
+# if BITS_IN_JSAMPLE == 8
+# define CONST_BITS 8
+# define PASS1_BITS 2
+# else
+# define CONST_BITS 8
+# define PASS1_BITS 1 /* lose a little precision to avoid overflow */
+# endif
/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
* causing a lot of useless floating-point operations at run time.
* (With a reasonable C compiler, you can just rely on the FIX() macro...)
*/
-#if CONST_BITS == 8
-#define FIX_1_082392200 ((INT32) 277) /* FIX(1.082392200) */
-#define FIX_1_414213562 ((INT32) 362) /* FIX(1.414213562) */
-#define FIX_1_847759065 ((INT32) 473) /* FIX(1.847759065) */
-#define FIX_2_613125930 ((INT32) 669) /* FIX(2.613125930) */
-#else
-#define FIX_1_082392200 FIX(1.082392200)
-#define FIX_1_414213562 FIX(1.414213562)
-#define FIX_1_847759065 FIX(1.847759065)
-#define FIX_2_613125930 FIX(2.613125930)
-#endif
+# if CONST_BITS == 8
+# define FIX_1_082392200 ((INT32) 277) /* FIX(1.082392200) */
+# define FIX_1_414213562 ((INT32) 362) /* FIX(1.414213562) */
+# define FIX_1_847759065 ((INT32) 473) /* FIX(1.847759065) */
+# define FIX_2_613125930 ((INT32) 669) /* FIX(2.613125930) */
+# else
+# define FIX_1_082392200 FIX(1.082392200)
+# define FIX_1_414213562 FIX(1.414213562)
+# define FIX_1_847759065 FIX(1.847759065)
+# define FIX_2_613125930 FIX(2.613125930)
+# endif
/* We can gain a little more speed, with a further compromise in accuracy,
* rounded result half the time...
*/
-#ifndef USE_ACCURATE_ROUNDING
-#undef DESCALE
-#define DESCALE(x,n) RIGHT_SHIFT(x, n)
-#endif
+# ifndef USE_ACCURATE_ROUNDING
+# undef DESCALE
+# define DESCALE(x,n) RIGHT_SHIFT(x, n)
+# endif
/* Multiply a DCTELEM variable by an INT32 constant, and immediately
* descale to yield a DCTELEM result.
*/
-#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
+# define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
/* Dequantize a coefficient by multiplying it by the multiplier-table
* declared INT32, so a 32-bit multiply will be used.
*/
-#if BITS_IN_JSAMPLE == 8
-#define DEQUANTIZE(coef,quantval) (((IFAST_MULT_TYPE) (coef)) * (quantval))
-#else
-#define DEQUANTIZE(coef,quantval) \
- DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS)
-#endif
+# if BITS_IN_JSAMPLE == 8
+# define DEQUANTIZE(coef,quantval) (((IFAST_MULT_TYPE) (coef)) * (quantval))
+# else
+# define DEQUANTIZE(coef,quantval) \
+ DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS)
+# endif
/* Like DESCALE, but applies to a DCTELEM and produces an int.
* We assume that int right shift is unsigned if INT32 right shift is.
*/
-#ifdef RIGHT_SHIFT_IS_UNSIGNED
-#define ISHIFT_TEMPS DCTELEM ishift_temp;
-#if BITS_IN_JSAMPLE == 8
-#define DCTELEMBITS 16 /* DCTELEM may be 16 or 32 bits */
-#else
-#define DCTELEMBITS 32 /* DCTELEM must be 32 bits */
-#endif
-#define IRIGHT_SHIFT(x,shft) \
- ((ishift_temp = (x)) < 0 ? \
- (ishift_temp >> (shft)) | ((~((DCTELEM) 0)) << (DCTELEMBITS-(shft))) : \
- (ishift_temp >> (shft)))
-#else
-#define ISHIFT_TEMPS
-#define IRIGHT_SHIFT(x,shft) ((x) >> (shft))
-#endif
-
-#ifdef USE_ACCURATE_ROUNDING
-#define IDESCALE(x,n) ((int) IRIGHT_SHIFT((x) + (1 << ((n)-1)), n))
-#else
-#define IDESCALE(x,n) ((int) IRIGHT_SHIFT(x, n))
-#endif
+# ifdef RIGHT_SHIFT_IS_UNSIGNED
+# define ISHIFT_TEMPS DCTELEM ishift_temp;
+# if BITS_IN_JSAMPLE == 8
+# define DCTELEMBITS 16 /* DCTELEM may be 16 or 32 bits */
+# else
+# define DCTELEMBITS 32 /* DCTELEM must be 32 bits */
+# endif
+# define IRIGHT_SHIFT(x,shft) \
+ ((ishift_temp = (x)) < 0 ? \
+ (ishift_temp >> (shft)) | ((~((DCTELEM) 0)) << (DCTELEMBITS-(shft))) : \
+ (ishift_temp >> (shft)))
+# else
+# define ISHIFT_TEMPS
+# define IRIGHT_SHIFT(x,shft) ((x) >> (shft))
+# endif
+
+# ifdef USE_ACCURATE_ROUNDING
+# define IDESCALE(x,n) ((int) IRIGHT_SHIFT((x) + (1 << ((n)-1)), n))
+# else
+# define IDESCALE(x,n) ((int) IRIGHT_SHIFT(x, n))
+# endif
/*
* Perform dequantization and inverse DCT on one block of coefficients.
*/
-GLOBAL(void)
+//GLOBAL(void)
jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
JCOEFPTR coef_block,
JSAMPARRAY output_buf, JDIMENSION output_col)
}
}
-#endif /* DCT_IFAST_SUPPORTED */
+//#endif /* DCT_IFAST_SUPPORTED */
# Enable this if you want to support loading MOD music via modplug
# The library path should be a relative path to this directory.
-SUPPORT_MOD_MODPLUG := true
+SUPPORT_MOD_MODPLUG := false
MODPLUG_LIBRARY_PATH := external/libmodplug-0.8.8.4
# Enable this if you want to support loading MOD music via mikmod
# The library path should be a relative path to this directory.
-SUPPORT_MOD_MIKMOD := true
+SUPPORT_MOD_MIKMOD := false
MIKMOD_LIBRARY_PATH := external/libmikmod-3.1.12
# Enable this if you want to support loading MP3 music via SMPEG
# The library path should be a relative path to this directory.
-SUPPORT_MP3_SMPEG := true
+SUPPORT_MP3_SMPEG := false
SMPEG_LIBRARY_PATH := external/smpeg2-2.0.0
# Enable this if you want to support loading OGG Vorbis music via Tremor
SDL_PATH := ../SDL
-LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include $(ROOT)/external/zero/include $(ROOT)/vndc/include
+LOCAL_C_INCLUDES := \
+$(LOCAL_PATH)/$(SDL_PATH)/include
# Add your application source files here...
-LOCAL_SRC_FILES := $(ROOT)/vndc/*.cpp $(ROOT)/external/zero/src/*.cpp
+LOCAL_SRC_FILES := \
+op_bgload.cpp \
+op_choice.cpp \
+op_cleartext.cpp \
+op_delay.cpp \
+op_fi.cpp \
+op_goto.cpp \
+op_gsetvar.cpp \
+op_if.cpp \
+op_jump.cpp \
+op_music.cpp \
+op_random.cpp \
+op_setimg.cpp \
+op_setvar.cpp \
+op_sound.cpp \
+op_text.cpp \
+Data.cpp \
+Loop.cpp \
+Parse.cpp \
+VNDC.cpp \
+AudioManager.cpp \
+ContextManager.cpp \
+TextManager.cpp \
+UDisplayable.cpp
+
+
+
LOCAL_SHARED_LIBRARIES := SDL2 SDL2_mixer SDL2_ttf SDL2_image
--- /dev/null
+#include "Zero.hpp"
+
+ // Sets up.
+ AudioManager::AudioManager() {
+ int MixerFlags = MIX_INIT_OGG | MIX_INIT_FLAC | MIX_INIT_MP3;
+ if((Mix_Init(MixerFlags) & MixerFlags) != MixerFlags) {
+ // Failed to load.
+ fprintf(stderr, "[E] Failed on Mix_Init. Reported error:\n");
+ fprintf(stderr, "[E] %s\n", Mix_GetError());
+ fprintf(stderr, "[E] Fatal. Dying.\n");
+ exit(-1);
+ }
+
+ uint16_t fmt = 0;
+ int freq = 0, chan = 0;
+ Mix_QuerySpec(&freq, &fmt, &chan);
+
+ if (Mix_OpenAudio(freq, fmt, chan, 1024)) {
+ printf("[Mix:err] %s\n", Mix_GetError());
+ exit(-7);
+ }
+
+ Mix_AllocateChannels(64); // 32 Sfx + 1 Music
+
+ MusicStore = NULL;
+ MusicCount = 0;
+ SfxStore = NULL;
+ SfxCount = 0;
+ }
+
+ // Cleans up everything.
+ AudioManager::~AudioManager() {
+ Mix_HaltChannel(-1);
+ Mix_HaltMusic();
+
+ while (SfxCount > 0) {
+ Mix_FreeChunk(SfxStore[SfxCount-1]);
+ --SfxCount;
+ }
+
+ while (MusicCount > 0) {
+ Mix_FreeMusic(MusicStore[MusicCount-1]);
+ --MusicCount;
+ }
+
+ free(SfxStore);
+ free(MusicStore);
+
+ Mix_CloseAudio();
+
+ while(Mix_Init(0))
+ Mix_Quit();
+ }
+
+ int AudioManager::LoadSfx(char* fname) {
+ ++SfxCount;
+ SfxStore = (Mix_Chunk**)realloc(SfxStore, sizeof(Mix_Chunk*) * SfxCount);
+
+ memset(&SfxStore[SfxCount-1], 0, sizeof(Mix_Chunk*));
+
+ SfxStore[SfxCount-1] = NULL;
+
+ SfxStore[SfxCount-1] = Mix_LoadWAV(fname);
+
+ if(!SfxStore[SfxCount-1]) {
+ --SfxCount;
+ SfxStore = (Mix_Chunk**)realloc(SfxStore, sizeof(Mix_Chunk*) * SfxCount);
+ return -1;
+ }
+
+ return SfxCount - 1;
+ }
+
+ int AudioManager::LoadMusic(char* fname) {
+ ++MusicCount;
+ MusicStore = (Mix_Music**)realloc(MusicStore, sizeof(Mix_Music*) * MusicCount);
+
+ memset(&MusicStore[MusicCount-1], 0, sizeof(Mix_Music*));
+
+ MusicStore[MusicCount-1] = NULL;
+
+ MusicStore[MusicCount-1] = Mix_LoadMUS(fname);
+
+ if(!MusicStore[MusicCount-1]) {
+ --MusicCount;
+ MusicStore = (Mix_Music**)realloc(MusicStore, sizeof(Mix_Music*) * MusicCount);
+ return -1;
+ }
+
+ return MusicCount - 1;
+ }
+
+ void AudioManager::PlaySfx(int index) {
+ if(index == -1)
+ return;
+
+ if (index > SfxCount-1)
+ return; // Not a valid index. No-op.
+
+ Mix_PlayChannel(-1, SfxStore[index], 0);
+ }
+
+ void AudioManager::PlaySfx(int index, int count) {
+ if(index == -1)
+ return;
+
+ if (index > SfxCount-1)
+ return; // Not a valid index. No-op.
+
+ Mix_PlayChannel(-1, SfxStore[index], count);
+ }
+
+ void AudioManager::PlayMusic(int index) {
+ if(index == -1)
+ return;
+
+ // FIXME - Implement this.
+ Mix_PlayMusic(MusicStore[index], 0);
+ }
+
+ void AudioManager::PlayMusicLoop(int index) {
+ if(index == -1)
+ return;
+
+ // FIXME - Implement this.
+ Mix_PlayMusic(MusicStore[index], -1);
+ }
+
+ void AudioManager::PauseMusic() {
+ // FIXME - Implement this.
+ Mix_PauseMusic();
+ }
+
+ void AudioManager::UnloadSfx(int index) {
+ if(index == -1)
+ return;
+
+ Mix_FreeChunk(SfxStore[index]);
+ }
+
+ void AudioManager::UnloadMusic(int index) {
+ if(index == -1)
+ return;
+
+ Mix_FreeMusic(MusicStore[index]);
+ }
+
+ // Unload all sfx
+ void AudioManager::FlushSfx() {
+ Mix_HaltChannel(-1);
+
+ while (SfxCount > 0) {
+ Mix_FreeChunk(SfxStore[SfxCount-1]);
+ --SfxCount;
+ }
+
+ free(SfxStore);
+ SfxStore = NULL;
+ }
+
+ // Unload all music.
+ void AudioManager::FlushMusic() {
+ Mix_HaltMusic();
+
+ while (MusicCount > 0) {
+ Mix_FreeMusic(MusicStore[MusicCount-1]);
+ --MusicCount;
+ }
+
+ free(MusicStore);
+ MusicStore = NULL;
+ }
--- /dev/null
+#ifndef AUDIOMANAGER_HPP
+#define AUDIOMANAGER_HPP
+
+
+ class AudioManager {
+ public:
+ // Ctors and dtors
+ AudioManager();
+ ~AudioManager();
+
+ // Load index.
+ int LoadSfx(char* fname);
+ int LoadMusic(char* fname);
+
+ // Playing functions.
+ void PlaySfx(int index);
+ void PlaySfx(int index, int count);
+ void PlayMusic(int index);
+ void PlayMusicLoop(int index);
+ void PauseMusic();
+
+ // Unload Functions
+ void UnloadSfx(int index);
+ void UnloadMusic(int index);
+
+ // Complete unload functions
+ void FlushSfx();
+ void FlushMusic();
+ private:
+ int SfxCount, MusicCount;
+ Mix_Chunk** SfxStore;
+ Mix_Music** MusicStore;
+ };
+
+
+#endif
--- /dev/null
+#include "Zero.hpp"
+
+
+ void ContextManager::DefaultVariables() {
+ inputmode = Medium;
+ window = NULL;
+ surface = NULL; surface_o = NULL;
+ texture = NULL; texture_o = NULL;
+ renderer = NULL;
+ // use logical size
+ logicalRender = false;
+ accelerate = false;
+
+ StartQuit = false;
+
+ audioMgr = NULL;
+ txtMgr = NULL;
+
+ inputMappings = NULL; // This can actually be used instead of InputList now. Weird.
+ inputStates = NULL;
+ inputCallbacks = NULL;
+ mouseCallback = NULL;
+
+ inputRegistered = 0;
+
+ // Logic cap.
+ logicRate = 60;
+ timeElapsed = 0;
+ syncElapsed = 0;
+
+ // Width and height
+ WIN_width = 0;
+ WIN_height = 0;
+ LOG_width = 0;
+ LOG_height = 0;
+ }
+
+ // Initializes SDL and saves stuff into the context.
+
+ ContextManager::ContextManager(int scr_width, int scr_height, bool fulls, bool accel) {
+ DefaultVariables();
+
+ if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0) {
+ #ifdef DEBUG_OVERKILL
+ printf("[ContextManager~Ctor] SDL Init error w/ VIDEO|AUDIO. Msg rep: %s\n", SDL_GetError());
+ #else
+ printf("Error initializing SDL. Info:%s\n", SDL_GetError());
+ #endif
+ }
+ else {
+ this->InitWindow(scr_width, scr_height, fulls, accel);
+ }
+
+ audioMgr = new AudioManager();
+ }
+
+ // Delays window creation; Use InitWindow before doing anything.
+
+ ContextManager::ContextManager() {
+ DefaultVariables();
+
+ if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0) {
+ #ifdef DEBUG_OVERKILL
+ printf("[ContextManager~Ctor] SDL Init error w/ VIDEO|AUDIO. Msg rep: %s\n", SDL_GetError());
+ #else
+ printf("Error initializing SDL. Info:%s\n", SDL_GetError());
+ #endif
+ }
+
+ audioMgr = new AudioManager();
+ }
+
+ // Creates a window.
+
+ void ContextManager::InitWindow(int width, int height, bool fulls, bool accel) {
+ this->WIN_width = width;
+ this->WIN_height = height;
+ this->LOG_width = width;
+ this->LOG_height = height;
+
+ #ifdef DEBUG_OVERKILL
+ printf("[ContextManager::InitWindow] Params: w:%d h:%d f:%d a:%d\n", width, height, fulls, accel);
+ #endif
+
+ if(accel) {
+ _InitWindowAC(width, height, fulls);
+ this->texture_o = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height);
+ SDL_SetTextureBlendMode(this->texture_o, SDL_BLENDMODE_BLEND);
+ }
+ else {
+ _InitWindowSW(width, height, fulls);
+ this->surface_o = SDL_CreateRGBSurface(0, width, height, 32, 0, 0, 0, 0);
+ }
+
+ txtMgr = new TextManager(this);
+ }
+
+ void ContextManager::_InitWindowSW(int width, int height, bool fulls) {
+ // Add title setting function.
+ this->window = SDL_CreateWindow("Zero", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_SHOWN);
+ if(this->window == NULL) {
+ fprintf(stderr, "[E] Error creating window. Info:\n");
+ fprintf(stderr, "[E] %s\n", SDL_GetError());
+ fprintf(stderr, "[E] This is fatal. Dying.");
+ exit(-1);
+ }
+ else {
+ SDL_SetHintWithPriority(SDL_HINT_RENDER_VSYNC, "1", SDL_HINT_OVERRIDE);
+ if(!SDL_CreateRenderer( this->window, -1, SDL_RENDERER_ACCELERATED )) {
+ fprintf(stderr, "[E] Error creating renderer. Info:\n");
+ fprintf(stderr, "[E] %s\n", SDL_GetError());
+ fprintf(stderr, "[E] This is fatal. Dying.");
+ exit(-1);
+ }
+ }
+ }
+
+ void ContextManager::_InitWindowAC(int width, int height, bool fulls) {
+ this->accelerate = true;
+
+ this->window = SDL_CreateWindow("Zero", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_SHOWN);
+ if(this->window == NULL) {
+ fprintf(stderr, "[E] Error creating window. Info:\n");
+ fprintf(stderr, "[E] %s\n", SDL_GetError());
+ fprintf(stderr, "[E] This is fatal. Dying.");
+ exit(-1);
+ }
+ else {
+ this->renderer = SDL_CreateRenderer( this->window, -1, SDL_RENDERER_ACCELERATED );
+ if(this->renderer == NULL) {
+ fprintf(stderr, "[E] Error creating renderer. Info:\n");
+ fprintf(stderr, "[E] %s\n", SDL_GetError());
+ fprintf(stderr, "[E] This is fatal. Dying.");
+ exit(-1);
+ }
+ else {
+ this->logicalRender = true;
+
+ this->texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height);
+ }
+ }
+ }
+
+ // Init window with a logical size and a real one. Determines which backend to use.
+ void ContextManager::InitWindowLogical(int width_win, int height_win, int width_log, int height_log, bool fulls, bool accel) {
+ this->LOG_width = width_log;
+ this->LOG_height = height_log;
+ this->WIN_width = width_win;
+ this->WIN_height = height_win;
+
+ #ifdef DEBUG_OVERKILL
+ printf("[ContextManager::InitWindowLogical] phyw:%d phyh:%d logw:%d logh:%d f:%d a:%d\n", width_win, height_win, width_log, height_log, fulls, accel);
+ #endif
+
+ if (accel) {
+ _InitWindowLogicalAC(width_win, height_win, width_log, height_log, fulls);
+ this->texture_o = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width_win, height_win);
+ SDL_SetTextureBlendMode(this->texture_o, SDL_BLENDMODE_BLEND);
+ }
+ else {
+ _InitWindowLogicalSW(width_win, height_win, width_log, height_log, fulls);
+ this->surface_o = SDL_CreateRGBSurface(0, width_win, height_win, 32, 0, 0, 0, 0);
+ }
+
+ txtMgr = new TextManager(this);
+ }
+
+ // Init window with a logical size and a real one.
+ void ContextManager::_InitWindowLogicalSW(int width_win, int height_win, int width_log, int height_log, bool fulls) {
+ this->window = SDL_CreateWindow("Zero", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width_win, height_win, SDL_WINDOW_SHOWN);
+ if(this->window == NULL) {
+ fprintf(stderr, "[E] Error creating window. Info:\n");
+ fprintf(stderr, "[E] %s\n", SDL_GetError());
+ fprintf(stderr, "[E] This is fatal. Dying.");
+ exit(-1);
+ }
+ else {
+ this->renderer = SDL_CreateRenderer( this->window, -1, SDL_RENDERER_ACCELERATED );
+ if(this->renderer == NULL) {
+ fprintf(stderr, "[E] Error creating renderer. Info:\n");
+ fprintf(stderr, "[E] %s\n", SDL_GetError());
+ fprintf(stderr, "[E] This is fatal. Dying.");
+ exit(-1);
+ }
+ else {
+ this->logicalRender = true;
+
+ this->surface = SDL_CreateRGBSurface(0, width_log, height_log, 32, 0, 0, 0, 0);
+ }
+ }
+ }
+
+ // Init window with a logical size and a real one.
+ void ContextManager::_InitWindowLogicalAC(int width_win, int height_win, int width_log, int height_log, bool fulls) {
+ this->accelerate = true;
+
+ this->window = SDL_CreateWindow("Zero", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width_win, height_win, SDL_WINDOW_SHOWN);
+ if(this->window == NULL) {
+ fprintf(stderr, "[E] Error creating window. Info:\n");
+ fprintf(stderr, "[E] %s\n", SDL_GetError());
+ fprintf(stderr, "[E] This is fatal. Dying.");
+ exit(-1);
+ }
+ else {
+ this->renderer = SDL_CreateRenderer( this->window, -1, SDL_RENDERER_ACCELERATED );
+ if(this->renderer == NULL) {
+ fprintf(stderr, "[E] Error creating renderer. Info:\n");
+ fprintf(stderr, "[E] %s\n", SDL_GetError());
+ fprintf(stderr, "[E] This is fatal. Dying.");
+ exit(-1);
+ }
+ else {
+ this->logicalRender = true;
+
+ this->texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width_log, height_log);
+ }
+ }
+ }
+
+ // Clears the display to black.
+
+ void ContextManager::Clear() {
+ if(this->StartQuit) return;
+
+ if (accelerate) {
+ if (logicalRender) {
+ SDL_SetRenderTarget(renderer, texture);
+ SDL_RenderClear(renderer);
+ SDL_SetRenderTarget(renderer, NULL);
+ }
+
+ SDL_SetRenderTarget(renderer, texture_o);
+ SDL_RenderClear(renderer);
+ SDL_SetRenderTarget(renderer, NULL);
+
+ SDL_RenderClear(renderer);
+ }
+ else {
+ if (logicalRender)
+ SDL_FillRect(this->surface, NULL, SDL_MapRGB(this->surface->format, 0x0, 0x0, 0x0));
+ SDL_FillRect(this->surface_o, NULL, SDL_MapRGB(this->surface_o->format, 0x0, 0x0, 0x0));
+
+ SDL_FillRect(SDL_GetWindowSurface(this->window), NULL, SDL_MapRGB(SDL_GetWindowSurface(this->window)->format, 0x0, 0x0, 0x0));
+ }
+ }
+
+ // Clears the display to black.
+
+ void ContextManager::ClearOverlay() {
+ if(this->StartQuit) return;
+
+ if (accelerate) {
+ SDL_SetRenderTarget(renderer, texture_o);
+ SDL_RenderClear(renderer);
+ SDL_SetRenderTarget(renderer, NULL);
+ }
+ else {
+ SDL_FillRect(this->surface_o, NULL, SDL_MapRGB(this->surface_o->format, 0x0, 0x0, 0x0));
+ }
+ }
+
+ // Flush any changes in the surface to screen
+
+ void ContextManager::Flush() {
+ if(this->StartQuit) return;
+ if (accelerate) {
+ if(logicalRender) {
+ SDL_Rect dst, src;
+
+ src.x = 0;
+ src.y = 0;
+ src.w = LOG_width;
+ src.h = LOG_height;
+
+ dst.x = 0;
+ dst.y = 0;
+ dst.w = WIN_width;
+ dst.h = WIN_height;
+
+ SDL_RenderCopy(renderer, texture, &src, &dst);
+ }
+
+ SDL_RenderCopy(renderer, texture_o, NULL, NULL);
+
+ SDL_RenderPresent(renderer);
+ }
+ else {
+ if(logicalRender)
+ SDL_BlitScaled(this->surface, NULL, SDL_GetWindowSurface(this->window), NULL);
+
+ SDL_BlitScaled(this->surface_o, NULL, SDL_GetWindowSurface(this->window), NULL);
+
+ SDL_UpdateWindowSurface(this->window);
+ }
+ }
+
+ // Return the internal surface for external blits.
+ SDL_Surface* ContextManager::Surface() {
+ if(this->StartQuit) return NULL;
+ if(accelerate) return NULL;
+
+ if( logicalRender )
+ return this->surface;
+
+ return SDL_GetWindowSurface(this->window);
+ }
+
+ // return the renderer.
+ SDL_Renderer* ContextManager::Renderer() {
+ return renderer;
+ }
+
+ // return the renderer.
+ bool ContextManager::Accelerated() {
+ return accelerate;
+ }
+
+ // Blit data via cast. inp should be a SDL_Surface or SDL_Texture.
+ void ContextManager::Blit(void* inp, SDL_Rect* src, SDL_Rect* dst) {
+ if(accelerate) {
+ if (logicalRender) SDL_SetRenderTarget(renderer, texture);
+
+ SDL_RenderCopy(renderer, (SDL_Texture*)inp, src, dst);
+
+ if (logicalRender) SDL_SetRenderTarget(renderer, NULL);
+ }
+ else {
+ SDL_BlitSurface((SDL_Surface*)inp, src, surface, dst);
+ }
+ }
+
+ // Blit data to overlay via cast. inp should be a SDL_Surface or SDL_Texture.
+ void ContextManager::OverlayBlit(void* inp, SDL_Rect* src, SDL_Rect* dst) {
+ // Recalculate src and dst based on upscale.
+ double OUTW_Ratio, OUTH_Ratio;
+ OUTW_Ratio = (double)WIN_width / (double)LOG_width;
+ OUTH_Ratio = (double)WIN_height / (double)LOG_height;
+
+ dst->x = (int)(((double)dst->x) * OUTW_Ratio);
+ dst->y = (int)(((double)dst->y) * OUTH_Ratio);
+ dst->w = (int)(((double)dst->w) * OUTW_Ratio);
+ dst->h = (int)(((double)dst->h) * OUTH_Ratio);
+
+ if(accelerate) {
+ if (logicalRender) SDL_SetRenderTarget(renderer, texture_o);
+
+ SDL_RenderCopy(renderer, (SDL_Texture*)inp, src, dst);
+
+ if (logicalRender) SDL_SetRenderTarget(renderer, NULL);
+ }
+ else {
+ SDL_BlitSurface((SDL_Surface*)inp, src, surface_o, dst);
+ }
+ }
+
+ // Gets width of display
+ int ContextManager::GetWidth() {
+ return this->LOG_width;
+ }
+
+ // Gets height of display
+ int ContextManager::GetHeight() {
+ return this->LOG_height;
+ }
+
+ // Checks input events for matches and run callbacks.
+ bool ContextManager::Input() {
+ if(this->StartQuit) return this->StartQuit;
+
+ SDL_Event evt;
+ for(int i = 0; i < this->inputmode && SDL_PollEvent(&evt); i++) {
+ for(int j = 0; j < inputRegistered; j++) {
+ if(inputMappings[j] == evt.key.keysym.sym) {
+ bool down = false;
+ if(evt.type == SDL_KEYDOWN)
+ down = true;
+ inputStates[j] = down;
+ if((evt.type == SDL_KEYDOWN || evt.type == SDL_KEYUP) && inputCallbacks[j] != NULL) {
+ (inputCallbacks[j])(down);
+ }
+ }
+ }
+ if((evt.type == SDL_MOUSEBUTTONDOWN || evt.type == SDL_MOUSEBUTTONUP) && mouseCallback != NULL) {
+ if(evt.button.button == SDL_BUTTON_LEFT) {
+ (mouseCallback)(evt.button.x, evt.button.y, (evt.type == SDL_MOUSEBUTTONDOWN), true, false, false);
+ }
+ if(evt.button.button == SDL_BUTTON_MIDDLE) {
+ (mouseCallback)(evt.button.x, evt.button.y, (evt.type == SDL_MOUSEBUTTONDOWN), false, true, false);
+ }
+ if(evt.button.button == SDL_BUTTON_RIGHT) {
+ (mouseCallback)(evt.button.x, evt.button.y, (evt.type == SDL_MOUSEBUTTONDOWN), false, false, true);
+ }
+ }
+ }
+
+ return this->StartQuit;
+ }
+
+ // Changes the Input Mode used.
+ void ContextManager::InputMode(InMode in) {
+ inputmode = in;
+ }
+
+ // Register an abstract handler. Returns an int corresponding to the index for the mapping.
+ int ContextManager::RegisterInput(SDL_Keycode key, GameCallback func) {
+
+ // Apply input mappings.
+
+ ++inputRegistered;
+
+ // allocate space for current keys+1.
+ inputMappings = (SDL_Keycode*)realloc(inputMappings, sizeof(SDL_Keycode) * inputRegistered);
+ inputCallbacks = (GameCallback*)realloc(inputCallbacks, sizeof(GameCallback) * inputRegistered);
+ inputStates = (bool*)realloc(inputStates, sizeof(bool) * inputRegistered);
+
+ // Actually apply the new callback
+ inputMappings[inputRegistered-1] = key;
+ inputCallbacks[inputRegistered-1] = func;
+ inputStates[inputRegistered-1] = false;
+
+ // Return the index.
+ return inputRegistered-1;
+ }
+
+ void ContextManager::RegisterMouse(MouseCallback func) {
+ mouseCallback = func;
+ }
+
+ // Get input via abstract ID.
+ bool ContextManager::GetInput(int index) {
+ return inputStates[index];
+ }
+
+ // Remap abstract key.
+ void ContextManager::RemapKey(int index, SDL_Keycode to) {
+ // Check if something is already mapped to 'to'.
+ int reg = -1;
+ for(int i = 0; i < inputRegistered; i++) {
+ if(inputMappings[i] == to) {
+ reg = i;
+ }
+ }
+ // Remap, swap if necessary.
+ if(reg > -1)
+ inputMappings[reg] = inputMappings[index];
+ inputMappings[index] = to;
+ }
+
+ // Set Quit flag.
+ void ContextManager::SetQuit() {
+ this->StartQuit = true;
+ }
+
+ bool ContextManager::GetQuit() {
+ return this->StartQuit;
+ }
+
+ // Destroy context.
+
+ ContextManager::~ContextManager() {
+ delete audioMgr;
+ SDL_DestroyWindow(window);
+ SDL_Quit();
+ }
+
+ // Gets the audio manager.
+ AudioManager* ContextManager::Audio() {
+ return audioMgr;
+ }
+
+ // Gets the audio manager.
+ TextManager* ContextManager::Text() {
+ return txtMgr;
+ }
+
+ void ContextManager::StartSync() {
+ timeElapsed = SDL_GetTicks();
+ }
+
+ void ContextManager::EndSync() {
+ while (1) {
+ double currentTime = SDL_GetTicks();
+ if(currentTime - timeElapsed > 1000 / logicRate)
+ return;
+ SDL_Delay((1000 / logicRate) / 8);
+ }
+ }
+
+ void ContextManager::SetTitle(char* title) {
+ SDL_SetWindowTitle(window, title);
+ }
--- /dev/null
+#ifndef CONTEXTMANAGER_HPP
+#define CONTEXTMANAGER_HPP
+
+typedef void (*GameCallback)(bool);
+typedef void (*MouseCallback)(int, int, bool, bool, bool, bool); // X, Y, up/down, isLeft, isMiddle, isRight
+
+class TextManager; // Forward decl
+
+ // Input Mode enum. This is the max events allowed in one go.
+ typedef enum InMode_e {
+ Slow = 20,
+ Medium = 10,
+ Burst = 5
+ } InMode;
+
+ class ContextManager {
+ public:
+ ContextManager();
+ ContextManager(int scr_width, int scr_height, bool fulls, bool accel);
+
+ // Initialization.
+ void InitWindow(int width, int height, bool fulls, bool accel);
+ void InitWindowLogical(int width, int height, int width_log, int height_log, bool fulls, bool accel);
+
+ // Set window title
+ void SetTitle(char* title);
+
+ // Display related.
+ void Clear();
+ void Flush();
+
+ void ClearOverlay();
+
+ SDL_Surface* Surface();
+ SDL_Renderer* Renderer();
+ bool Accelerated();
+ void Blit(void* inp, SDL_Rect* src, SDL_Rect* dst);
+ void OverlayBlit(void* inp, SDL_Rect* src, SDL_Rect* dst);
+
+ // Support funcs.
+ int GetWidth();
+ int GetHeight();
+
+ // Get Input State and Modify input state.
+ bool Input();
+
+ // Abstract remappable key functions.
+ int RegisterInput(SDL_Keycode key, GameCallback func);
+ void RegisterMouse(MouseCallback func);
+ bool GetInput(int index);
+ void RemapKey(int index, SDL_Keycode to);
+ void InputMode(InMode mode);
+
+ // Gets the AudioManager & TextManager
+ AudioManager* Audio();
+ TextManager* Text();
+
+ // Exit methods.
+ void SetQuit();
+ bool GetQuit();
+
+ // Logic sync limiter.
+ void StartSync();
+ void EndSync();
+
+ ~ContextManager();
+ private:
+ // Lower init.
+ // DELETEME - Software rendering doesn't work now.
+ void _InitWindowSW(int width, int height, bool fulls);
+ void _InitWindowAC(int width, int height, bool fulls);
+ // DELETEME - Software rendering doesn't work now.
+ void _InitWindowLogicalSW(int width_win, int height_win, int width_log, int height_log, bool fulls);
+ void _InitWindowLogicalAC(int width_win, int height_win, int width_log, int height_log, bool fulls);
+
+ void DefaultVariables();
+
+ InMode inputmode;
+ SDL_Window* window;
+ SDL_Surface* surface, *surface_o;
+ SDL_Texture* texture, *texture_o;
+ SDL_Renderer* renderer;
+ // use logical size
+ bool logicalRender;
+ bool accelerate;
+
+ bool StartQuit;
+
+ AudioManager* audioMgr;
+ TextManager* txtMgr;
+
+ SDL_Keycode* inputMappings; // This can actually be used instead of InputList now. Weird.
+ bool* inputStates;
+ GameCallback* inputCallbacks;
+ MouseCallback mouseCallback;
+
+ int inputRegistered;
+
+ // Logic cap.
+ int logicRate;
+ int timeElapsed;
+ int syncElapsed;
+
+ // Width and height
+ int WIN_width;
+ int WIN_height;
+ int LOG_width;
+ int LOG_height;
+ };
+
+#endif
--- /dev/null
+#include "Zero.hpp"
+
+#include "Funcs.hpp"
+
+DataContainer* data = NULL;
+
+const char* loadup = "script/main.scr";
+
+DataContainer::DataContainer() {
+ if_fail = 0;
+ wait_input = false;
+ screen_w = 800;
+ screen_h = 600;
+ physical_w = 800;
+ physical_h = 600;
+ render_x1 = screen_w / 15;
+ render_y1 = screen_h / 15;
+ render_x2 = screen_w / 15 * 14;
+ render_y2 = screen_h / 15 * 13;
+ text_x = render_x1;
+ text_y = render_y1;
+ jumped = false;
+ choice_coords = NULL;
+ choices = 0;
+ accessScriptHandle = NULL;
+ vndc_enabled = true;
+ quote_incomplete = false;
+ debug_mode = false;
+ debug_to_shell = false;
+ verbose = false;
+ currentLine = 0;
+ skip_key_on = false;
+ eof = false;
+ next_line = NULL; // Used for voice-detect.
+ // It's impossible to parse without lookahead.
+}
+
+void CreateDataContainer() {
+ data = new DataContainer();
+
+
+
+ GetData()->main_scr = (char**)calloc(sizeof(char*), 1);
+ GetData()->main_scr[0] = (char*)calloc(sizeof(char), 400);
+ strncpy(GetData()->main_scr[0], loadup, 400);
+}
+
+DataContainer* GetData() {
+ return &data[0];
+}
+
+void DumpSave(char* fname) {
+ // Dump variables.
+ // Dump script file.
+
+ // A save actually ends up as a mini-script.
+ // So, to load a save you load this as the
+ // main script
+ // For example:
+ // setvar data1 = 6
+ // setvar data2 = 9
+ // music mus
+ // bgload bg
+ // jump script.scr 60
+ // The call command runs a scr, and returns here.
+
+ FILE* save_to = fopen(fname, "w");
+
+ std::map<std::string, int> data_vals = GetData()->s_flags[0];
+
+ if(!data_vals.empty()) {
+ std::map<std::string, int>::iterator item = data_vals.begin();
+ while(item != data_vals.end()) {
+ if(strcmp(item->first.c_str(), "selected"))
+ fprintf(save_to, "setvar %s = %d\n", item->first.c_str(), item->second);
+
+ ++item;
+ }
+ }
+
+ fprintf(save_to, "music %s\n", &(GetData()->current_music[6]));
+ fprintf(save_to, "bgload %s\n", &(GetData()->current_bg[11]));
+ fprintf(save_to, "jump %s %d\n", &(GetData()->current_scr[7]), GetData()->currentLine - 1); // The text never completely displayed
+ // So restore back one to replay
+
+ fclose(save_to);
+}
--- /dev/null
+#ifndef DATAGUARD_HPP
+#define DATAGUARD_HPP
+
+#include <map>
+#include <string>
+
+class DataContainer {
+ public:
+ DataContainer();
+
+ ContextManager* ctx;
+ int if_fail;
+ bool wait_input;
+ char current_scr[400], current_music[400], current_bg[400];
+ int screen_w;
+ int screen_h;
+ int physical_w;
+ int physical_h;
+ int render_x1;
+ int render_y1;
+ int render_x2;
+ int render_y2;
+ int text_x;
+ int text_y;
+ std::map<std::string, int> *s_flags;
+ bool jumped;
+ int* choice_coords;
+ int choices;
+ FILE* accessScriptHandle;
+ char** main_scr; // Default value.
+ bool vndc_enabled;
+ bool quote_incomplete;
+ bool debug_mode;
+ bool debug_to_shell;
+ bool verbose;
+ int currentLine;
+ bool skip_key_on;
+ bool eof;
+ char* window_name;
+ char* next_line; // Used for voice-detect.
+ // It's impossible to parse without lookahead.
+};
+
+DataContainer* GetData();
+void CreateDataContainer();
+void DumpSave(char* fname);
+
+#endif
--- /dev/null
+#ifndef FUNCS_HPP
+#define FUNCS_HPP
+
+#include <cstdio>
+#include <cstdlib>
+#include <ctime>
+#include <cstring>
+
+#include "gitrev.hpp"
+
+#include "Data.hpp"
+
+void Parse(); // This reads commands from files.
+void ParseShell(); // This reads commands from the shell.
+void ParseCmd(char* line); // This does the heavy lifting.
+void Loop();
+void Wait();
+void Setup();
+
+void InputAdvance(int x, int y, bool down, bool left, bool middle, bool right);
+void QuitKey(bool down);
+void NopKey(bool down);
+
+void op_bgload(char* file, int* fadetime);
+void op_cleartext();
+void op_delay(int* frames);
+void op_fi();
+void op_gsetvar(char* var, int *modifier, char *value);
+void op_if(char* left, int* op, char* right);
+void op_music(char* file);
+void op_random(char* var, int* low, int* high);
+void op_setimg(char* file, int* x, int* y);
+void op_setvar(char* var, int *modifier, char *value);
+void op_sound(char* file, int* times);
+void op_text(char* string);
+void op_jump(char* file, int* lineTo, bool isSave);
+void op_goto(char* label);
+void op_choice(char* choices);
+
+#endif
--- /dev/null
+#include "Zero.hpp"
+
+#include "Funcs.hpp"
+
+void Wait() {
+ // If wait wasn't specified, don't halt.
+ // Don't even bother with extensions off.
+ // If we're currently in a quote, leave it alone.
+ // If the line is spoken, then halt previous spoken lines.
+ // If the skip key is held, just gogogo
+
+ // bool stop_voice = GetData()->wait_input && GetData()->vndc_enabled && GetData()->is_spoken_line;
+
+ while((GetData()->wait_input && !GetData()->ctx->GetQuit())) {
+ GetData()->ctx->Input();
+
+ GetData()->ctx->Flush();
+
+ if(GetData()->debug_to_shell)
+ ParseShell();
+
+ if(GetData()->ctx->GetInput(1)) break;
+ }
+}
+
+void Loop() {
+ if(GetData()->ctx->GetQuit()) return;
+ Parse();
+
+ // We don't clear. This system uses dirty blits. ;P
+ GetData()->ctx->Flush();
+
+ GetData()->ctx->StartSync();
+
+ Wait();
+
+ GetData()->ctx->EndSync();
+}
+
+void Setup() {
+ // Init window
+ GetData()->ctx->InitWindowLogical(GetData()->physical_w, GetData()->physical_h, GetData()->screen_w, GetData()->screen_h, false, true);
+
+ GetData()->window_name = (char*)calloc(sizeof(char), 400);
+ sprintf(GetData()->window_name, "%s", "VNDC Interpreter ");
+ GetData()->ctx->SetTitle(GetData()->window_name);
+
+ GetData()->ctx->InputMode(Burst);
+
+ // Input
+ GetData()->ctx->RegisterMouse(&InputAdvance);
+ GetData()->ctx->RegisterInput(SDLK_ESCAPE, &QuitKey);
+ GetData()->ctx->RegisterInput(SDLK_LCTRL, &NopKey);
+
+ GetData()->s_flags = new std::map<std::string, int>();
+
+ // Font
+ GetData()->ctx->Text()->LoadFont((char*)"default.ttf", 24);
+ GetData()->ctx->Text()->SetFontUsed(1);
+
+ GetData()->ctx->Text()->Outline(1);
+ GetData()->ctx->Text()->SetColor(255,255,255,255);
+
+ op_cleartext();
+}
--- /dev/null
+#include "Zero.hpp"
+
+#include "Data.hpp"
+
+#include "Funcs.hpp"
+
+void ParseCmd(char* line) {
+
+ char *passthru_line = (char*)calloc(sizeof(char), 400);
+
+ char** tokens = NULL;
+
+ strncpy(passthru_line, line, sizeof(char)*400);
+
+ if(GetData()->verbose) printf("[scr] %s\n", line);
+
+ int num = 1;
+ tokens = (char**)realloc(NULL, sizeof(char*) * (1));
+ tokens[num-1] = strtok(line, " ");
+
+ do {
+ #ifdef DEBUG_OVERKILL
+ printf("Loop: num = %d;\n", num);
+ #endif
+ ++num;
+ tokens = (char**)realloc(tokens, sizeof(char*) * (num));
+ tokens[num-1] = strtok(NULL, " ");
+ } while(tokens[num-1] != NULL);
+
+ --num;
+
+ //printf("Made it out of the loop.\n");
+ //for (int i = 0; i < num; i++) {
+ //printf("[param] %d = '%s'\n", i, tokens[i]);
+ //}
+
+ int value_1, value_2;
+
+ if(!strcmp(tokens[0], "bgload")) {
+ //printf("[OP::bgload] exec (params:%d)", num-1);
+ if (num > 2) {
+ sscanf(tokens[2], "%d", &value_1);
+ op_bgload(tokens[1], &value_1);
+ }
+ else
+ op_bgload(tokens[1], NULL);
+ }
+ else if(!strcmp(tokens[0], "setimg")) {
+ sscanf(tokens[2], "%d", &value_1);
+ sscanf(tokens[3], "%d", &value_2);
+ op_setimg(tokens[1], &value_1, &value_2);
+ }
+ else if(!strcmp(tokens[0], "sound")) {
+ // Another ridiculous thing. Second parameter if not
+ // specified is implicity one
+ if(num > 2) {
+ sscanf(tokens[2], "%d", &value_1);
+ op_sound(tokens[1], &value_1);
+ }
+ else
+ op_sound(tokens[1], NULL);
+ }
+ else if(!strcmp(tokens[0], "music"))
+ op_music(tokens[1]);
+ else if(!strcmp(tokens[0], "text")) {
+ // Because of *reasons* (lack of quotes) we use the copy of line,
+ // passthru_line and adjust the pointer to use that.
+ // strtok destroys the structure
+ // And there's the possibility of a zero-length string as well.
+ //printf("[op_text] Reconstructed string = '%s'\n", &passthru_line[5]);
+ op_text(&passthru_line[5]);
+ }
+ else if(!strcmp(tokens[0], "choice")) {
+ op_choice(&passthru_line[7]);
+ }
+ else if(!strcmp(tokens[0], "setvar")) {
+ if(num > 3) {
+ if(!strcmp(tokens[2], "="))
+ value_1 = 0;
+ else if(!strcmp(tokens[2], "+"))
+ value_1 = 1;
+ else if(!strcmp(tokens[2], "-"))
+ value_1 = -1;
+ else if(!strcmp(tokens[2], "~")) // Apparently resets. UGH NOT DOC'D
+ value_1 = -2;
+
+
+ sscanf(tokens[3], "%d", &value_2);
+ op_setvar(tokens[1], &value_1, tokens[3]);
+ }
+ else {
+ value_1 = -2;
+ op_setvar(tokens[1], &value_1, NULL);
+ }
+ }
+ else if(!strcmp(tokens[0], "gsetvar")) {
+ if(!strcmp(tokens[2], "="))
+ value_1 = 0;
+ else if(!strcmp(tokens[2], "+"))
+ value_1 = 1;
+ else if(!strcmp(tokens[2], "-"))
+ value_1 = -1;
+
+ op_gsetvar(tokens[1], &value_1, tokens[3]);
+ }
+ else if(!strcmp(tokens[0], "if")) {
+ if(!strcmp(tokens[2], "<="))
+ value_1 = 0;
+ else if(!strcmp(tokens[2], "<"))
+ value_1 = 1;
+ else if(!strcmp(tokens[2], "=="))
+ value_1 = 2;
+ else if(!strcmp(tokens[2], "!="))
+ value_1 = 3;
+ else if(!strcmp(tokens[2], ">"))
+ value_1 = 4;
+ else if(!strcmp(tokens[2], ">="))
+ value_1 = 5;
+
+ op_if(tokens[1], &value_1, tokens[3]);
+ }
+ else if(!strcmp(tokens[0], "fi"))
+ op_fi();
+ else if(!strcmp(tokens[0], "jump")) {
+ if(num > 2) {
+ sscanf(tokens[2], "%d", &value_1);
+ op_jump(tokens[1], &value_1, false);
+ }
+ else
+ op_jump(tokens[1], NULL, false);
+ }
+ else if(!strcmp(tokens[0], "delay")) {
+ sscanf(tokens[1], "%d", &value_1);
+ op_delay(&value_1);
+ }
+ else if(!strcmp(tokens[0], "random")) {
+ sscanf(tokens[2], "%d", &value_1);
+ sscanf(tokens[3], "%d", &value_2);
+ op_random(tokens[1], &value_1, &value_2);
+ }
+ else if(!strcmp(tokens[0], "goto"))
+ op_goto(tokens[1]);
+ else if(!strcmp(tokens[0], "cleartext"))
+ op_cleartext();
+
+ free(tokens);
+ free(passthru_line);
+}
+
+void ParseShell() {
+ bool DebugContinue = true;
+ char buffer[400];
+ while(DebugContinue) {
+ memset(buffer, 0, sizeof(char)*400);
+
+ printf("[scr command] $ ");
+ fgets(buffer, 400, stdin);
+
+ // Remove all '\n' from this string
+ for(int i=0; i < 400; i++) {
+ if (buffer[i] == '\n')
+ buffer[i] = '\0';
+ }
+
+ if(!strcmp(buffer, "help") || strlen(buffer) < 1) {
+ printf("%s\n", "Commands available:");
+ printf("\t%s\t\t\t%s\n", "(debug) resume", "Stops debug mode");
+ printf("\t%s\t\t\t%s\n", "(debug) quit", "Quits game");
+ printf("\t%s\t\t%s\n", "(debug) save [file]", "Saves immediately to file");
+ printf("\t%s\t%s\n", "setvar [var] [mod] [val]", "Set save flag");
+ printf("\t%s\t%s\n", "gsetvar [var] [mod] [val]", "Set system flag");
+ printf("\t%s\t\t\t%s\n", "text [text] ...", "Display text");
+ printf("\t%s\t\t%s\n", "sound [file] (num)", "Play sound num times");
+ printf("\t%s\t\t\t%s\n", "music [file]", "Play music");
+ printf("\t%s\t\t%s\n", "setimg [file] [x] [y]", "Display image at x,y");
+ printf("\t%s\t%s\n", "random [var] [low] [high]", "Store random number in var");
+ printf("\t%s\t\t%s\n", "jump [file.scr] {N}", "Switch to file.src (goto line N)");
+ printf("\t%s\t\t\t%s\n", "goto [label]", "Goto label in current file");
+ printf("\t%s\t\t%s\n", "if [var] [op] [val]", "Test condition, and execute till\n\t\t\t\t\tfi if true");
+ printf("\t%s\t\t\t\t%s\n", "fi", "Stop computing if");
+ printf("\t%s\t\t\t%s\n", "delay [frames]", "Delay frames (at 60fps)");
+ printf("\t%s\t\t\t%s\n", "cleartext", "Clear text from screen");
+ printf("\t%s\t%s\n", "choice [ch|ch|...] {<var}", "Get input for choice. Store to selected\n\t\t\t\t\t(or var if extensions are on)");
+ printf("\t%s\t%s\n", "bgload [file] [fadeframes]", "Load background");
+ }
+ else if (!strcmp(buffer, "quit")) {
+ printf("[debug] Setting quit status & stopping debug.\n");
+ GetData()->ctx->SetQuit();
+ DebugContinue = false;
+ }
+ else if (!strcmp(buffer, "resume")) {
+ printf("[debug] Exiting debug shell and resuming.\n");
+ DebugContinue = false;
+ GetData()->wait_input = true;
+ }
+ else if (!strncmp(buffer, "save", 4)) {
+ char* savefile = &buffer[5];
+ printf("[debug] Saving to file '%s' NOW.\n", savefile);
+ DumpSave(savefile);
+ }
+ else {
+ ParseCmd(buffer);
+ GetData()->ctx->Flush();
+ GetData()->wait_input = false;
+ }
+ }
+ GetData()->debug_to_shell = false;
+}
+
+void Parse() {
+ if(GetData()->ctx->GetQuit()) return;
+
+ ++(GetData()->currentLine);
+
+ if (!GetData()->accessScriptHandle) {
+ fprintf(stderr, "Could not open script data\n");
+ exit(-8);
+ }
+
+ // Load the next line to this one.
+ char* line = GetData()->next_line;
+
+ char* line_copy = line;
+
+ while(line_copy[0] == ' ' || line_copy[0] == '\t') {
+ line_copy[0] = '\0';
+ line_copy = &line_copy[1];
+ }
+
+ // Remove all '\n' from the buffer line
+ for(int i=0; i < (int)strlen(line_copy); i++) {
+ if (line_copy[i] == '\n')
+ line_copy[i] = '\0';
+ }
+
+ // The next line is null, because the file is finished.
+ if(feof(GetData()->accessScriptHandle) && strlen(GetData()->next_line) == 0) {
+ // We've reached EOF. Jump back and return.
+ op_jump(GetData()->main_scr[0], NULL, true);
+ }
+
+ GetData()->next_line = (char*)calloc(sizeof(char), 400);
+ fgets(GetData()->next_line, 400, GetData()->accessScriptHandle);
+
+ // Execute the current line.
+ if(strlen(line_copy) != 0) {
+ ParseCmd(line_copy);
+ }
+
+ free(line);
+
+ // Load the next line.
+
+ return;
+}
+
+void InputAdvance(int x, int y, bool down, bool left, bool middle, bool right) {
+ if(GetData()->choices > 0) {
+ // Choose an option.
+ for(int i=0; i<GetData()->choices; i++) {
+ if(!down && y > GetData()->choice_coords[i*2] && y < GetData()->choice_coords[i*2+1])
+ {
+ GetData()->choices = -(i+1); // Negative indicates complete. This is just
+ // for storage savings.
+ }
+ }
+ }
+ else if(left && !down) {
+ GetData()->wait_input = false;
+ }
+}
+
+void QuitKey(bool down) {
+ // Flush data to save.scr
+ DumpSave((char*)"save.scr");
+
+ GetData()->ctx->SetQuit();
+}
+
+void NopKey(bool down) {}
--- /dev/null
+#include "Zero.hpp"
+
+TextManager::TextManager(ContextManager* ct) {
+
+ fonts = NULL;
+ current_font = 0;
+ fonts_loaded = 0;
+ outline = false;
+ outline_px = 0;
+
+ this->ctx = ct;
+
+ if(TTF_Init() == -1) {
+ printf("TTF Init failed. %s\n", TTF_GetError());
+ exit(-8);
+ }
+
+ LoadFont((char*)"default.ttf", 20);
+
+ color.r = 255;
+ color.g = 255;
+ color.b = 255;
+ color.a = 255;
+
+}
+
+TextManager::~TextManager() {
+
+ while(fonts_loaded > 0) {
+ TTF_CloseFont(fonts[fonts_loaded-1]);
+ --fonts_loaded;
+ }
+
+ free(fonts);
+
+ TTF_Quit();
+}
+
+int TextManager::LoadFont(char* fname, int size) {
+
+ ++fonts_loaded;
+
+ fonts = (TTF_Font**)realloc(fonts, sizeof(TTF_Font*) * fonts_loaded);
+
+ if ( !(fonts[fonts_loaded - 1] = TTF_OpenFont(fname, size) ) ) {
+ printf("Font Open Failed. Load attempt: %s. Msg: %s\n", fname, TTF_GetError());
+ }
+
+ TTF_SetFontHinting(fonts[fonts_loaded - 1], TTF_HINTING_NONE);
+
+ return fonts_loaded - 1;
+}
+
+
+// Implement properly later with wrapped coordinates.
+void TextManager::Render(char* text) {
+ Render(text, 0, 0);
+}
+
+void TextManager::Render(char* text, int x, int y) {
+ if (text == NULL || fonts[current_font] == NULL)
+ return;
+
+ SDL_Surface *sf1 = NULL, *sf2 = NULL;
+ sf1 = TTF_RenderUTF8_Blended(fonts[current_font], text, color);
+ if(outline) {
+ SDL_Color n_color;
+ n_color.r = 255 - color.r;
+ n_color.g = 255 - color.g;
+ n_color.b = 255 - color.b;
+ n_color.a = color.a;
+ TTF_SetFontOutline(fonts[current_font], outline_px);
+ sf2 = TTF_RenderUTF8_Blended(fonts[current_font], text, n_color);
+ TTF_SetFontOutline(fonts[current_font], 0);
+ }
+
+ SDL_Texture *tmp1 = NULL, *tmp2 = NULL;
+
+ tmp1 = SDL_CreateTextureFromSurface(ctx->Renderer(), sf1);
+ if(outline)
+ tmp2 = SDL_CreateTextureFromSurface(ctx->Renderer(), sf2);
+
+ SDL_Rect src, dst, src2, dst2;
+ src.x = 0;
+ src.y = 0;
+ src.w = sf1->w;
+ src.h = sf1->h;
+
+ dst.x = x;
+ dst.y = y;
+ dst.w = src.w;
+ dst.h = src.h;
+
+ if(outline) {
+ src2.x = 0;
+ src2.y = 0;
+ src2.w = sf2->w;
+ src2.h = sf2->h;
+
+ dst2.x = x - (outline_px);
+ dst2.y = y - (outline_px);
+ dst2.w = src2.w;
+ dst2.h = src2.h;
+ SDL_FreeSurface(sf2);
+ ctx->OverlayBlit(tmp2, &src2, &dst2);
+ SDL_DestroyTexture(tmp2);
+ }
+
+ SDL_FreeSurface(sf1);
+ ctx->OverlayBlit(tmp1, &src, &dst);
+ SDL_DestroyTexture(tmp1);
+
+}
+
+int TextManager::TestLen(char* text) {
+ int w, h;
+ TTF_SizeText(fonts[current_font], text, &w, &h);
+
+ return w;
+}
+
+void TextManager::Outline(int pixels) {
+ if(pixels == 0) {
+ outline = false;
+ }
+ else {
+ outline = true;
+ outline_px = pixels;
+ }
+}
+
+void TextManager::SetColor(int r, int g, int b, int a)
+{
+ color.r = r;
+ color.g = g;
+ color.b = b;
+ color.a = a;
+}
+
+void TextManager::SetFontUsed(int index)
+{
+ current_font = index;
+}
--- /dev/null
+
+class TextManager {
+ public:
+ // Ctors & Dtors
+ TextManager(ContextManager* ct);
+ ~TextManager();
+
+ // Base font functions.
+ int LoadFont(char* fname, int size);
+ void Render(char* text);
+ void Render(char* text, int x, int y);
+
+ int TestLen(char* text);
+ void Outline(int pixels);
+
+ // Property functions.
+ // void SetStyle(int style);
+ void SetFontUsed(int font);
+ void SetColor(int r, int g, int b, int a);
+
+ // Complex functions.
+ // Like printf but with formatting codes. Also not varargs.
+ // Should support this subset of standards:
+ // %d %u %x %c %s %f %%
+ // It also should have the following:
+ // %t - Font Index. Switches to font index.
+ // %p - Style. Sets style to S.
+ // %m - Expects an SDL_Color. Sets the color.
+ // void fnoutf(char* text, void** data);
+
+ // Uses control codes, unline fnoutf. Mainly intended for scripts.
+ // These ops should be implemented:
+ // ^b (bold) ^i (italic) ^r (normal / reset) ^fI (font -> i)
+ // ^cNNN (color -> #NNN) ^n (next line) ^c (clear)
+ // void scoutf(char* text);
+
+ private:
+ TTF_Font** fonts;
+ int current_font;
+ int fonts_loaded;
+ SDL_Color color;
+ ContextManager* ctx;
+ bool outline;
+ int outline_px;
+};
--- /dev/null
+#include "Zero.hpp"
+
+ void UDisplayable::DefaultVars() {
+ bitmap = NULL; // Will contain either a SDL_Surface or SDL_Texture
+
+ bmp_w = 0; bmp_h = 0;
+
+ // Used in docked mode
+ frame = NULL;
+ // Used in hitbox mode
+ hitbox = NULL;
+
+ // The current mode.
+ dispMode = Normal;
+
+ // Used by animated mode.
+ frameIndex = -1;
+
+ Error = false;
+ }
+
+ // Creates a new Displayable.
+ // The mode is already Normal if we do nothing, so this constructor doesn't have to change.
+ UDisplayable::UDisplayable(ContextManager* cx, char* fname) {
+
+ DefaultVars();
+
+ SDL_Surface* bitmap_tmp = IMG_Load(fname);
+
+ if(!bitmap_tmp) {
+ printf("[UDisplayable::Ctor] File could not be loaded, this->Error set.\n");
+ Error = true;
+ }
+ else {
+ this->x = 0;
+ this->y = 0;
+ this->loc.x = 0;
+ this->loc.y = 0;
+ this->ctx = cx;
+ this->frameWidth = bitmap_tmp->w;
+ this->bmp_w = bitmap_tmp->w;
+ this->bmp_h = bitmap_tmp->h;
+
+ // We still allocate the two arrays, regardless.
+
+ // These values are unused, but we'll default them so it will operate normally.
+ hitbox = (int*)calloc(sizeof(int), 4);
+
+ // By default, it will fill this with 0, 0, W, H.
+ // This will behave identically to a displayable.
+ hitbox[0] = 0;
+ hitbox[1] = 0;
+ hitbox[2] = bitmap_tmp->w;
+ hitbox[3] = bitmap_tmp->h;
+
+ this->loc.w = bitmap_tmp->w;
+ this->loc.h = bitmap_tmp->w;
+
+ frame = (int*)calloc(sizeof(int), 4);
+
+ frame[0] = 0;
+ frame[1] = 0;
+ frame[2] = cx->GetWidth();
+ frame[3] = cx->GetHeight();
+
+ // Determine if we're on an accelerated context. If so, we create a texture out of the bitmap.
+ // Then we store what we'll use to the void* bitmap, either Tex or Surf.
+
+ if (cx->Accelerated()) {
+ SDL_Texture* tex = SDL_CreateTextureFromSurface(ctx->Renderer(), bitmap_tmp);
+ this->bitmap = (void*)tex;
+ SDL_FreeSurface(bitmap_tmp);
+ }
+ else {
+ this->bitmap = (void*)bitmap_tmp;
+ }
+ }
+ #ifdef DEBUG_OVERKILL
+ printf("[UDisplayable~Ctor] accel:%d\n", cx->Accelerated());
+ #endif
+ }
+
+ // Sets the Displayable's mode.
+ UDisplayable::UDisplayable(ContextManager* cx, UDisplayableMode mode, char* fname) {
+ UDisplayable(cx, fname);
+ this->dispMode = mode;
+ }
+
+ // Load from memory.
+ UDisplayable::UDisplayable(ContextManager* cx, UDisplayableMode mode, void* memory, int mSize) {
+
+ DefaultVars();
+
+ SDL_RWops* rwo = SDL_RWFromMem(memory, mSize);
+ SDL_Surface* bitmap_tmp = IMG_LoadTyped_RW(rwo, 0, "PNG");
+ if(rwo == NULL || bitmap_tmp == NULL) {
+ printf("Loading RWops failed. %s", SDL_GetError());
+ while(1);
+ //exit(-1);
+ }
+
+ this->x = 0;
+ this->y = 0;
+ this->loc.x = 0;
+ this->loc.y = 0;
+ this->ctx = cx;
+ this->frameWidth = bitmap_tmp->w;
+ this->bmp_w = bitmap_tmp->w;
+ this->bmp_h = bitmap_tmp->h;
+
+ // We still allocate the two arrays, regardless.
+
+ // These values are unused, but we'll default them so it will operate normally.
+ hitbox = (int*)calloc(sizeof(int), 4);
+
+ // By default, it will fill this with 0, 0, W, H.
+ // This will behave identically to a displayable.
+ hitbox[0] = 0;
+ hitbox[1] = 0;
+ hitbox[2] = bitmap_tmp->w;
+ hitbox[3] = bitmap_tmp->h;
+
+ this->loc.w = bitmap_tmp->w;
+ this->loc.h = bitmap_tmp->w;
+
+ frame = (int*)calloc(sizeof(int), 4);
+
+ frame[0] = 0;
+ frame[1] = 0;
+ frame[2] = cx->GetWidth();
+ frame[3] = cx->GetHeight();
+
+ // Determine if we're on an accelerated context. If so, we create a texture out of the bitmap.
+ // Then we store what we'll use to the void* bitmap, either Tex or Surf.
+
+ if (cx->Accelerated()) {
+ SDL_Texture* tex = SDL_CreateTextureFromSurface(ctx->Renderer(), bitmap_tmp);
+ this->bitmap = (void*)tex;
+ SDL_FreeSurface(bitmap_tmp);
+ }
+ else {
+ this->bitmap = (void*)bitmap_tmp;
+ }
+
+ this->dispMode = mode;
+ }
+
+ // Sets the position on screen.
+
+ void UDisplayable::SetXY(double x, double y) {
+ if (Error)
+ return;
+ this->x = x;
+ this->y = y;
+
+ // Expand that logic above.
+
+ if(this->x < 0)
+ this->x = 0;
+ if(this->y < 0)
+ this->y = 0;
+
+ if(frameIndex == -1) {
+ if(this->x > frame[2] - this->bmp_w)
+ this->x = (double)(frame[2] - this->bmp_w);
+ }
+ else {
+ if(this->x > frame[2] - this->frameWidth)
+ this->x = (double)(frame[2] - this->frameWidth);
+ }
+
+ if(this->y > frame[3] - this->bmp_h)
+ this->y = (double)(frame[3] - this->bmp_h);
+
+ this->loc.x = (int)this->x;
+ this->loc.y = (int)this->y;
+
+ #ifdef DEBUG_OVERKILL
+ printf("[UDisplayable::SetXY] x:%d y:%d w:%d h:%d\n", frame[0], frame[1], frame[2], frame[3]);
+ #endif
+ }
+
+ // Modifies the position on screen. Meant to avoid embedded retrievals.
+
+ void UDisplayable::ModXY(double x, double y) {
+ if (Error)
+ return;
+
+ this->x += x;
+ this->y += y;
+
+ // Expand that logic above.
+
+ if(this->x < 0)
+ this->x = 0;
+ if(this->y < 0)
+ this->y = 0;
+
+ if(frameIndex == -1) {
+ if(this->x > frame[2] - this->bmp_w)
+ this->x = (double)(frame[2] - this->bmp_w);
+ }
+ else {
+ if(this->x > frame[2] - this->frameWidth)
+ this->x = (double)(frame[2] - this->frameWidth);
+ }
+
+ if(this->y > frame[3] - this->bmp_h)
+ this->y = (double)(frame[3] - this->bmp_h);
+
+ this->loc.x = (int)this->x;
+ this->loc.y = (int)this->y;
+
+ #ifdef DEBUG_OVERKILL
+ printf("[UDisplayable::SetXY] x:%d y:%d w:%d h:%d\n", frame[0], frame[1], frame[2], frame[3]);
+ #endif
+ }
+
+ // Get X coord.
+
+ double UDisplayable::GetX() {
+ if (Error)
+ return 0;
+
+ return this->x;
+ }
+
+ // Get Y coord.
+
+ double UDisplayable::GetY() {
+ if (Error)
+ return 0;
+ return this->y;
+ }
+
+ // Get aligned X coord.
+
+ int UDisplayable::GetXI() {
+ if (Error)
+ return 0;
+ return this->loc.x;
+ }
+
+ // Get aligned Y coord.
+
+ int UDisplayable::GetYI() {
+ if (Error)
+ return 0;
+ return this->loc.y;
+ }
+
+ // Get Width
+
+ int UDisplayable::GetW() {
+ if (Error)
+ return 0;
+ return this->bmp_w;
+ }
+
+ // Get Height
+
+ int UDisplayable::GetH() {
+ if (Error)
+ return 0;
+ return this->bmp_h;
+ }
+
+ // Blit to an associated context.
+
+ void UDisplayable::Blit() {
+ if (Error)
+ return;
+
+ // Copy loc and alter position.
+ SDL_Rect loc_adj;
+ loc_adj.x = loc.x + frame[0];
+ loc_adj.y = loc.y + frame[1];
+ loc_adj.w = frameWidth;
+ loc_adj.h = bmp_h;
+
+ #ifdef DEBUG_OVERKILL
+ printf("[UDisplayable::Blit]\n");
+ #endif
+
+ if (frameIndex == -1) {
+ ctx->Blit(bitmap, NULL, &loc_adj);
+ return;
+ }
+
+ SDL_Rect frameClip;
+
+ frameClip.x = frameWidth * frameIndex;
+ frameClip.y = 0;
+ frameClip.w = frameWidth;
+ frameClip.h = bmp_h;
+
+ ctx->Blit(bitmap, &frameClip, &loc_adj);
+ }
+
+ // Get SDL_Rect for collision calculation. In a base Displayable, it returns the image width.
+ // In a derived class, it may return only a hitbox.
+
+ int* UDisplayable::GetHitbox() {
+ if (Error)
+ return NULL;
+ int* rect = (int*)calloc(sizeof(int), 4);
+
+ rect[0] = hitbox[0] + (int)this->x;
+ rect[1] = hitbox[1] + (int)this->y;
+ rect[2] = hitbox[2];
+ rect[3] = hitbox[3];
+
+ return rect;
+ }
+
+ // Destroy bitmap.
+
+ UDisplayable::~UDisplayable() {
+ if (Error)
+ return;
+ if(ctx->Accelerated())
+ SDL_DestroyTexture((SDL_Texture*)bitmap);
+ else
+ SDL_FreeSurface((SDL_Surface*)bitmap);
+ free(hitbox);
+ free(frame);
+ }
+
+ void UDisplayable::SetHitbox(int x, int y, int w, int h) {
+ if (Error)
+ return;
+ if(dispMode == Normal || dispMode == Docked || dispMode == Anim || dispMode == AnimDocked)
+ return;
+
+ hitbox[0] = x;
+ hitbox[1] = y;
+ hitbox[2] = w;
+ hitbox[3] = h;
+ }
+
+ void UDisplayable::SetDock(int x, int y, int w, int h) {
+ if (Error)
+ return;
+ if(dispMode == Normal || dispMode == Hitbox || dispMode == Anim || dispMode == AnimHitbox)
+ return;
+ frame[0] = x;
+ frame[1] = y;
+ frame[2] = w;
+ frame[3] = h;
+ }
+
+ void UDisplayable::NextFrame() {
+ if (Error)
+ return;
+ if (dispMode == Normal || dispMode == Hitbox || dispMode == Docked || dispMode == HitboxDocked)
+ return;
+
+ ++frameIndex;
+
+ if(frameWidth * frameIndex >= bmp_w)
+ frameIndex = 0;
+ }
+
+ void UDisplayable::NextFrame(int f) {
+ if (Error)
+ return;
+ if (dispMode == Normal || dispMode == Hitbox || dispMode == Docked || dispMode == HitboxDocked)
+ return;
+ frameIndex += f;
+
+ if(frameWidth * frameIndex >= bmp_w)
+ frameIndex = 0;
+ }
+
+ void UDisplayable::ResetFrame() {
+ if (Error)
+ return;
+ if (dispMode == Normal || dispMode == Hitbox || dispMode == Docked || dispMode == HitboxDocked)
+ return;
+ frameIndex = 0;
+ }
+
+ void UDisplayable::SetFrame(int f) {
+ if (Error)
+ return;
+ if (dispMode == Normal || dispMode == Hitbox || dispMode == Docked || dispMode == HitboxDocked)
+ return;
+
+ frameIndex = f;
+ }
+
+ void UDisplayable::SetFrameWidth(int frameW) {
+ if (Error)
+ return;
+ if (dispMode == Normal || dispMode == Hitbox || dispMode == Docked || dispMode == HitboxDocked)
+ return;
+ this->frameWidth = frameW;
+
+ #ifdef DEBUG_OVERKILL
+ printf("[UDisplayable::SetFrameWidth] fW:%d\n", frameW);
+ #endif
+ }
--- /dev/null
+#ifndef UDISPLAYABLE_HPP
+#define UDISPLAYABLE_HPP
+
+typedef enum {
+ Normal=1,
+ Hitbox=2,
+ Docked=3,
+ HitboxDocked=4,
+ Anim=5, // nyi
+ AnimHitbox=6, // nyi
+ AnimDocked=7, // nyi
+ AnimHitboxDocked=8 // nyi
+} UDisplayableMode;
+
+ class UDisplayable {
+ public:
+ UDisplayable(ContextManager* ctx, char* fname); // Sets up in normal mode.
+ UDisplayable(ContextManager* ctx, UDisplayableMode mode, char* fname); // Sets up in specified mode; params not set
+ UDisplayable(ContextManager* ctx, UDisplayableMode mode, void* memory, int mSize); // Sets up from memory block in mode
+
+ // All modes can use the following.
+ void SetXY(double x, double y);
+ void ModXY(double xd, double yd);
+
+ double GetX();
+ double GetY();
+
+ int GetXI();
+ int GetYI();
+
+ int GetW();
+ int GetH();
+
+ void Blit();
+
+ int* GetHitbox();
+
+ ~UDisplayable();
+
+ // Only specific modes can use these. Otherwise, they nop.
+ void SetHitbox(int x, int y, int w, int h);
+ void SetDock(int x, int y, int w, int h);
+
+ // Only animated Displayables can use these.
+ void SetFrameWidth(int frameW);
+ void NextFrame();
+ void NextFrame(int f);
+ void ResetFrame();
+ void SetFrame(int f);
+
+
+ protected:
+ void DefaultVars();
+
+ double x, y;
+ void* bitmap; // Will contain either a SDL_Surface or SDL_Texture
+ SDL_Rect loc, clip;
+ ContextManager* ctx;
+
+ int bmp_w, bmp_h;
+
+ // Used in docked mode
+ int* frame;
+ // Used in hitbox mode
+ int* hitbox;
+
+ // The current mode.
+ UDisplayableMode dispMode;
+
+ // Used by animated mode.
+ int frameIndex;
+ int frameWidth;
+
+ bool Error;
+ };
+#endif
--- /dev/null
+#include "Zero.hpp"
+
+#include "Funcs.hpp"
+
+#include <unistd.h>
+#include <signal.h>
+
+
+
+void DebugTrap(int sig) {
+ GetData()->debug_to_shell = true;
+}
+
+int main(int argc, char** argv) {
+ printf(" ___________________________________________________________ \n");
+ printf("| VNDC - VNDC is Not a Direct Clone (of VNDS ;P) |\n");
+ printf("| Interprets VNDS scripts with a few goodies and extensions |\n");
+ printf("| (C) Jonathan Feldman 2014 - Under the MIT license |\n");
+ printf("| git: %s |\n", GIT_REV);
+ printf("|___________________________________________________________|\n\n");
+
+ char* chdir_to_dir = NULL;
+ char* main_script_override = NULL;
+ char* save_file = NULL;
+ bool vndc_extensions = true;
+ int width = 0, height = 0;
+ bool debug_enable = false;
+ bool enable_v = false;
+ bool newgame = false;
+ char c;
+
+ while((c = getopt(argc, argv, "nbvx:y:d:m:s:ch")) != -1) {
+ switch(c) {
+ case 'n':
+ printf("[info] New game, not reloading save.\n");
+ newgame = true;
+ case 'v':
+ printf("[info] Script commands will be echoed.\n");
+ enable_v = true;
+ break;
+ case 'b':
+ printf("[debug] Debug Mode enabled.\n");
+ debug_enable = true;
+ break;
+ case 'd':
+ printf("[info] Directory specified: %s\n", optarg);
+ chdir_to_dir = optarg;
+ break;
+ case 'x':
+ sscanf(optarg, "%d", &width);
+ break;
+ case 'y':
+ sscanf(optarg, "%d", &height);
+ chdir_to_dir = optarg;
+ break;
+ case 'm':
+ printf("[debug] Main script overriden as: '%s'\n", optarg);
+ main_script_override = optarg;
+ break;
+ case 's':
+ printf("[info] Load save: '%s'\n", optarg);
+ save_file = optarg;
+ break;
+ case 'c':
+ printf("[debug] Compliant mode: all VNDC extensions off\n");
+ vndc_extensions = false;
+ break;
+ case 'h':
+ printf("-x size -y size\tStretch display window to WxH\n");
+ printf("-n\t\tNew Game. Do not reload default save.\n");
+ printf("-d dir\t\tChange to directory/Run game in directory\n");
+ printf("-b\t\tDebug Mode. Hit Ctrl+C on console for shell\n");
+ printf("-v\t\tVerbose. Echo script commands back as they execute\n");
+ printf("-m .scr\t\tLoad .scr as main script\n");
+ printf("-s .scr\t\tLoad save .scr instead of default\n");
+ printf("-c\t\tCompliant mode; don't use VNDC extensions\n");
+ printf("-h\t\tPrint this help message\n\n");
+ return 0;
+ break;
+ default:
+ break;
+ }
+ }
+
+ CreateDataContainer();
+
+ GetData()->ctx = new ContextManager();
+
+ if(chdir_to_dir)
+ chdir(chdir_to_dir);
+ if(main_script_override != NULL) {
+ printf("[debug] Note that in this mode, l_flags is not set.\n[debug] Expect bugs/gameover, this is normal.\n");
+ memset(GetData()->main_scr[0], 0, 399);
+ strncpy(GetData()->main_scr[0], main_script_override, 399);
+ }
+ GetData()->vndc_enabled = vndc_extensions;
+ GetData()->verbose = enable_v;
+ if(debug_enable) {
+ signal(SIGINT, DebugTrap);
+ GetData()->debug_mode = true;
+ }
+
+ if(width > 0 && height > 0) {
+ GetData()->physical_w = width;
+ GetData()->physical_h = height;
+ }
+
+ Setup();
+
+ if(!save_file) {
+ // Check if a default save exists at save.scr.
+ if(newgame == false) {
+ FILE* t = fopen((char*)"save.scr", "r");
+ if(t != NULL) {
+ // File exists. first, close the descriptor.
+ fclose(t);
+ // Op_jump to it
+ op_jump((char*)"save.scr", NULL, true);
+ }
+ else // Jump to main, there is no save.
+ op_jump(GetData()->main_scr[0], NULL, true);
+ }
+ else // Otherwise just jump to the main screen.
+ op_jump(GetData()->main_scr[0], NULL, true);
+ }
+ else // Jump to save file specified.
+ op_jump(save_file, NULL, true);
+
+ while(!(GetData()->ctx->GetQuit())) {
+ Loop();
+ }
+
+ delete GetData()->ctx;
+ delete GetData();
+
+ return 0;
+}
--- /dev/null
+#ifndef _ZERO_LIBRARY_HPP
+#define _ZERO_LIBRARY_HPP
+
+#ifdef __WIN32
+#include <windows.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <SDL.h>
+#include <SDL_image.h>
+#include <SDL_mixer.h>
+#include <SDL_ttf.h>
+
+#include "AudioManager.hpp"
+#include "ContextManager.hpp"
+#include "TextManager.hpp"
+#include "UDisplayable.hpp"
+
+#endif
--- /dev/null
+#ifndef GIT_REV_HDR
+#define GIT_REV_HDR
+#define GIT_REV "c7ef31d2ee1c2c24b2c76369d203ac024dfae5f9"
+
+#endif
--- /dev/null
+#include "Zero.hpp"
+
+#include "Funcs.hpp"
+
+/*
+ * Implements bgload vnds function.
+ * bgload file [fadetime] (default 16)
+ */
+
+void op_bgload(char* file, int* fadetime) {
+ if (GetData()->if_fail != 0 || GetData()->ctx->GetQuit())
+ return;
+
+ // Fadeout not implemented yet.
+
+ memset(GetData()->current_bg, 0, 400);
+
+ snprintf(GetData()->current_bg, 400, "background/%s", file);
+
+ //printf("Attempt to load file %s as BG\n", path);
+
+ // Load displayable.
+ SDL_Surface* sfc = IMG_Load(GetData()->current_bg);
+
+ uint8_t transp_incr = 16;
+ if(fadetime != NULL)
+ transp_incr = 255 / *fadetime;
+
+ // Transition effect.
+
+ SDL_Texture* tx = NULL;
+ tx = SDL_CreateTextureFromSurface(GetData()->ctx->Renderer(), sfc);
+ SDL_SetTextureBlendMode(tx, SDL_BLENDMODE_BLEND);
+
+ SDL_FreeSurface(sfc);
+
+ int delay = 1;
+ for(int tr = 0; tr < 255; tr += transp_incr) {
+ SDL_SetTextureAlphaMod(tx, tr);
+ GetData()->ctx->Blit(tx, NULL, NULL);
+ op_delay(&delay);
+ }
+
+ SDL_DestroyTexture(tx);
+}
--- /dev/null
+#include "Zero.hpp"
+
+#include "Funcs.hpp"
+
+/*
+ * Implements choice vnds function.
+ * choice choicest1|choicest2|... [>var]
+ * [>var] is an extension of this dialect
+ * which stores the result into a specific variable
+ * The default will still be 'selected' if not specified
+ */
+
+void op_choice(char* line) {
+ if (GetData()->if_fail != 0)
+ return;
+ // Strtok by the pipe '|' character
+
+ //printf("%s\n", line);
+
+ int num = 1;
+ char** tokens = (char**)realloc(NULL, sizeof(char*) * (1));
+ tokens[num-1] = strtok(line, "|");
+
+ do {
+ //printf("Loop: num = %d;\n", num);
+ ++num;
+ tokens = (char**)realloc(tokens, sizeof(char*) * (num));
+ tokens[num-1] = strtok(NULL, "|");
+ } while(tokens[num-1] != NULL);
+
+ --num;
+
+ /*for(int i=0; i<num; i++) {
+ printf("%s\n", tokens[i]);
+ }*/
+
+ // Scan thru the last token to see if a '>' is there.
+
+ char varname[400];
+ memset(varname, 0, 400);
+ int defaultname = 0;
+
+ if(GetData()->vndc_enabled) { // This is an extension.
+ for( int i = strlen(tokens[num-1]); i >= 0; i-- ) {
+ if(tokens[num-1][i] == '>') {
+ // Yes there is.
+ defaultname = i + 1;
+ tokens[num-1][i] = '\0';
+ break;
+ }
+ }
+ }
+
+ if(defaultname > 0) {
+ strncpy(varname, &tokens[num-1][defaultname], 400);
+ }
+ else {
+ strncpy(varname, "selected", 400);
+ }
+
+ op_cleartext();
+
+ // For each choice, we need to print text and make a click area. This will use the text function.
+ int *choices = (int*)calloc(sizeof(int), num * 2);
+
+ for(int i=0; i < num*2; i+=2) {
+ choices[i] = GetData()->text_y;
+ char* outarr = (char*)calloc(sizeof(char*), strlen(tokens[i/2])+3);
+ outarr[0] = '0' + (i/2);
+ outarr[1] = '.';
+ outarr[2] = ' ';
+ strncpy(&outarr[3], tokens[i/2], strlen(tokens[i/2]));
+ op_text(outarr);
+ free(outarr);
+ choices[i+1] = GetData()->text_y;
+ }
+
+ GetData()->choice_coords = choices;
+ GetData()->choices = num;
+
+ while(GetData()->choices > 0) {
+ if(GetData()->ctx->GetQuit()) goto killed;
+
+ GetData()->ctx->Flush();
+
+ GetData()->ctx->StartSync();
+ GetData()->ctx->Input();
+ GetData()->ctx->EndSync();
+ }
+
+ // Get the chosen option and load it to a variable (abs of course)
+
+ GetData()->s_flags[0][std::string(varname)] = -(GetData()->choices);
+
+ // Clear after choices. Period.
+ op_cleartext();
+
+killed:
+
+ // Also reset the 'need to click' since we just did.
+ GetData()->wait_input = false;
+}
--- /dev/null
+#include "Zero.hpp"
+
+#include "Funcs.hpp"
+
+void ct_transwindow() {
+
+ int width_dr = (GetData()->render_x2 - GetData()->render_x1 + 20);
+ int height_dr = (GetData()->render_y2 - GetData()->render_y1 + 30 + 20);
+
+ SDL_Surface* sfc = SDL_CreateRGBSurface(0, width_dr, height_dr, 32, 0, 0, 0, 0);
+ SDL_FillRect(sfc, NULL, SDL_MapRGBA(sfc->format, 0, 0, 0, 128));
+
+ SDL_Rect src;
+ src.x = 0;
+ src.y = 0;
+ src.w = sfc->w;
+ src.h = sfc->h;
+
+ SDL_Texture* dim = SDL_CreateTextureFromSurface(GetData()->ctx->Renderer(), sfc);
+ SDL_SetTextureBlendMode(dim, SDL_BLENDMODE_BLEND);
+ SDL_SetTextureAlphaMod(dim, 128);
+
+ SDL_FreeSurface(sfc);
+
+ SDL_Rect dst;
+ dst.x = GetData()->render_x1 - 10;
+ dst.y = GetData()->render_y1 - 10;
+ dst.w = src.w;
+ dst.h = src.h;
+
+ GetData()->ctx->OverlayBlit(dim, &src, &dst);
+
+ SDL_DestroyTexture(dim);
+}
+
+/*
+ * Implements cleartext vnds function.
+ * cleartext mod
+ * However, we ignore mod for now.
+ */
+
+void op_cleartext() {
+ if (GetData()->if_fail != 0 || GetData()->ctx->GetQuit())
+ return;
+
+ GetData()->text_x = GetData()->render_x1;
+ GetData()->text_y = GetData()->render_y1;
+ GetData()->ctx->ClearOverlay();
+
+ // Dim transparent overlay
+ ct_transwindow();
+}
--- /dev/null
+#include "Zero.hpp"
+
+#include "Funcs.hpp"
+
+/*
+ * Implements delay vnds function.
+ * delay frames
+ */
+
+void op_delay(int* frames) {
+ if (GetData()->if_fail != 0 || GetData()->ctx->GetQuit())
+ return;
+ for(int i = 0; i < *frames; i++) {
+ // This is one frame.
+ GetData()->ctx->StartSync();
+ GetData()->ctx->EndSync();
+ }
+}
--- /dev/null
+#include "Zero.hpp"
+
+#include "Funcs.hpp"
+
+/*
+ * Implements fi vnds function.
+ * if var op val
+ */
+
+void op_fi() {
+ if(GetData()->if_fail != 0)
+ GetData()->if_fail -= 1;
+}
--- /dev/null
+#include "Zero.hpp"
+
+#include "Funcs.hpp"
+
+/* Implements vnds goto function
+ * goto label
+ * File pointer is provided so we can rewind.
+ */
+
+void op_goto(char* label) {
+ if (GetData()->if_fail != 0 || GetData()->ctx->GetQuit())
+ return;
+ FILE** infile = &(GetData()->accessScriptHandle);
+
+ rewind(*infile);
+
+ char *line = (char*)calloc(sizeof(char), 400);
+
+ int line_to = 0;
+
+ bool found = false;
+ while(!found) {
+ line_to++;
+ fgets(line, 400, *infile);
+
+ // Remove all '\n' from this string
+ for(int i=0; i < 400; i++) {
+ if (line[i] == '\n')
+ line[i] = '\0';
+ }
+
+ int num = 1;
+ char** tokens = (char**)realloc(NULL, sizeof(char*) * (1));
+ tokens[num-1] = strtok(line, " ");
+
+ do {
+ //printf("Loop: num = %d;\n", num);
+ ++num;
+ tokens = (char**)realloc(tokens, sizeof(char*) * (num));
+ tokens[num-1] = strtok(NULL, " ");
+ } while(tokens[num-1] != NULL);
+
+ --num;
+
+ if(!strcmp(tokens[0], "label"))
+ if(!strcmp(tokens[1], label))
+ found = true;
+ }
+ GetData()->currentLine = line_to;
+}
--- /dev/null
+#include "Zero.hpp"
+
+#include "Funcs.hpp"
+
+/*
+ * Implements gsetvar vnds function.
+ * gsetvar var mod val
+ * Modifier is '=' '+' or '-' in script, simplify to ('-':-1, '=':0, '+':1).
+ * is apparently UTF8 friendly
+ * Also, for now I simply redirect to setvar. Global values are only set
+ * by definition on an end-game event for replays, so when the interpreter hits
+ * 'the end' it loops back to the title.
+ *
+ * As an exception, setvar ~ ~ will ignore all vars prefixed with g
+ * because these are globals.
+ *
+ * You can set global vars with setvar because my implementation just
+ * works different here, but still.
+ *
+ * Any local vars will obviously be nuked by setvar ~ ~.
+ */
+
+void op_gsetvar(char* var, int *modifier, char *value) {
+ if (GetData()->if_fail != 0)
+ return;
+
+ op_setvar(var, modifier, value);
+}
--- /dev/null
+#include "Zero.hpp"
+
+#include "Funcs.hpp"
+
+/*
+ * Implements if vnds function.
+ * if var op val
+ * op is a c-style compare
+ * ('<=':0 '<':1 '==':2 '!=':3 '>': '>=':5)
+ */
+
+void op_if(char* left, int* op, char* right) {
+ if (GetData()->if_fail != 0) {
+ GetData()->if_fail += 1;
+ return;
+ }
+
+ int r_val = 0, ret = 0;
+
+ ret = sscanf(right, "%d", &r_val);
+
+ if(ret == 0 && GetData()->vndc_enabled) { // This is a var name. We couldn't scan a number.
+ r_val = GetData()->s_flags[0][std::string(right)];
+ }
+
+ int l_val = GetData()->s_flags[0][std::string(left)];
+
+ //printf("op_if(%s, %d, %d)\n", var, op[0], val[0]);
+ //printf("GetData()->s_flags[0][%s] = %d\n", var, GetData()->s_flags[0][std::string(var)]);
+
+ switch (op[0]) {
+ case 0:
+ if ( !(l_val <= r_val) )
+ GetData()->if_fail += 1;
+ break;
+ case 1:
+ if ( !(l_val < r_val) )
+ GetData()->if_fail += 1;
+ break;
+ case 2:
+ if ( !(l_val == r_val) )
+ GetData()->if_fail += 1;
+ break;
+ case 3:
+ if ( !(l_val != r_val) )
+ GetData()->if_fail += 1;
+ break;
+ case 4:
+ if ( !(l_val > r_val) )
+ GetData()->if_fail += 1;
+ break;
+ case 5:
+ if ( !(l_val >= r_val) )
+ GetData()->if_fail += 1;
+ break;
+ }
+}
--- /dev/null
+#include "Zero.hpp"
+
+#include "Funcs.hpp"
+
+/*
+ * Implements jump vnds function.
+ * jump file
+ */
+
+void op_jump(char* file, int* lineTo, bool isSave) {
+ if (GetData()->if_fail != 0)
+ return;
+
+ memset(GetData()->current_scr, 0, 400);
+ if(!isSave)
+ snprintf(GetData()->current_scr, 400, "script/%s", file);
+ else
+ snprintf(GetData()->current_scr, 400, "%s", file);
+
+ if(GetData()->debug_mode) {
+ memset(&GetData()->window_name[16], 0, sizeof(char)*400);
+ snprintf(&GetData()->window_name[16], 400-16-3, " (%s)", file);
+ GetData()->ctx->SetTitle(GetData()->window_name);
+ }
+
+ if(GetData()->accessScriptHandle != NULL)
+ fclose(GetData()->accessScriptHandle);
+
+ GetData()->accessScriptHandle = fopen(GetData()->current_scr, "r");
+ if(GetData()->accessScriptHandle == NULL) {
+ printf("[error] Failed to open script file %s.\n", GetData()->current_scr);
+ exit(-1);
+ }
+
+
+ if(lineTo != NULL) {
+ GetData()->currentLine = lineTo[0];
+ char *line = (char*)calloc(sizeof(char), 400);
+
+ while(--lineTo[0] > 0) {
+ fgets(line, 400, GetData()->accessScriptHandle);
+ }
+ }
+ else {
+ GetData()->currentLine = 0;
+ }
+
+ // Read the first line into next_line.
+ GetData()->next_line = (char*)calloc(sizeof(char), 400);
+ // Load the next line.
+ fgets(GetData()->next_line, 400, GetData()->accessScriptHandle);
+
+}
--- /dev/null
+#include "Zero.hpp"
+
+#include "Funcs.hpp"
+
+/*
+ * Implements music vnds function.
+ * music file
+ */
+
+void op_music(char* file) {
+ if (GetData()->if_fail != 0 || GetData()->ctx->GetQuit())
+ return;
+
+ memset(GetData()->current_music, 0, 400);
+
+ snprintf(GetData()->current_music, 400, "sound/%s", file);
+
+ // Halt command
+ if (!strcmp(file, "~")) {
+ GetData()->ctx->Audio()->FlushMusic();
+ }
+ // Play command
+ else {
+ GetData()->ctx->Audio()->FlushMusic();
+
+ int index = GetData()->ctx->Audio()->LoadMusic(GetData()->current_music);
+
+ GetData()->ctx->Audio()->PlayMusicLoop(index);
+ }
+}
--- /dev/null
+#include "Zero.hpp"
+
+#include "Funcs.hpp"
+
+/*
+ * Implements random vnds function.
+ * random var low high
+ */
+
+bool seeded = false;
+
+void op_random(char* var, int* low, int* high) {
+ if (GetData()->if_fail != 0)
+ return;
+ if (seeded == false)
+ srand(time(NULL));
+
+ int num = *low + ( rand() % ( *high - *low ) );
+
+ GetData()->s_flags[0][std::string(var)] = num;
+}
--- /dev/null
+#include "Zero.hpp"
+
+#include "Funcs.hpp"
+
+/*
+ * Implements setimg vnds function.
+ * setimg file x y
+ */
+
+void op_setimg(char* file, int* x, int* y) {
+ if (GetData()->if_fail != 0 || GetData()->ctx->GetQuit())
+ return;
+
+ // Fadeout not implemented yet.
+
+ char path[400];
+ memset(path, 0, 400);
+
+ snprintf(path, 400, "foreground/%s", file);
+
+ // Load displayable.
+ UDisplayable* fg_add = new UDisplayable(GetData()->ctx, Normal, path);
+
+ // Centered NDS adapted
+ double adp_x = ((double)x[0]) * (GetData()->screen_w / 256);
+ double adp_y = ((double)y[0]) * (GetData()->screen_h / 192);
+ fg_add->SetXY((int)adp_x, (int)adp_y);
+
+ // Raw
+ // fg_add->SetXY(x[0], y[0]);
+
+ fg_add->Blit();
+
+ // Delete fg_new. We're done with it.
+ delete fg_add;
+}
--- /dev/null
+#include "Zero.hpp"
+
+#include "Funcs.hpp"
+
+/*
+ * Implements gsetvar vnds function.
+ * gsetvar var mod val
+ * Modifier is '=' '+' or '-' in script, simplify to ('-':-1, '=':0, '+':1).
+ * MAY need to be UTF8 friendly
+ */
+
+void op_setvar(char* var, int* modifier, char* value) {
+ if (GetData()->if_fail != 0)
+ return;
+
+ int value_r = 0, ret;
+ if(value == NULL)
+ ret = 0;
+ else
+ ret = sscanf(value, "%d", &value_r);
+
+ if(ret == 0 && GetData()->vndc_enabled) { // value is a variable not a number
+ if(*modifier == 0) {
+ GetData()->s_flags[0][std::string(var)] = GetData()->s_flags[0][std::string(value)];
+ }
+ else if (*modifier == -1) {
+ GetData()->s_flags[0][std::string(var)] -= GetData()->s_flags[0][std::string(value)];
+ }
+ else if (*modifier == 1) {
+ GetData()->s_flags[0][std::string(var)] += GetData()->s_flags[0][std::string(value)];
+ }
+ }
+ else {
+ if(*modifier == 0) {
+ GetData()->s_flags[0][std::string(var)] = value_r;
+ }
+ else if (*modifier == -1) {
+ GetData()->s_flags[0][std::string(var)] -= value_r;
+ }
+ else if (*modifier == 1) {
+ GetData()->s_flags[0][std::string(var)] += value_r;
+ }
+ else if (*modifier == -2) {
+ // There's a rare case on program start where a resetall
+ // happens.
+
+ if(!strcmp(var, "~")) {
+ // We'll handle it by searching through and deleting all non-G values.
+ // g values are global, so they by definition survive this.
+
+ if(!GetData()->s_flags[0].empty()) {
+ std::map<std::string, int>::iterator item = GetData()->s_flags[0].begin();
+ while(item != GetData()->s_flags[0].end()) {
+ if(item->first.c_str()[0] != 'g')
+ GetData()->s_flags[0].erase(item++);
+ else
+ item++;
+ }
+ }
+ return;
+ }
+
+ GetData()->s_flags[0][std::string(var)] = 0;
+ }
+ }
+}
--- /dev/null
+#include "Zero.hpp"
+
+#include "Funcs.hpp"
+
+/*
+ * Implements sound vnds function.
+ * sound file [times]
+ */
+
+void op_sound(char* file, int* times) {
+ if (GetData()->if_fail != 0 || GetData()->ctx->GetQuit())
+ return;
+
+ // Fadeout not implemented yet.
+
+ // Halt command
+ if (!strcmp(file, "~")) {
+ GetData()->ctx->Audio()->FlushSfx();
+ return;
+ }
+ // Extension - Voiced auto-stop. If the next line contains quotes,
+ // it is voiced. We set a flag in response. If the flag is already
+ // set - e.g. the sound was a voice as well, we stop the previous
+ // sound before playing this one.
+
+ if(GetData()->vndc_enabled && // 0 1 2 3 4 5
+ (GetData()->next_line[5] == '"' || // t e x t "
+ GetData()->next_line[strlen(GetData()->next_line) - 1] == '"' ||
+ GetData()->quote_incomplete)) {
+ GetData()->ctx->Audio()->FlushSfx();
+
+ if(GetData()->next_line[5] == '"' &&
+ !(GetData()->next_line[strlen(GetData()->next_line) - 1] == '"')) {
+ // Quote is incomplete.
+ GetData()->quote_incomplete = true;
+ }
+
+ if(GetData()->next_line[strlen(GetData()->next_line) - 1] == '"' &&
+ !(GetData()->next_line[5] == '"')) {
+ GetData()->quote_incomplete = false;
+ }
+
+ }
+
+ // Play command
+ int count = 1;
+ if (times != NULL)
+ count = *times;
+
+ char path[400];
+ memset(path, 0, 400);
+
+ snprintf(path, 400, "sound/%s", file);
+
+ // Load sfx.
+ int sfxi = GetData()->ctx->Audio()->LoadSfx(path);
+
+ if (count == -1) {
+ GetData()->ctx->Audio()->PlaySfx(sfxi, count);
+ }
+ else {
+ GetData()->ctx->Audio()->PlaySfx(sfxi, count-1);
+ }
+}
--- /dev/null
+#include "Zero.hpp"
+
+#include "Funcs.hpp"
+
+/*
+ * Implements text vnds function.
+ * text string
+ */
+
+void op_text(char* string) {
+ if (GetData()->if_fail != 0 || GetData()->ctx->GetQuit())
+ return;
+
+ // Search thru for vars and rebuild string.
+
+ // Linebreak on zero-length, and render size exceed.
+ if (GetData()->text_y > (GetData()->render_y2) || strlen(string) < 1)
+ op_cleartext();
+
+ if(strlen(string) < 1)
+ return;
+
+ // Improvised linebreak. Also, an extension.
+ if(GetData()->vndc_enabled && string[1] == '-' && string[2] == '-' && string[3] == '-') {
+ op_cleartext();
+ }
+ // Improvised Tag display. Extension.
+ if(GetData()->vndc_enabled && string[0] == '<' && string[strlen(string)-1] == '>') {
+ string[strlen(string)-1] = '\0';
+ string = &string[1];
+
+ GetData()->ctx->ClearOverlay();
+
+ TextManager* txt = GetData()->ctx->Text();
+
+ int xloc = ( GetData()->screen_w - (txt->TestLen(string) + GetData()->render_x1) );
+
+ txt->Render(string, xloc, GetData()->render_y1);
+
+ GetData()->wait_input = true;
+ Wait();
+
+ op_cleartext();
+
+ return;
+ }
+ // Wait for input, then blank
+ if(!strcmp(string, "!")) {
+ GetData()->wait_input = true;
+ Wait();
+ op_cleartext();
+ }
+ // Blank screen
+ else if(!strcmp(string, "~")) {
+ op_cleartext();
+ }
+ // Output
+ else {
+ bool noclick = false;
+ // No click required
+ if(string[0] == '@') {
+ noclick = true;
+ string = &string[1];
+ }
+
+
+ TextManager* txt = GetData()->ctx->Text();
+
+ if(txt->TestLen(string) > (GetData()->render_x2 - GetData()->render_x1)) {
+
+ /* new algo */
+ char** ptrs = NULL;
+ int lines = 0;
+
+ int len = strlen(string);
+
+ int counted = 0;
+
+ while(counted < len) {
+ char* pt_start = &string[counted];
+ char* pt_end = &pt_start[strlen(pt_start)];
+
+ while(pt_end > pt_start && txt->TestLen(pt_start) > (GetData()->render_x2 - GetData()->render_x1)) {
+ *pt_end = ' ';
+ --pt_end;
+
+ while (*pt_end != ' ' && pt_end > pt_start) --pt_end;
+
+ *pt_end = '\0';
+ }
+
+ #ifdef DEBUG_OVERKILL
+ printf("Reduced line %d: %s\n", lines, pt_start);
+ #endif
+
+ ptrs = (char**)realloc(ptrs, sizeof(char*)*(lines+1));
+
+ ptrs[lines] = pt_start;
+
+ counted += strlen(pt_start) + 1;
+
+ ++lines;
+ }
+
+ if( ( lines * 35 + GetData()->text_y ) > GetData()->render_y2 )
+ op_cleartext();
+
+ for(int i=0; i < lines; i++) {
+ //printf("[br] %s\n", ptrs[i]);
+ txt->Render(ptrs[i], GetData()->text_x, GetData()->text_y);
+ GetData()->text_y += 35;
+ }
+
+ free(ptrs);
+
+ }
+ else {
+ txt->Render(string, GetData()->text_x, GetData()->text_y);
+ GetData()->text_y += 35;
+ }
+
+ if(!noclick) {
+ GetData()->wait_input = true;
+ }
+ }
+}
--- /dev/null
+package com.github.chaoskagami.vndc;
+
+import org.libsdl.app.SDLActivity;
+
+public class VNDCActivity extends SDLActivity { }
void FlushSfx();
void FlushMusic();
private:
- int SfxCount = 0, MusicCount = 0;
- Mix_Chunk** SfxStore = NULL;
- Mix_Music** MusicStore = NULL;
+ int SfxCount, MusicCount;
+ Mix_Chunk** SfxStore;
+ Mix_Music** MusicStore;
};
void _InitWindowLogicalSW(int width_win, int height_win, int width_log, int height_log, bool fulls);
void _InitWindowLogicalAC(int width_win, int height_win, int width_log, int height_log, bool fulls);
- InMode inputmode = Medium;
- SDL_Window* window = NULL;
- SDL_Surface* surface = NULL, *surface_o = NULL;
- SDL_Texture* texture = NULL, *texture_o = NULL;
- SDL_Renderer* renderer = NULL;
+ void DefaultVariables();
+
+ InMode inputmode;
+ SDL_Window* window;
+ SDL_Surface* surface, *surface_o;
+ SDL_Texture* texture, *texture_o;
+ SDL_Renderer* renderer;
// use logical size
- bool logicalRender = false;
- bool accelerate = false;
+ bool logicalRender;
+ bool accelerate;
- bool StartQuit = false;
+ bool StartQuit;
- AudioManager* audioMgr = NULL;
- TextManager* txtMgr = NULL;
+ AudioManager* audioMgr;
+ TextManager* txtMgr;
- SDL_Keycode* inputMappings = NULL; // This can actually be used instead of InputList now. Weird.
- bool* inputStates = NULL;
- GameCallback* inputCallbacks = NULL;
- MouseCallback mouseCallback = NULL;
+ SDL_Keycode* inputMappings; // This can actually be used instead of InputList now. Weird.
+ bool* inputStates;
+ GameCallback* inputCallbacks;
+ MouseCallback mouseCallback;
- int inputRegistered = 0;
+ int inputRegistered;
// Logic cap.
- int logicRate = 60;
- int timeElapsed = 0;
- int syncElapsed = 0;
+ int logicRate;
+ int timeElapsed;
+ int syncElapsed;
// Width and height
- int WIN_width = 0;
- int WIN_height = 0;
- int LOG_width = 0;
- int LOG_height = 0;
+ int WIN_width;
+ int WIN_height;
+ int LOG_width;
+ int LOG_height;
};
#endif
// void scoutf(char* text);
private:
- TTF_Font** fonts = NULL;
- int current_font = 0;
- int fonts_loaded = 0;
+ TTF_Font** fonts;
+ int current_font;
+ int fonts_loaded;
SDL_Color color;
- ContextManager* ctx = NULL;
- bool outline = false;
- int outline_px = 0;
+ ContextManager* ctx;
+ bool outline;
+ int outline_px;
};
protected:
+ void DefaultVars();
+
double x, y;
- void* bitmap = NULL; // Will contain either a SDL_Surface or SDL_Texture
+ void* bitmap; // Will contain either a SDL_Surface or SDL_Texture
SDL_Rect loc, clip;
ContextManager* ctx;
- int bmp_w = 0, bmp_h = 0;
+ int bmp_w, bmp_h;
// Used in docked mode
- int* frame = NULL;
+ int* frame;
// Used in hitbox mode
- int* hitbox = NULL;
+ int* hitbox;
// The current mode.
- UDisplayableMode dispMode = Normal;
+ UDisplayableMode dispMode;
// Used by animated mode.
- int frameIndex = -1;
+ int frameIndex;
int frameWidth;
- bool Error = false;
+ bool Error;
};
#endif
#include <stdio.h>
#include <string.h>
-#include <SDL2/SDL.h>
-#include <SDL2/SDL_image.h>
-#include <SDL2/SDL_mixer.h>
-#include <SDL2/SDL_ttf.h>
+#include <SDL.h>
+#include <SDL_image.h>
+#include <SDL_mixer.h>
+#include <SDL_ttf.h>
#include "AudioManager.hpp"
#include "ContextManager.hpp"
}
Mix_AllocateChannels(64); // 32 Sfx + 1 Music
+
+ MusicStore = NULL;
+ MusicCount = 0;
+ SfxStore = NULL;
+ SfxCount = 0;
}
// Cleans up everything.
#include "Zero.hpp"
+ void ContextManager::DefaultVariables() {
+ inputmode = Medium;
+ window = NULL;
+ surface = NULL; surface_o = NULL;
+ texture = NULL; texture_o = NULL;
+ renderer = NULL;
+ // use logical size
+ logicalRender = false;
+ accelerate = false;
+
+ StartQuit = false;
+
+ audioMgr = NULL;
+ txtMgr = NULL;
+
+ inputMappings = NULL; // This can actually be used instead of InputList now. Weird.
+ inputStates = NULL;
+ inputCallbacks = NULL;
+ mouseCallback = NULL;
+
+ inputRegistered = 0;
+
+ // Logic cap.
+ logicRate = 60;
+ timeElapsed = 0;
+ syncElapsed = 0;
+
+ // Width and height
+ WIN_width = 0;
+ WIN_height = 0;
+ LOG_width = 0;
+ LOG_height = 0;
+ }
+
// Initializes SDL and saves stuff into the context.
ContextManager::ContextManager(int scr_width, int scr_height, bool fulls, bool accel) {
+ DefaultVariables();
+
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0) {
#ifdef DEBUG_OVERKILL
printf("[ContextManager~Ctor] SDL Init error w/ VIDEO|AUDIO. Msg rep: %s\n", SDL_GetError());
// Delays window creation; Use InitWindow before doing anything.
ContextManager::ContextManager() {
+ DefaultVariables();
+
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0) {
#ifdef DEBUG_OVERKILL
printf("[ContextManager~Ctor] SDL Init error w/ VIDEO|AUDIO. Msg rep: %s\n", SDL_GetError());
#include "Zero.hpp"
TextManager::TextManager(ContextManager* ct) {
+
+ fonts = NULL;
+ current_font = 0;
+ fonts_loaded = 0;
+ outline = false;
+ outline_px = 0;
+
this->ctx = ct;
if(TTF_Init() == -1) {
}
TextManager::~TextManager() {
+
while(fonts_loaded > 0) {
TTF_CloseFont(fonts[fonts_loaded-1]);
--fonts_loaded;
#include "Zero.hpp"
+ void UDisplayable::DefaultVars() {
+ bitmap = NULL; // Will contain either a SDL_Surface or SDL_Texture
+
+ bmp_w = 0; bmp_h = 0;
+
+ // Used in docked mode
+ frame = NULL;
+ // Used in hitbox mode
+ hitbox = NULL;
+
+ // The current mode.
+ dispMode = Normal;
+
+ // Used by animated mode.
+ frameIndex = -1;
+
+ Error = false;
+ }
+
// Creates a new Displayable.
// The mode is already Normal if we do nothing, so this constructor doesn't have to change.
UDisplayable::UDisplayable(ContextManager* cx, char* fname) {
+ DefaultVars();
+
SDL_Surface* bitmap_tmp = IMG_Load(fname);
if(!bitmap_tmp) {
}
// Sets the Displayable's mode.
- UDisplayable::UDisplayable(ContextManager* cx, UDisplayableMode mode, char* fname) : UDisplayable(cx, fname) {
+ UDisplayable::UDisplayable(ContextManager* cx, UDisplayableMode mode, char* fname) {
+ UDisplayable(cx, fname);
this->dispMode = mode;
}
// Load from memory.
UDisplayable::UDisplayable(ContextManager* cx, UDisplayableMode mode, void* memory, int mSize) {
+ DefaultVars();
+
SDL_RWops* rwo = SDL_RWFromMem(memory, mSize);
SDL_Surface* bitmap_tmp = IMG_LoadTyped_RW(rwo, 0, "PNG");
if(rwo == NULL || bitmap_tmp == NULL) {
class DataContainer {
public:
+ DataContainer();
+
ContextManager* ctx;
- int if_fail = 0;
- bool wait_input = false;
+ int if_fail;
+ bool wait_input;
char current_scr[400], current_music[400], current_bg[400];
- int screen_w = 800;
- int screen_h = 600;
- int physical_w = 800;
- int physical_h = 600;
- int render_x1 = screen_w / 15;
- int render_y1 = screen_h / 15;
- int render_x2 = screen_w / 15 * 14;
- int render_y2 = screen_h / 15 * 13;
- int text_x = render_x1;
- int text_y = render_y1;
- std::map<std::string, int> *g_flags = NULL;
- std::map<std::string, int> *s_flags = NULL;
- bool jumped = false;
- int* choice_coords = NULL;
- int choices = 0;
- FILE* accessScriptHandle = NULL;
+ int screen_w;
+ int screen_h;
+ int physical_w;
+ int physical_h;
+ int render_x1;
+ int render_y1;
+ int render_x2;
+ int render_y2;
+ int text_x;
+ int text_y;
+ std::map<std::string, int> *s_flags;
+ bool jumped;
+ int* choice_coords;
+ int choices;
+ FILE* accessScriptHandle;
char** main_scr; // Default value.
- bool vndc_enabled = true;
- bool quote_incomplete = false;
- bool debug_mode = false;
- bool debug_to_shell = false;
- bool verbose = false;
- int currentLine = 0;
- bool skip_key_on = false;
- bool eof = false;
+ bool vndc_enabled;
+ bool quote_incomplete;
+ bool debug_mode;
+ bool debug_to_shell;
+ bool verbose;
+ int currentLine;
+ bool skip_key_on;
+ bool eof;
char* window_name;
- char* next_line = NULL; // Used for voice-detect.
+ char* next_line; // Used for voice-detect.
// It's impossible to parse without lookahead.
};
#include <ctime>
#include <cstring>
+#include "gitrev.hpp"
+
+// No output capabilities.
+#ifdef WITH_ANDROID
+# define printf(...)
+#endif
+
#include "Data.hpp"
void Parse(); // This reads commands from files.
--- /dev/null
+#ifndef GIT_REV_HDR
+#define GIT_REV_HDR
+#define GIT_REV "c7ef31d2ee1c2c24b2c76369d203ac024dfae5f9"
+
+#endif
const char* loadup = "script/main.scr";
+DataContainer::DataContainer() {
+ if_fail = 0;
+ wait_input = false;
+ screen_w = 800;
+ screen_h = 600;
+ physical_w = 800;
+ physical_h = 600;
+ render_x1 = screen_w / 15;
+ render_y1 = screen_h / 15;
+ render_x2 = screen_w / 15 * 14;
+ render_y2 = screen_h / 15 * 13;
+ text_x = render_x1;
+ text_y = render_y1;
+ jumped = false;
+ choice_coords = NULL;
+ choices = 0;
+ accessScriptHandle = NULL;
+ vndc_enabled = true;
+ quote_incomplete = false;
+ debug_mode = false;
+ debug_to_shell = false;
+ verbose = false;
+ currentLine = 0;
+ skip_key_on = false;
+ eof = false;
+ next_line = NULL; // Used for voice-detect.
+ // It's impossible to parse without lookahead.
+}
+
void CreateDataContainer() {
data = new DataContainer();
+
+
+
GetData()->main_scr = (char**)calloc(sizeof(char*), 1);
GetData()->main_scr[0] = (char*)calloc(sizeof(char), 400);
strncpy(GetData()->main_scr[0], loadup, 400);
GetData()->ctx->RegisterInput(SDLK_LCTRL, &NopKey);
GetData()->s_flags = new std::map<std::string, int>();
- GetData()->g_flags = new std::map<std::string, int>();
// Font
GetData()->ctx->Text()->LoadFont((char*)"default.ttf", 24);
#include <unistd.h>
#include <signal.h>
-
-
void DebugTrap(int sig) {
GetData()->debug_to_shell = true;
}
if(chdir_to_dir)
chdir(chdir_to_dir);
+ #ifdef WITH_ANDROID
+ chdir((char*)"/mnt/sdcard/vndc/");
+ #endif
+
if(main_script_override != NULL) {
printf("[debug] Note that in this mode, l_flags is not set.\n[debug] Expect bugs/gameover, this is normal.\n");
memset(GetData()->main_scr[0], 0, 399);