aboutsummaryrefslogtreecommitdiff
path: root/lib/lua/src/print.c
blob: e240cfc3c6087105bb8a04d861e590a52f2b2911 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
/*
** $Id: print.c,v 1.55a 2006/05/31 13:30:05 lhf Exp $
** print bytecodes
** See Copyright Notice in lua.h
*/

#include <ctype.h>
#include <stdio.h>

#define luac_c
#define LUA_CORE

#include "ldebug.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lundump.h"

#define PrintFunction	luaU_print

#define Sizeof(x)	((int)sizeof(x))
#define VOID(p)		((const void*)(p))

static void PrintString(const TString* ts)
{
 const char* s=getstr(ts);
 size_t i,n=ts->tsv.len;
 putchar('"');
 for (i=0; i<n; i++)
 {
  int c=s[i];
  switch (c)
  {
   case '"': printf("\\\""); break;
   case '\\': printf("\\\\"); break;
   case '\a': printf("\\a"); break;
   case '\b': printf("\\b"); break;
   case '\f': printf("\\f"); break;
   case '\n': printf("\\n"); break;
   case '\r': printf("\\r"); break;
   case '\t': printf("\\t"); break;
   case '\v': printf("\\v"); break;
   default:	if (isprint((unsigned char)c))
   			putchar(c);
		else
			printf("\\%03u",(unsigned char)c);
  }
 }
 putchar('"');
}

static void PrintConstant(const Proto* f, int i)
{
 const TValue* o=&f->k[i];
 switch (ttype(o))
 {
  case LUA_TNIL:
	printf("nil");
	break;
  case LUA_TBOOLEAN:
	printf(bvalue(o) ? "true" : "false");
	break;
  case LUA_TNUMBER:
	printf(LUA_NUMBER_FMT,nvalue(o));
	break;
  case LUA_TSTRING:
	PrintString(rawtsvalue(o));
	break;
  default:				/* cannot happen */
	printf("? type=%d",ttype(o));
	break;
 }
}

static void PrintCode(const Proto* f)
{
 const Instruction* code=f->code;
 int pc,n=f->sizecode;
 for (pc=0; pc<n; pc++)
 {
  Instruction i=code[pc];
  OpCode o=GET_OPCODE(i);
  int a=GETARG_A(i);
  int b=GETARG_B(i);
  int c=GETARG_C(i);
  int bx=GETARG_Bx(i);
  int sbx=GETARG_sBx(i);
  int line=getline(f,pc);
  printf("\t%d\t",pc+1);
  if (line>0) printf("[%d]\t",line); else printf("[-]\t");
  printf("%-9s\t",luaP_opnames[o]);
  switch (getOpMode(o))
  {
   case iABC:
    printf("%d",a);
    if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b);
    if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c);
    break;
   case iABx:
    if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx);
    break;
   case iAsBx:
    if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx);
    break;
  }
  switch (o)
  {
   case OP_LOADK:
    printf("\t; "); PrintConstant(f,bx);
    break;
   case OP_GETUPVAL:
   case OP_SETUPVAL:
    printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-");
    break;
   case OP_GETGLOBAL:
   case OP_SETGLOBAL:
    printf("\t; %s",svalue(&f->k[bx]));
    break;
   case OP_GETTABLE:
   case OP_SELF:
    if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); }
    break;
   case OP_SETTABLE:
   case OP_ADD:
   case OP_SUB:
   case OP_MUL:
   case OP_DIV:
   case OP_POW:
   case OP_EQ:
   case OP_LT:
   case OP_LE:
    if (ISK(b) || ISK(c))
    {
     printf("\t; ");
     if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-");
     printf(" ");
     if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-");
    }
    break;
   case OP_JMP:
   case OP_FORLOOP:
   case OP_FORPREP:
    printf("\t; to %d",sbx+pc+2);
    break;
   case OP_CLOSURE:
    printf("\t; %p",VOID(f->p[bx]));
    break;
   case OP_SETLIST:
    if (c==0) printf("\t; %d",(int)code[++pc]);
    else printf("\t; %d",c);
    break;
   default:
    break;
  }
  printf("\n");
 }
}

#define SS(x)	(x==1)?"":"s"
#define S(x)	x,SS(x)

static void PrintHeader(const Proto* f)
{
 const char* s=getstr(f->source);
 if (*s=='@' || *s=='=')
  s++;
 else if (*s==LUA_SIGNATURE[0])
  s="(bstring)";
 else
  s="(string)";
 printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n",
 	(f->linedefined==0)?"main":"function",s,
	f->linedefined,f->lastlinedefined,
	S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f));
 printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
	f->numparams,f->is_vararg?"+":"",SS(f->numparams),
	S(f->maxstacksize),S(f->nups));
 printf("%d local%s, %d constant%s, %d function%s\n",
	S(f->sizelocvars),S(f->sizek),S(f->sizep));
}

