U E D R , A S I H C RSS

Code/RPG Maker

Difference between r1.19 and the current

@@ -196,308 +196,164 @@
}
}}}

= Actors.rvdata Parser =
= Table 클래스의 구현 =

{{{#!vim java
public class RMFileParser {
class IDFinder {
static final int TYPE_SIG = 0;
static final int TYPE_INT = 1;
static final int TYPE_BOOL = 2;
static final int TYPE_STR = 3;
static final int TYPE_TABLE = 4;
static final int TYPE_PARAM = 5;
public IDFinder(String name, int type) {
this.name = name;
this.type = type;
}
boolean addChar(byte c){
if(index >= name.length())
return false;
if(name.charAt(index) == c) {
index++;
if(index == name.length())
return true;
}
else {
index = 0;
}
return false;
}
public String name = "";
public int type;
private int index = 0;
}
private IDFinder[] finder = {
new IDFinder("@id", IDFinder.TYPE_INT),
new IDFinder("@name", IDFinder.TYPE_STR),
new IDFinder("Table", IDFinder.TYPE_TABLE),
new IDFinder("@class_id", IDFinder.TYPE_INT),
new IDFinder("@weapon_id", IDFinder.TYPE_INT),
new IDFinder("@armor1_id", IDFinder.TYPE_INT),
new IDFinder("@armor2_id", IDFinder.TYPE_INT),
new IDFinder("@armor3_id", IDFinder.TYPE_INT),
new IDFinder("@armor4_id", IDFinder.TYPE_INT),
new IDFinder("@exp_basis", IDFinder.TYPE_INT),
new IDFinder("@face_name", IDFinder.TYPE_STR),
new IDFinder("@parameters", IDFinder.TYPE_PARAM),
new IDFinder("@face_index", IDFinder.TYPE_INT),
new IDFinder("@super_guard", IDFinder.TYPE_BOOL),
new IDFinder("@auto_battle", IDFinder.TYPE_BOOL),
new IDFinder("@pharmacology", IDFinder.TYPE_BOOL),
new IDFinder("@initial_level", IDFinder.TYPE_INT),
new IDFinder("@exp_inflation", IDFinder.TYPE_INT),
new IDFinder("@fix_equipment", IDFinder.TYPE_BOOL),
new IDFinder("@character_name", IDFinder.TYPE_STR),
new IDFinder("@critical_bonus", IDFinder.TYPE_BOOL),
new IDFinder("@character_index", IDFinder.TYPE_INT),
new IDFinder("@two_swords_style", IDFinder.TYPE_BOOL),
new IDFinder("RPG::Actor", IDFinder.TYPE_SIG)
};
{{{#!vim ruby

public static void main(String[] args)
{
//test
new RMFileParser();
}
public RMFileParser()
{
try {
FileInputStream fis = new FileInputStream(new File("testdata/Project1-/Data/Actors.rvdata"));
newParse(fis);
fis.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void newParse(InputStream is) throws IOException
{
is.skip(3);
int data = 0;
List<IDFinder> argList = new ArrayList<IDFinder>();
boolean bFound = false;
boolean firstChar = true;
while((data = is.read()) != -1) {
if(bFound && data == 0x3a)
bFound = false;
else if(bFound && data == 0x3b) {
firstChar = false;
bFound = false;
continue;
}
for(int i=0; firstChar && i<finder.length && !bFound; i++) {
if(finder[i].addChar((byte)data)) {
Util.LOGD("found: " + finder[i].name);
bFound = true;
argList.add(finder[i]);
String result = null;
switch(finder[i].type) {
case IDFinder.TYPE_BOOL:
result = String.valueOf(is.read() == 'T');
break;
case IDFinder.TYPE_INT:
is.skip(1);
int v = is.read();
result = String.valueOf(v == 0 ? 0 : v-5);
break;
case IDFinder.TYPE_PARAM:
result = String.valueOf((char)is.read());
break;
case IDFinder.TYPE_SIG:
result = finder[i].name;
break;
case IDFinder.TYPE_STR:
is.skip(2);
byte[] arr = new byte[100];
for(int j=0;; j++) {
byte b = (byte)is.read();
if(b == 0x3a) {
result = new String(arr, 0, j);
bFound = false;
break;
}
else {
arr[j] = b;
}
}
break;
case IDFinder.TYPE_TABLE:
result = "Table start: ";
read_table(is);
break;
} 
Util.LOGD(result);
break;
}
}
if(!firstChar && !bFound) { 
int index = get_int(data);
Util.LOGD("found: " + argList.get(index).name);
bFound = true;
if(argList.get(index).name.equals("Table")) { 
Util.LOGD("table found");
read_table(is);
}
}
}
Util.LOGD("" + argList.size());
}
private int get_int(int data)
{
return data <= 0 ? 0 : data - 5;
}
private void read_table(InputStream is)
{
try {
is.skip(0x17);
for(int i=0; i<100; i++) {
System.out.print("level " + i + ": ");
for(int j=0; j<6; j++) {
int v = readShort(is);
System.out.print(v + " ");
}
System.out.println();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private int readShort(InputStream is) throws IOException
{
return is.read() + (is.read() << 8);
}
}
}}}
# Table class
# a 3-dimensional array2 stores 2Byte integer
# Uses hash table internally.
class Table
def initialize(xsize=1, ysize=1, zsize=1)
resize(xsize, ysize, zsize)
end
def resize xsize, ysize, zsize
@array = Hash.new
@xsize = xsize
@ysize = ysize
@zsize = zsize
end
def self.resize xsize, ysize, zsize
#puts "resize to (#{xsize}, #{ysize}, #{zsize})"
@array = Hash.new
@xsize = xsize
@ysize = ysize
@zsize = zsize
end

= Actors.rvdata Parser: advanced(위 parser 코드와 이어짐) =
def [] *args
x=0
y=0
z=0
if args.length > 0
x = args[0]
end
if args.length > 1
y = args[1]
end
if args.length > 2
z = args[2]
end
return @array[[x, y, z]]
end
def []= *args
value = args[args.size-1]
args.delete_at(args.size-1) 
x=0
y=0
z=0
if args.length > 0
x = args[0]
end
if args.length > 1
y = args[1]
end
if args.length > 2
z = args[2]
end

{{{
@array[[x, y, z]] = value
end
def self._load args
#puts "load table"
header = args.unpack("l5")
table = args.unpack("@20s*")
#puts header.inspect
#puts table.inspect
obj = Table.new(header[1], header[2], header[3])
i=-1
for z in 0 ... obj.zsize
for y in 0 ... obj.ysize
for x in 0 ... obj.xsize
obj[x, y, z] = table[i = i+1]
#puts "array put #{table[i]}"
end
end
end
return obj
end

public void parse2(InputStream is) throws IOException
{
is.skip(3);
int numChar = is.read()-6;
Util.LOGD("캐릭터 수: " + numChar);
int data;
byte[] buf;
while((data = is.read()) != -1) {
// RPG::Actor(시그니쳐) 찾은 경우
if(finder_actor[0].addChar((byte) data)) {
// 입력받을 클래스 변수 수
int numArgs = get_int(is.read());
// 변수 순서가 저장될 행렬
String result = null;
List<String> argList = new ArrayList<String>();
// 첫번째 캐릭터
for(int i=0; i<numArgs; i++) {
for(;is.read() != 0x3a;); // 다음 구분자까지 읽는다
// 이름 길이
int elementNameLen = get_int(is.read());
buf = new byte[elementNameLen];
// 변수 이름 입력
is.read(buf);
result = new String(buf);
// 변수에 들일 값 읽기
String value = getValue(is);
Util.LOGD("발견!" + result + " value: " + value);
argList.add(result);
attr_accessor :xsize
attr_accessor :ysize
attr_accessor :zsize
end
}}}

// 테이블은 있으면 개수에 포함하지 않는다
if(value.equals("u"))
i--;
}
// 그 이후 캐릭터들
for(int i=0; i<numChar-1; i++) {
Util.LOGD((i+2) + "번째 캐릭터 시작");
for(;is.read() != 0x3b;); // 시작 시그니쳐 건너뜀
for(int j=0; j<numArgs; j++) {
for(;is.read() != 0x3b;); // 다음 구분자까지
// 변수 순서
int index = get_int(is.read());
String value = getValue(is);
// 변수값 읽기
Util.LOGD("발견!" + argList.get(index-1) + " value: " + value);
= Color 클래스의 구현 =
알만툴에서 사용하는 Color 클래스이다.

// 테이블은 있으면 개수에 포함하지 않는다
if(value.equals("u"))
j--;
}
}
}
}
}
내부적으로 자바의 java.awt.Color 클래스를 가지고 있으며 이를 이용하여 모든 값을 주고받는다.

루비의 Color와 자바의 Color이 이름이 같기 때문에 자바의 Color을 임시 모듈에 담아 모호성을 해결하였다.
{{{#!vim ruby
require 'java'

private String getValue(InputStream is) throws IOException
{
byte type = (byte) is.read();
String result = null;
switch(type) {
case 0x02: // table
result = "table start";
read_table(is);
break;
case '"': //str
int len = get_int(is.read());
if(len < 0) 
len = readShort(is); 
byte[] str = new byte[len]; 
is.read(str);
result = new String(str);
break;
case 'i': // int
int value = get_int(is.read());
result = String.valueOf(value);
break;
case 'T':
case 'F':
result = String.valueOf(type == 'T');
break;
case 'u':
result = "u";
}
return result;
}
# use temporary namespace(module) to solve ambiguous class name
module AA
import 'java.awt.Color'
end
 
class Color
attr_reader :object
def initialize red, green, blue, alpha=255
@object = AA::Color.new(red, green, blue, alpha)
end
def set red, green, blue, alpha=255
@object = AA::Color.new(red, green, blue, alpha) 
end
 
def red
return @object.getRed
end
def green
return @object.getGreen
end
def blue
return @object.getBlue
end
def alpha
return @object.getAlpha
end
def self._load args
# convert to floting point value
value = args.unpack("d4")
return Color.new(value[0].to_i, value[1].to_i, value[2].to_i, value[3].to_i)
end
def to_i
return (red | (green << 8) | (blue <<; 16) | (alpha <;<; 24))
end
def red= r
r = adjust_value(r, 0, 255)
set(r, green, blue, alpha)
end
def green= g
g = adjust_value(g, 0, 255)
set(red, g, blue, alpha)
end
def blue= b
b = adjust_value(b, 0, 255)
set(red, green, b, alpha)
end
def alpha= a
a = adjust_value(a, 0, 255)
set(red, green, blue, a)
end
end
}}}




1. Orthogonal projection coordinate system 만들기


        public void onSurfaceChanged(GL10 gl, int width, int height) {

                this.m_width = width;
                this.m_height = height;

                if(buffer == null) {

                        Util.LOGD("make framebuffer");
                        world = new World();
                        m_cam = world.getCamera();

                        // light mass
                        world.setAmbientLight(0xff, 0xff, 0xff);

                        // making background plane
                        float[] coordinates = { // position of vertices
                                0.0f, 0.0f, 0.0f,
                                m_width, 0.0f, 0.0f,
                                0.0f, m_height, 0.0f,
                                m_width, m_height, 0.0f
                        };

                        float[] uvs = { // how uv mapped?
                                0.0f, 0.0f,
                                1.0f, 0.0f,
                                0.0f, 1.0f,
                                1.0f, 1.0f
                        };

                        int[] indices = { // index of each coordinate
                                0, 2, 1,
                                1, 2, 3
                        };

                        // make plane
                        Object3D plane = new Object3D(coordinates, uvs, indices, RMObject2D.getTextureIDByColor(Color.white));
                        plane.build();
                        Util.LOGD("center: " + plane.getTransformedCenter());
                        world.addObject(plane);

                        // FOV settings
                        m_cam.setFOVLimits(0.1f, 2.0f);
                        m_cam.setFOV(0.1f);

                        // set up camera
                        // z = (width/2) / tan(fov/2)
                        m_cam.setPosition(m_width/2, m_height/2, (float) -(m_width/2/Math.tan(m_cam.getFOV()/2.0f)));
                        m_cam.lookAt(plane.getTransformedCenter());
                        fixCubePosition();

                        // configuration to view far object
                        Config.farPlane = Math.abs(m_cam.getPosition().z) + 1000f;
                }

                // make framebuffer
                if(buffer != null)
                        buffer.dispose();
                buffer = new FrameBuffer(m_width, m_height, FrameBuffer.SAMPLINGMODE_NORMAL);
        }


2. FillBox class

package cau.rpg.maker.object;

import java.awt.Color;

import javax.vecmath.Vector2f;

import com.threed.jpct.Object3D;

public class RMFillBox extends RMObject2D {

        public RMFillBox(float x1, float y1, float x2, float y2, Color color)
        {
                init(x1, y1, x2, y2, color);
        }

        public RMFillBox(Vector2f vStart, Vector2f vEnd, Color color)
        {
                init(vStart.x, vStart.y, vEnd.x, vEnd.y, color);
        }

        private void init(float x1, float y1, float x2, float y2, Color color)
        {
                if(x1 >= x2 || y1 >= y2)
                        return;

                float z = -10f;

                float[] coords = {
                        x1, y1, z,              // up left
                        x1, y2, z,              // bottom left
                        x2, y1, z,              // up right
                        x2, y2, z               // bottom right corner
                };

                float[] uvs = {
                        0f, 0f,
                        0f, 1f,
                        1f, 0f,
                        1f, 1f
                };

                int[] indices = {
                        0, 1, 2,
                        2, 1, 3
                };

                m_polygon = new Object3D(coords, uvs, indices, getTextureIDByColor(color));
        }
}


3. 2D line class

package cau.rpg.maker.object;

import java.awt.Color;

import javax.vecmath.Vector2f;
import javax.vecmath.Vector3f;

import com.threed.jpct.Object3D;

public class RMLine extends RMObject2D {

        private static final Vector3f vectorZ = new Vector3f(0, 0, -1);

        public RMLine(Vector2f vStart, Vector2f vEnd, float width, Color color)
        {
                float z = -10f;
                Vector3f v3Start = new Vector3f(vStart.x, vStart.y, z);
                Vector3f v3End = new Vector3f(vEnd.x, vEnd.y, z);

                // line vector
                Vector3f lineVector = new Vector3f();
                lineVector.sub(v3End, v3Start);

                // calc normal vector of line
                Vector3f normal = new Vector3f();
                normal.cross(lineVector, vectorZ);
                normal.normalize();
                normal.scale(width/2.0f);

                float[] coords = {
                        (vStart.x + normal.x), (vStart.y + normal.y), z,
                        (vStart.x - normal.x), (vStart.y - normal.y), z,
                        (vEnd.x + normal.x), (vEnd.y + normal.y), z,
                        (vEnd.x - normal.x), (vEnd.y - normal.y), z
                };

                float[] uvs = {
                        0f, 0f,
                        0f, 1f,
                        1f, 0f,
                        1f, 1f
                };

                int[] indices = {
                        0, 2, 1,
                        1, 2, 3
                };

                m_polygon = new Object3D(coords, uvs, indices, getTextureIDByColor(color));
        }

}

4. Interpolation


        public void setDepth(float depth)
        {
                float delta = depth - this.depth;

                // move object
                SimpleVector curPosition = m_polygon.getTransformedCenter();
                SimpleVector toCam = MainRenderer.getCamera().getPosition().calcSub(curPosition);
                float a = MainRenderer.getCamera().getPosition().z - this.depth;
                toCam.scalarMul(delta/a);
                m_polygon.translate(toCam);
                Util.LOGD("translate to " + toCam);

                // scale
                m_polygon.scale((a-delta)/a);

                this.depth = depth;
        }

5. Table 클래스의 구현



# Table class
# a 3-dimensional array2 stores 2Byte integer
# Uses hash table internally.
class Table
  def initialize(xsize=1, ysize=1, zsize=1)
    resize(xsize, ysize, zsize)
  end

  def resize xsize, ysize, zsize
    @array = Hash.new
    @xsize = xsize
    @ysize = ysize
    @zsize = zsize
  end

  def self.resize xsize, ysize, zsize
    #puts "resize to (#{xsize}, #{ysize}, #{zsize})"
    @array = Hash.new
    @xsize = xsize
    @ysize = ysize
    @zsize = zsize
  end

  def [] *args
    x=0
    y=0
    z=0
    if args.length > 0
      x = args[0]
    end
    if args.length > 1
      y = args[1]
    end
    if args.length > 2
      z = args[2]
    end
    return @array[[x, y, z]]
  end

  def []= *args
    value = args[args.size-1]
    args.delete_at(args.size-1)

    x=0
    y=0
    z=0
    if args.length > 0
      x = args[0]
    end
    if args.length > 1
      y = args[1]
    end
    if args.length > 2
      z = args[2]
    end

    @array[[x, y, z]] = value
  end

  def self._load args
    #puts "load table"
    header = args.unpack("l5")
    table = args.unpack("@20s*")
    #puts header.inspect
    #puts table.inspect

    obj = Table.new(header[1], header[2], header[3])

    i=-1
    for z in 0 ... obj.zsize
      for y in 0 ... obj.ysize
        for x in 0 ... obj.xsize
          obj[x, y, z] = table[i = i+1]
          #puts "array put #{table[i]}"
        end
      end
    end

    return obj
  end

  attr_accessor :xsize
  attr_accessor :ysize
  attr_accessor :zsize
end

6. Color 클래스의 구현

알만툴에서 사용하는 Color 클래스이다.

내부적으로 자바의 java.awt.Color 클래스를 가지고 있으며 이를 이용하여 모든 값을 주고받는다.

루비의 Color와 자바의 Color이 이름이 같기 때문에 자바의 Color을 임시 모듈에 담아 모호성을 해결하였다.

require 'java'

# use temporary namespace(module) to solve ambiguous class name
module AA
  import 'java.awt.Color'
end

class Color

  attr_reader :object

  def initialize red, green, blue, alpha=255
    @object = AA::Color.new(red, green, blue, alpha)
  end

  def set red, green, blue, alpha=255
    @object = AA::Color.new(red, green, blue, alpha)
  end

  def red
    return @object.getRed
  end
  def green
    return @object.getGreen
  end
  def blue
    return @object.getBlue
  end
  def alpha
    return @object.getAlpha
  end

  def self._load args
    # convert to floting point value
    value = args.unpack("d4")
    return  Color.new(value[0].to_i, value[1].to_i, value[2].to_i, value[3].to_i)
  end

  def to_i
    return (red | (green << 8) | (blue << 16) | (alpha << 24))
  end

  def red= r
    r = adjust_value(r, 0, 255)
    set(r, green, blue, alpha)
  end

  def green= g
    g = adjust_value(g, 0, 255)
    set(red, g, blue, alpha)
  end

  def blue= b
    b = adjust_value(b, 0, 255)
    set(red, green, b, alpha)
  end

  def alpha= a
    a = adjust_value(a, 0, 255)
    set(red, green, blue, a)
  end
end
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:22:57
Processing time 0.0698 sec