static void PrintConstants(const Proto* f)
{
 int i,n=f->sizek;
 printf("constants (%d) for %p:\n",n,VOID(f));
 for (i=0; i<n; i++)
 {
  printf("\t%d\t",i+1);
  PrintConstant(f,i);
  printf("\n");
 }
}

static void PrintLocals(const Proto* f)
{
 int i,n=f->sizelocvars;
 printf("locals (%d) for %p:\n",n,VOID(f));
 for (i=0; i<n; i++)
 {
  printf("\t%d\t%s\t%d\t%d\n",
  i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
 }
}

static void PrintUpvalues(const Proto* f)
{
 int i,n=f->sizeupvalues;
 printf("upvalues (%d) for %p:\n",n,VOID(f));
 if (f->upvalues==NULL) return;
 for (i=0; i<n; i++)
 {
  printf("\t%d\t%s\n",i,getstr(f->upvalues[i]));
 }
}

void PrintFunction(const Proto* f, int full)
{
 int i,n=f->sizep;
 PrintHeader(f);
 PrintCode(f);
 if (full)
 {
  PrintConstants(f);
  PrintLocals(f);
  PrintUpvalues(f);
 }
 for (i=0; i<n; i++) PrintFunction(f->p[i],full);
}
an>("mgcarpathian_np_height4", np_height4); settings->getNoiseParams("mgcarpathian_np_hills_terrain", np_hills_terrain); settings->getNoiseParams("mgcarpathian_np_ridge_terrain", np_ridge_terrain); settings->getNoiseParams("mgcarpathian_np_step_terrain", np_step_terrain); settings->getNoiseParams("mgcarpathian_np_hills", np_hills); settings->getNoiseParams("mgcarpathian_np_ridge_mnt", np_ridge_mnt); settings->getNoiseParams("mgcarpathian_np_step_mnt", np_step_mnt); settings->getNoiseParams("mgcarpathian_np_mnt_var", np_mnt_var); settings->getNoiseParams("mgcarpathian_np_cave1", np_cave1); settings->getNoiseParams("mgcarpathian_np_cave2", np_cave2); settings->getNoiseParams("mgcarpathian_np_cavern", np_cavern); } void MapgenCarpathianParams::writeParams(Settings *settings) const { settings->setFlagStr("mgcarpathian_spflags", spflags, flagdesc_mapgen_carpathian, U32_MAX); settings->setFloat("mgcarpathian_base_level", base_level); settings->setFloat("mgcarpathian_cave_width", cave_width); settings->setS16("mgcarpathian_large_cave_depth", large_cave_depth); settings->setS16("mgcarpathian_lava_depth", lava_depth); settings->setS16("mgcarpathian_cavern_limit", cavern_limit); settings->setS16("mgcarpathian_cavern_taper", cavern_taper); settings->setFloat("mgcarpathian_cavern_threshold", cavern_threshold); settings->setS16("mgcarpathian_dungeon_ymin", dungeon_ymin); settings->setS16("mgcarpathian_dungeon_ymax", dungeon_ymax); settings->setNoiseParams("mgcarpathian_np_filler_depth", np_filler_depth); settings->setNoiseParams("mgcarpathian_np_height1", np_height1); settings->setNoiseParams("mgcarpathian_np_height2", np_height2); settings->setNoiseParams("mgcarpathian_np_height3", np_height3); settings->setNoiseParams("mgcarpathian_np_height4", np_height4); settings->setNoiseParams("mgcarpathian_np_hills_terrain", np_hills_terrain); settings->setNoiseParams("mgcarpathian_np_ridge_terrain", np_ridge_terrain); settings->setNoiseParams("mgcarpathian_np_step_terrain", np_step_terrain); settings->setNoiseParams("mgcarpathian_np_hills", np_hills); settings->setNoiseParams("mgcarpathian_np_ridge_mnt", np_ridge_mnt); settings->setNoiseParams("mgcarpathian_np_step_mnt", np_step_mnt); settings->setNoiseParams("mgcarpathian_np_mnt_var", np_mnt_var); settings->setNoiseParams("mgcarpathian_np_cave1", np_cave1); settings->setNoiseParams("mgcarpathian_np_cave2", np_cave2); settings->setNoiseParams("mgcarpathian_np_cavern", np_cavern); } //////////////////////////////////////////////////////////////////////////////// // Lerp function inline float MapgenCarpathian::getLerp(float noise1, float noise2, float mod) { return noise1 + mod * (noise2 - noise1); } // Steps function float MapgenCarpathian::getSteps(float noise) { float w = 0.5f; float k = std::floor(noise / w); float f = (noise - k * w) / w; float s = std::fmin(2.f * f, 1.f); return (k + s) * w; } //////////////////////////////////////////////////////////////////////////////// void MapgenCarpathian::makeChunk(BlockMakeData *data) { // Pre-conditions assert(data->vmanip); assert(data->nodedef); assert(data->blockpos_requested.X >= data->blockpos_min.X && data->blockpos_requested.Y >= data->blockpos_min.Y && data->blockpos_requested.Z >= data->blockpos_min.Z); assert(data->blockpos_requested.X <= data->blockpos_max.X && data->blockpos_requested.Y <= data->blockpos_max.Y && data->blockpos_requested.Z <= data->blockpos_max.Z); this->generating = true; this->vm = data->vmanip; this->ndef = data->nodedef; v3s16 blockpos_min = data->blockpos_min; v3s16 blockpos_max = data->blockpos_max; node_min = blockpos_min * MAP_BLOCKSIZE; node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1); full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE; full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1); // Create a block-specific seed blockseed = getBlockSeed2(full_node_min, seed); // Generate terrain s16 stone_surface_max_y = generateTerrain(); // Create heightmap updateHeightmap(node_min, node_max); // Init biome generator, place biome-specific nodes, and build biomemap biomegen->calcBiomeNoise(node_min); generateBiomes(); // Generate caverns, tunnels and classic caves if (flags & MG_CAVES) { bool has_cavern = false; // Generate caverns if (spflags & MGCARPATHIAN_CAVERNS) has_cavern = generateCaverns(stone_surface_max_y); // Generate tunnels and classic caves if (has_cavern) // Disable classic caves in this mapchunk by setting // 'large cave depth' to world base. Avoids excessive liquid in // large caverns and floating blobs of overgenerated liquid. generateCaves(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT); else generateCaves(stone_surface_max_y, large_cave_depth); } // Generate dungeons if ((flags & MG_DUNGEONS) && full_node_min.Y >= dungeon_ymin && full_node_max.Y <= dungeon_ymax) generateDungeons(stone_surface_max_y); // Generate the registered decorations if (flags & MG_DECORATIONS) m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max); // Generate the registered ores m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max); // Sprinkle some dust on top after everything else was generated dustTopNodes(); // Update liquids updateLiquid(&data->transforming_liquid, full_node_min, full_node_max); // Calculate lighting if (flags & MG_LIGHT) { calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0), full_node_min, full_node_max); } this->generating = false; } //////////////////////////////////////////////////////////////////////////////// int MapgenCarpathian::getSpawnLevelAtPoint(v2s16 p) { s16 level_at_point = terrainLevelAtPoint(p.X, p.Y); if (level_at_point <= water_level || level_at_point > water_level + 32) return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point return level_at_point; } float MapgenCarpathian::terrainLevelAtPoint(s16 x, s16 z) { float height1 = NoisePerlin2D(&noise_height1->np, x, z, seed); float height2 = NoisePerlin2D(&noise_height2->np, x, z, seed); float height3 = NoisePerlin2D(&noise_height3->np, x, z, seed); float height4 = NoisePerlin2D(&noise_height4->np, x, z, seed); float hter = NoisePerlin2D(&noise_hills_terrain->np, x, z, seed); float rter = NoisePerlin2D(&noise_ridge_terrain->np, x, z, seed); float ster = NoisePerlin2D(&noise_step_terrain->np, x, z, seed); float n_hills = NoisePerlin2D(&noise_hills->np, x, z, seed); float n_ridge_mnt = NoisePerlin2D(&noise_ridge_mnt->np, x, z, seed); float n_step_mnt = NoisePerlin2D(&noise_step_mnt->np, x, z, seed); int height = -MAX_MAP_GENERATION_LIMIT; for (s16 y = 1; y <= 30; y++) { float mnt_var = NoisePerlin3D(&noise_mnt_var->np, x, y, z, seed); // Gradient & shallow seabed s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y; // Hill/Mountain height (hilliness) float hill1 = getLerp(height1, height2, mnt_var); float hill2 = getLerp(height3, height4, mnt_var); float hill3 = getLerp(height3, height2, mnt_var); float hill4 = getLerp(height1, height4, mnt_var); float hilliness = std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4)); // Rolling hills float hill_mnt = hilliness * std::pow(n_hills, 2.f); float hills = std::pow(std::fabs(hter), 3.f) * hill_mnt; // Ridged mountains float ridge_mnt = hilliness * (1.f - std::fabs(n_ridge_mnt)); float ridged_mountains = std::pow(std::fabs(rter), 3.f) * ridge_mnt; // Step (terraced) mountains float step_mnt = hilliness * getSteps(n_step_mnt); float step_mountains = std::pow(std::fabs(ster), 3.f) * step_mnt; // Final terrain level float mountains = hills + ridged_mountains + step_mountains; float surface_level = base_level + mountains + grad; if (y > surface_level && height < 0) height = y; } return height; } //////////////////////////////////////////////////////////////////////////////// int MapgenCarpathian::generateTerrain() { MapNode mn_air(CONTENT_AIR); MapNode mn_stone(c_stone); MapNode mn_water(c_water_source); // Calculate noise for terrain generation noise_height1->perlinMap2D(node_min.X, node_min.Z); noise_height2->perlinMap2D(node_min.X, node_min.Z); noise_height3->perlinMap2D(node_min.X, node_min.Z); noise_height4->perlinMap2D(node_min.X, node_min.Z); noise_hills_terrain->perlinMap2D(node_min.X, node_min.Z); noise_ridge_terrain->perlinMap2D(node_min.X, node_min.Z); noise_step_terrain->perlinMap2D(node_min.X, node_min.Z); noise_hills->perlinMap2D(node_min.X, node_min.Z); noise_ridge_mnt->perlinMap2D(node_min.X, node_min.Z); noise_step_mnt->perlinMap2D(node_min.X, node_min.Z); noise_mnt_var->perlinMap3D(node_min.X, node_min.Y - 1, node_min.Z); //// Place nodes const v3s16 &em = vm->m_area.getExtent(); s16 stone_surface_max_y = -MAX_MAP_GENERATION_LIMIT; u32 index2d = 0; for (s16 z = node_min.Z; z <= node_max.Z; z++) for (s16 x = node_min.X; x <= node_max.X; x++, index2d++) { // Hill/Mountain height (hilliness) float height1 = noise_height1->result[index2d]; float height2 = noise_height2->result[index2d]; float height3 = noise_height3->result[index2d]; float height4 = noise_height4->result[index2d]; // Rolling hills float hterabs = std::fabs(noise_hills_terrain->result[index2d]); float n_hills = noise_hills->result[index2d]; float hill_mnt = hterabs * hterabs * hterabs * n_hills * n_hills; // Ridged mountains float rterabs = std::fabs(noise_ridge_terrain->result[index2d]); float n_ridge_mnt = noise_ridge_mnt->result[index2d]; float ridge_mnt = rterabs * rterabs * rterabs * (1.f - std::fabs(n_ridge_mnt)); // Step (terraced) mountains float sterabs = std::fabs(noise_step_terrain->result[index2d]); float n_step_mnt = noise_step_mnt->result[index2d]; float step_mnt = sterabs * sterabs * sterabs * getSteps(n_step_mnt); // Initialise 3D noise index and voxelmanip index to column base u32 index3d = (z - node_min.Z) * zstride_1u1d + (x - node_min.X); u32 vi = vm->m_area.index(x, node_min.Y - 1, z); for (s16 y = node_min.Y - 1; y <= node_max.Y + 1; y++, index3d += ystride, VoxelArea::add_y(em, vi, 1)) { if (vm->m_data[vi].getContent() != CONTENT_IGNORE) continue; // Combine height noises and apply 3D variation float mnt_var = noise_mnt_var->result[index3d]; float hill1 = getLerp(height1, height2, mnt_var); float hill2 = getLerp(height3, height4, mnt_var); float hill3 = getLerp(height3, height2, mnt_var); float hill4 = getLerp(height1, height4, mnt_var); // 'hilliness' determines whether hills/mountains are // small or large float hilliness = std::fmax(std::fmin(hill1, hill2), std::fmin(hill3, hill4)); float hills = hill_mnt * hilliness; float ridged_mountains = ridge_mnt * hilliness; float step_mountains = step_mnt * hilliness; // Gradient & shallow seabed s32 grad = (y < water_level) ? grad_wl + (water_level - y) * 3 : 1 - y; // Final terrain level float mountains = hills + ridged_mountains + step_mountains; float surface_level = base_level + mountains + grad; if (y < surface_level) { vm->m_data[vi] = mn_stone; // Stone if (y > stone_surface_max_y) stone_surface_max_y = y; } else if (y <= water_level) { vm->m_data[vi] = mn_water; // Sea water } else { vm->m_data[vi] = mn_air; // Air } } } return stone_surface_max_y; }